मैं SQL सर्वर में एक क्वेरी का उपयोग कर रहा हूं जिसके लिए यह जांचने के लिए एक सीमा की आवश्यकता है कि उस श्रेणी में कोई संख्या है (उदाहरण के लिए नीचे DemographicGroupDimID
है या नहीं । या तो (1,2 या 3) मुझे लगता है कि ऐसा करने में सक्षम हो पाया एक ही रास्ता googling कुछ करने के बाद नीचे था:पैरामीटर के साथ SQL सर्वर से पढ़ना: पांडा (या pyodbc) ठीक से काम नहीं कर रहा है
एसक्यूएल
DECLARE @adults table (Id int)
INSERT INTO @adults VALUES (1), (2), (3)
SELECT [date], [station], [impression] = SUM([impressions])/COUNT(DISTINCT [datetime])
FROM
(SELECT [datetime] = DATEADD(minute,td.Minute,DATEADD(hour,td.NielsenLocalHour,CONVERT(smalldatetime, ddt.DateKey))), [date] = ddt.DateKey, [station] = nd.Name, [impressions] = SUM(naf.Impression)
FROM [Nielsen].[dbo].[NielsenAnalyticsFact] as naf
LEFT JOIN [dbo].[DateDim] AS ddt
ON naf.StartDateDimID = ddt.DateDimID
LEFT JOIN [dbo].NetworkDim as nd
ON naf.NetworkDimID = nd.NetworkDimID
LEFT JOIN [dbo].TimeDim as td
ON naf.QuarterHourDimID = td.TimeDimID
WHERE (naf.NielsenMarketDimID = 1
AND naf.RecordTypeDimID = 2
AND naf.AudienceEstimateTypeDimID = 1
AND naf.DailyOrWeeklyDimID = 1
AND naf.RecordSequenceCodeDimID = 5
AND naf.ViewingTypeDimID = 4
AND naf.QuarterHourDimID IS NOT NULL
AND naf.DemographicGroupDimID < 31
AND nd.Affiliation = 'Cable'
AND naf.NetworkDimID != 1278
AND naf.DemographicGroupDimID in (SELECT Id FROM @adults))
GROUP BY DATEADD(minute,td.Minute,DATEADD(hour,td.NielsenLocalHour,CONVERT(smalldatetime, ddt.DateKey))), nd.Name, ddt.DateKey)
AS grouped_table
GROUP BY [date], [station]
ORDER BY [date], [station]
मैं गतिशील अलग के साथ ऐसा करना चाहते हैं तो श्रेणियां, यह विफल हो जाती है, जैसे:
पांडा क्वेरी
from queries import DB_CREDENTIALS
import pyodbc
import pandas as pd
sql_ = """DECLARE @adults table (Id int)
INSERT INTO @adults VALUES ?
SELECT [date], [station], [impression] = SUM([impressions])/COUNT(DISTINCT [datetime])
FROM
(SELECT [datetime] = DATEADD(minute,td.Minute,DATEADD(hour,td.NielsenLocalHour,CONVERT(smalldatetime, ddt.DateKey))), [date] = ddt.DateKey, [station] = nd.Name, [impressions] = SUM(naf.Impression)
FROM [Nielsen].[dbo].[NielsenAnalyticsFact] as naf
LEFT JOIN [dbo].[DateDim] AS ddt
ON naf.StartDateDimID = ddt.DateDimID
LEFT JOIN [dbo].NetworkDim as nd
ON naf.NetworkDimID = nd.NetworkDimID
LEFT JOIN [dbo].TimeDim as td
ON naf.QuarterHourDimID = td.TimeDimID
WHERE (naf.NielsenMarketDimID = 1
AND naf.RecordTypeDimID = 2
AND naf.AudienceEstimateTypeDimID = 1
AND naf.DailyOrWeeklyDimID = 1
AND naf.RecordSequenceCodeDimID = 5
AND naf.ViewingTypeDimID = 4
AND naf.QuarterHourDimID IS NOT NULL
AND naf.DemographicGroupDimID < 31
AND nd.Affiliation = 'Cable'
AND naf.NetworkDimID != 1278
AND naf.DemographicGroupDimID in (SELECT Id FROM @adults))
GROUP BY DATEADD(minute,td.Minute,DATEADD(hour,td.NielsenLocalHour,CONVERT(smalldatetime, ddt.DateKey))), nd.Name, ddt.DateKey)
AS grouped_table
GROUP BY [date], [station]
ORDER BY [date], [station]"""
with pyodbc.connect(DB_CREDENTIALS) as cnxn:
df = pd.read_sql(sql=sql_, con=cnxn, params=['(30)'])
त्रुटि:
---------------------------------------------------------------------------
DatabaseError Traceback (most recent call last)
<ipython-input-5-4b63847d007f> in <module>()
1 with pyodbc.connect(DB_CREDENTIALS) as cnxn:
----> 2 df = pd.read_sql(sql=sql_, con=cnxn, params=['(30)'])
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\pandas\io\sql.pyc in read_sql(sql, con, index_col, coerce_float, params, parse_dates, columns, chunksize)
497 sql, index_col=index_col, params=params,
498 coerce_float=coerce_float, parse_dates=parse_dates,
--> 499 chunksize=chunksize)
500
501 try:
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\pandas\io\sql.pyc in read_query(self, sql, index_col, coerce_float, params, parse_dates, chunksize)
1593
1594 args = _convert_params(sql, params)
-> 1595 cursor = self.execute(*args)
1596 columns = [col_desc[0] for col_desc in cursor.description]
1597
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\pandas\io\sql.pyc in execute(self, *args, **kwargs)
1570 ex = DatabaseError(
1571 "Execution failed on sql '%s': %s" % (args[0], exc))
-> 1572 raise_with_traceback(ex)
1573
1574 @staticmethod
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\pandas\io\sql.pyc in execute(self, *args, **kwargs)
1558 cur.execute(*args, **kwargs)
1559 else:
-> 1560 cur.execute(*args)
1561 return cur
1562 except Exception as exc:
DatabaseError: Execution failed on sql 'DECLARE @adults table (Id int)
INSERT INTO @adults VALUES ?
SELECT [date], [station], [impression] = SUM([impressions])/COUNT(DISTINCT [datetime])
FROM
(SELECT [datetime] = DATEADD(minute,td.Minute,DATEADD(hour,td.NielsenLocalHour,CONVERT(smalldatetime, ddt.DateKey))), [date] = ddt.DateKey, [station] = nd.Name, [impressions] = SUM(naf.Impression)
FROM [Nielsen].[dbo].[NielsenAnalyticsFact] as naf
LEFT JOIN [dbo].[DateDim] AS ddt
ON naf.StartDateDimID = ddt.DateDimID
LEFT JOIN [dbo].NetworkDim as nd
ON naf.NetworkDimID = nd.NetworkDimID
LEFT JOIN [dbo].TimeDim as td
ON naf.QuarterHourDimID = td.TimeDimID
WHERE (naf.NielsenMarketDimID = 1
AND naf.RecordTypeDimID = 2
AND naf.AudienceEstimateTypeDimID = 1
AND naf.DailyOrWeeklyDimID = 1
AND naf.RecordSequenceCodeDimID = 5
AND naf.ViewingTypeDimID = 4
AND naf.QuarterHourDimID IS NOT NULL
AND naf.DemographicGroupDimID < 31
AND nd.Affiliation = 'Cable'
AND naf.NetworkDimID != 1278
AND naf.DemographicGroupDimID in (SELECT Id FROM @adults))
GROUP BY DATEADD(minute,td.Minute,DATEADD(hour,td.NielsenLocalHour,CONVERT(smalldatetime, ddt.DateKey))), nd.Name, ddt.DateKey)
AS grouped_table
GROUP BY [date], [station]
ORDER BY [date], [station]': ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '@P1'. (102) (SQLExecDirectW); [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Statement(s) could not be prepared. (8180)")
इस वजह घोषणा बयान का चयन बयान खुद की सीमा के भीतर होने की जरूरत है है? मुझे यकीन नहीं है कि pandas
pyodbc
कर्सर ऑब्जेक्ट को संभालता है, इसलिए मुझे यह पता नहीं है कि यह त्रुटि कहां से उत्पन्न होती है।
संपादित करें: बस ध्यान दें, इस उदाहरण में पारित पैराम (30)
बस उस साधारण मामले का उपयोग करने के लिए होता है जब असफलता में केवल एक संख्या होती है। यह निश्चित रूप से ऊपर के उदाहरण के मामले में (1), (2), (3)
जैसे अधिक जटिल तारों के लिए विफल रहता है।
एक अतिरिक्त नोट: यदि पैरा को वास्तविक मान के साथ प्रतिस्थापित किया गया है तो यह क्वेरी ठीक काम करती है। तो शायद एक वर्कअराउंड सिर्फ SQL क्वेरी स्ट्रिंग को गतिशील रूप से प्रारूपित करना होगा। – mburke05
दो चीजें: 1) एसक्यूएल के 'IN (?,?,?) 'खंड का उपयोग क्यों नहीं करते हैं यदि एक पूर्णांक पूर्णांक स्केलर पास करते हैं; या 2) पैराम में गुजरने वाली संग्रहीत प्रक्रिया को क्यों न बुलाएं? – Parfait