2011-01-27 12 views
7

का उपयोग कर रहा pyodbc उपयोग कर रहा हूँ एक SQL सर्वर डेटाबेसएसक्यूएल pyodbc और SQL सर्वर

import datetime 
import pyodbc  
conn = pyodbc.connect("Driver={SQL Server};Server='dbserver',Database='db', 
         TrustedConnection=Yes") 
cursor = conn.cursor() 
ratings = ("PG-13", "PG", "G") 
st_dt = datetime(2010, 1, 1) 
end_dt = datetime(2010, 12, 31) 
cursor.execute("""Select title, director, producer From movies 
       Where rating In ? And release_dt Between ? And ?""", 
       ratings, str(st_dt), str(end_dt)) 

को क्वेरी करने के लिए, लेकिन नीचे त्रुटि मिल रही है। क्या ट्यूपल पैरामीटर को अलग तरीके से संभालना होगा? क्या इस क्वेरी को ढूढ़ने का कोई बेहतर तरीका है?

('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Line 9: 
    Incorrect syntax near '@P1'. (170) (SQLExecDirectW); 
    [42000] [Microsoft][ODBC SQL Server Driver][SQL Server] 
    Statement(s) could not be prepared. (8180)") 

अद्यतन:

मैं स्ट्रिंग स्वरूपण ऑपरेटर, जो आदर्श के रूप में यह सुरक्षा चिंताओं का परिचय नहीं है का उपयोग कर काम करने के लिए इस क्वेरी प्राप्त करने में सक्षम था।

import datetime 
import pyodbc  
conn = pyodbc.connect("Driver={SQL Server};Server='dbserver',Database='db', 
         TrustedConnection=Yes") 
cursor = conn.cursor() 
ratings = ("PG-13", "PG", "G") 
st_dt = datetime(2010, 1, 1) 
end_dt = datetime(2010, 12, 31) 
cursor.execute("""Select title, director, producer From movies 
       Where rating In %s And release_dt Between '%s' And '%s'""" % 
       (ratings, st_dt, end_dt)) 

उत्तर

12

आप किसी एकल स्ट्रिंग पैरामीटर का उपयोग कर एक IN() खंड में एक से अधिक मान parameterize नहीं कर सकते हैं:

का अनुसरण करें। इसे पूरा करने का एकमात्र तरीका यह है:

  1. स्ट्रिंग प्रतिस्थापन (जैसा आपने किया था)।

  2. बिल्ड रूप IN (?, ?, . . ., ?) में एक पैरामिट्रीकृत क्वेरी और उसके बाद प्रत्येक स्थान धारक के लिए एक अलग पैरामीटर में गुजरती हैं। मैं पाइथन में ओडीबीसी के विशेषज्ञ नहीं हूं लेकिन मुझे कल्पना है कि पाइथन जैसी भाषा में यह करना आसान है। यह सुरक्षित है क्योंकि आपको पैरामीटर के पूर्ण मूल्य मिलते हैं।

+1

अपने दूसरे विकल्प के लिए, एक गतिशील टपल एक कामना के आकार के आधार एसक्यूएल बयान बनाने के लिए की आवश्यकता होगी ? में बयान के पारित करने के लिए – user338714

+1

आप की तरह कुछ कर सकते हैं:।। '?' cursor.execute (("फिल्मों से चयन * कहां रेटिंग में ({})" प्रारूप ',' में शामिल होने के (* lEN (रेटिंग))) , रेटिंग्स) – rleelr

2

समस्या आपकी ट्यूपल है। ओडीबीसी कनेक्शन क्वेरी बनाने के लिए स्ट्रिंग की अपेक्षा कर रहा है और आप एक अजगर ट्यूपल भेज रहे हैं। और याद रखें कि आपको स्ट्रिंग उद्धरण सही प्राप्त करना होगा। मुझे लगता है कि रेटिंग की संख्या आप खोज रहे हैं अलग-अलग होती है। शायद एक बेहतर तरीका है, लेकिन मेरा pyodbc सरल और सीधा हो जाता है।

import datetime 
import pyodbc  
conn = pyodbc.connect("Driver={SQL Server};Server='dbserver',Database='db', 
         TrustedConnection=Yes") 

def List2SQLList(items): 
    sqllist = "%s" % "\",\"".join(items) 
    return sqllist 


cursor = conn.cursor() 
ratings = ("PG-13", "PG", "G") 
st_dt = datetime(2010, 1, 1) 
end_dt = datetime(2010, 12, 31) 
cursor.execute("""Select title, director, producer From movies 
       Where rating In (?) And release_dt Between ? And ?""", 
       List2SQLList(ratings), str(st_dt), str(end_dt)) 
+0

मैं:

placeholders = ",".join("?" * len(code_list)) sql = "delete from dbo.Results where RESULT_ID = ? AND CODE IN (%s)" % placeholders params = [result_id] params.extend(code_list) cursor.execute(sql, params) 

उचित मानकों के साथ निम्नलिखित एसक्यूएल देता है मैं अभी भी 1 पैरामीटर के लिए एक "गलत वाक्यविन्यास" त्रुटि प्राप्त कर रहा हूँ। क्या pyodbc सूची की बजाय स्ट्रिंग की तरह सूची का इलाज कर सकता है? – user338714

+0

इसकी डाल "की पूरी स्ट्रिंग के आसपास। मेरे संपादन देखें। – WombatPM

+0

मैं अभी भी एक पैरामीटर त्रुटि प्राप्त कर रहा हूँ। मैं स्ट्रिंग प्रारूप ऑपरेटर का उपयोग काम करने के लिए क्वेरी को पाने के लिए एक तरह से मिला (ऊपर मेरी अद्यतन देखें), और के बाद से इस कोड को केवल स्थानीय रूप से चलाया जाएगा, सुरक्षा चिंताओं शायद अनदेखी की जा। मुझे लगता है कि कर सकते हैं cursor.executemany एक और विकल्प हो सकता है। – user338714

11

लैरी का दूसरा विकल्प पर विस्तार करने के लिए - गतिशील रूप से एक पैरामिट्रीकृत स्ट्रिंग बनाने, मैं इस्तेमाल किया सफलतापूर्वक निम्नलिखित:

delete from dbo.Results where RESULT_ID = ? AND CODE IN (?,?,?) 
संबंधित मुद्दे