2010-08-25 10 views
25

के साथ संग्रहीत प्रक्रियाओं को एसक्यूएल सर्वर के साथ एसक्यूएल सर्वर की संग्रहीत प्रक्रियाओं को कैसे कॉल कर सकता हूं?एसक्यूएलकेमी

उत्तर

15

इंजन और कनेक्शन में execute() विधि है जिसका आप मनमाने ढंग से एसक्यूएल स्टेटमेंट्स के लिए उपयोग कर सकते हैं, और सत्र भी कर सकते हैं।

results = sess.execute('myproc ?, ?', [param1, param2]) 

आप outparam() का उपयोग उत्पादन पैरामीटर बनाना सकते हैं यदि आप (या बाँध मापदंडों isoutparam=True विकल्प के साथ bindparam() का उपयोग के लिए)

+0

यह डेटाबेस-अज्ञेयवादी नहीं है। इसके बजाए 'sqlalchemy.sql.text' का प्रयोग करें। – Profpatsch

+0

बीटीडब्लू आपको एमएस एसक्यूएल सर्वर में संग्रहीत प्रक्रिया द्वारा लौटाई गई पंक्तियों तक पहुंचने के लिए 'sess.execute (' सेट एनओसीटी चालू ') की आवश्यकता है। आप इसे एक निष्पादित कॉल में कर सकते हैं: 'results = sess.execute (' SET NOCOUNT ON; EXEC myproc?,?; SET NOCOUNT OFF ', [param1, param2]) '। –

+1

यह एक पुराना धागा है, हो सकता है कि यह ऐसा कुछ है जो स्क्लेल्चेमी के नए संस्करणों में बदल गया है, लेकिन मुझे पैरामीटर के लिए सूची के बजाय एक शब्दकोश का उपयोग करना था और "? Param" नाम का उपयोग कच्चे वर्ग में "?" । तो, ऊपर दिया गया उदाहरण बन जाता है: 'sess.execute (' myproc: p1,: p2 ', {' p1 ':' value1 ',' p2 ':' value2 '}) ' – ThatAintWorking

6

बस प्रक्रिया वस्तु func के साथ बनाया पर अमल करने की जरूरत है::

from sqlalchemy import create_engine, func 
from sqlalchemy.orm import sessionmaker 

engine = create_engine('sqlite://', echo=True) 
print engine.execute(func.upper('abc')).scalar() # Using engine 
session = sessionmaker(bind=engine)() 
print session.execute(func.upper('abc')).scalar() # Using session 
उदाहरण के लिए
+0

यह MySQL,' फ़ंक्शन के साथ काम नहीं करता है अस्तित्व में नहीं है। – Profpatsch

+0

संग्रहीत प्रक्रियाओं को कॉल करने के लिए मेरे लिए सुरुचिपूर्ण और सरल तरीका। आधिकारिक नोट्स _: डेटा: '.func' निर्माण में स्टैंडअलोन" संग्रहीत प्रक्रियाओं "को कॉल करने के लिए केवल सीमित समर्थन है, खासकर विशेष पैरामीटरेशन चिंताओं के साथ । मेरे जैसे लोगों के लिए 'stored_procedures' कैसे उपयोग करने के लिए DBAPI स्तरीय' 'callproc पर जानकारी के लिए()' 'विधि पूरी तरह से पारंपरिक संग्रहीत procedures._ कोड: देखें अनुभाग: रेफरी' session.execute (समारोह।your_proc_name (param1, param2)) ' – Niyojan

5

मान लीजिए कि आपके पास सत्रमेकर() के साथ पहले से सत्र बनाया गया है, तो आप निम्न फ़ंक्शन का उपयोग कर सकते हैं:

def exec_procedure(session, proc_name, params): 
    sql_params = ",".join(["@{0}={1}".format(name, value) for name, value in params.items()]) 
    sql_string = """ 
     DECLARE @return_value int; 
     EXEC @return_value = [dbo].[{proc_name}] {params}; 
     SELECT 'Return Value' = @return_value; 
    """.format(proc_name=proc_name, params=sql_params) 

    return session.execute(sql_string).fetchall() 

अब आप बस ऐसे ही मानकों के साथ अपने संग्रहीत प्रक्रिया 'MyProc' पर अमल कर सकते हैं:

params = { 
    'Foo': foo_value, 
    'Bar': bar_value 
} 
exec_procedure(session, 'MyProc', params) 
+5

यह SQL इंजेक्शन के लिए कमजोर लगता है। –

+0

यह वास्तव में कमजोर है। इंजन को तर्क मानों से बचने के लिए 'execute (sql_string, params = ...) 'के साथ नामित तर्कों को पार करना बेहतर होता है। @Profpatsch द्वारा जवाब पहले से ही करता है। –

+0

मैं इसके साथ आउटपुट पैरामीटर कैसे एकत्र करूं? यानी, मेरा बयान है: 'EXEC dbo.next_rowid 'dbo', 'workorder_feature', @id OUTPUT; 'मैं आईडी कैसे प्राप्त करूं? – roemhildtg

1

मेरा एक परियोजना के लिए बेताब की जरूरत में से, मैं एक समारोह प्रक्रिया कॉल संग्रहित हैंडल कि लिखा था।

ये रहा: उम्मीद के रूप में

import sqlalchemy as sql 

def execute_db_store_procedure(database, types, sql_store_procedure, *sp_args): 
    """ Execute the store procedure and return the response table. 

    Attention: No injection checking!!! 

    Does work with the CALL syntax as of yet (TODO: other databases). 

    Attributes: 
     database   -- the database 
     types    -- tuple of strings of SQLAlchemy type names. 
           Each type describes the type of the argument 
           with the same number. 
           List: http://docs.sqlalchemy.org/en/rel_0_7/core/types.html 
     sql_store_procudure -- string of the stored procedure to be executed 
     sp_args    -- arguments passed to the stored procedure 
    """ 
    if not len(types) == len(sp_args): 
     raise ValueError("types tuple must be the length of the sp args.") 

    # Construch the type list for the given types 
    # See 
    # http://docs.sqlalchemy.org/en/latest/core/sqlelement.html?highlight=expression.text#sqlalchemy.sql.expression.text 
    # sp_args (and their types) are numbered from 0 to len(sp_args)-1 
    type_list = [sql.sql.expression.bindparam(
        str(no), type_=getattr(sql.types, typ)()) 
         for no, typ in zip(range(len(types)), types)] 

    try: 
     # Adapts to the number of arguments given to the function 
     sp_call = sql.text("CALL `%s`(%s)" % (
       sql_store_procedure, 
       ", ".join([":%s" % n for n in range(len(sp_args))])), 
      bindparams=type_list 
     ) 
     #raise ValueError("%s\n%s" % (sp_call, type_list)) 
     with database.engine.begin() as connection: 
      return connection.execute(
       sp_call, 
       # Don't do this at home, kids... 
       **dict((str(no), arg) 
        for (no, arg) in zip(range(len(sp_args)), sp_args))) 
    except sql.exc.DatabaseError: 
     raise 

इसे कहते वाक्य रचना के साथ काम करता है, तो MySQL काम करना चाहिए। MSSQL कॉल के बजाय EXEC का उपयोग करता है और थोड़ा differennt वाक्यविन्यास, मुझे लगता है। तो इसे सर्वर अज्ञेयवादी बनाना आपके ऊपर है लेकिन बहुत कठिन नहीं होना चाहिए।

3

SQLAlchemy का उपयोग करके MySQL में संग्रहीत प्रक्रिया को कॉल करने का सबसे आसान तरीका Engine.raw_connection() का callproc विधि का उपयोग कर है। call_proc को संग्रहित प्रक्रिया के लिए आवश्यक प्रक्रिया नाम और पैरामीटर की आवश्यकता होगी।

def call_procedure(function_name, params): 
     connection = cloudsql.Engine.raw_connection() 
     try: 
      cursor = connection.cursor() 
      cursor.callproc(function_name, params) 
      results = list(cursor.fetchall()) 
      cursor.close() 
      connection.commit() 
      return results 
     finally: 
      connection.close() 
संबंधित मुद्दे