Python 百分比计算的查询参数出现语法错误
我有一个pyodbc查询,它工作得很好,但我正在尝试应用更新来向结果中添加一个新的计算字段。工作查询是:Python 百分比计算的查询参数出现语法错误,python,sql-server,python-3.x,sql-server-2014,pyodbc,Python,Sql Server,Python 3.x,Sql Server 2014,Pyodbc,我有一个pyodbc查询,它工作得很好,但我正在尝试应用更新来向结果中添加一个新的计算字段。工作查询是: cursor = cnxn.cursor() cursor.execute("SELECT RestaurantLocation.ID, Restaurant.DisplayName FROM Restaurant INNER JOIN RestaurantLocation ON Restaurant.ID = RestaurantLocation.Restaurant_
cursor = cnxn.cursor()
cursor.execute("SELECT RestaurantLocation.ID, Restaurant.DisplayName FROM
Restaurant INNER JOIN RestaurantLocation ON Restaurant.ID =
RestaurantLocation.Restaurant_ID WHERE (RestaurantLocation.Active = 1)")
row = cursor.fetchall()
columns = [column[0] for column in cursor.description]
for ID,DisplayName in row:
DisplayName = DisplayName.replace(" ","")
cursor = cnxn.cursor()
cursor.execute("SET NOCOUNT ON; SELECT ScheduledService.ServiceDate,
Restaurant.DisplayName AS RestaurantName, InvoiceLineItem.Invoice_ID,
ScheduledRestaurantService.Location_ID, ScheduledService.Service_ID,
Service.DisplayName AS ServiceName, InvoiceLineItem.Description,
InvoiceLineItem.Amount AS 'Subtotal' INTO #Subtotal FROM
ScheduledService INNER JOIN Invoice ON ScheduledService.Invoice_ID =
Invoice.ID INNER JOIN InvoiceLineItem ON Invoice.ID =
InvoiceLineItem.Invoice_ID INNER JOIN Payment ON Invoice.ID =
Payment.RelatedInvoice_ID INNER JOIN ScheduledRestaurantService ON
ScheduledService.ID = ScheduledRestaurantService.ID INNER JOIN
RMenuAllocatedScheduleSlot ON ScheduledRestaurantService.TimeSlot_ID =
RMenuAllocatedScheduleSlot.ID INNER JOIN [User] ON
ScheduledService.RelatedUser_ID = [User].ID INNER JOIN
RestaurantLocation ON ScheduledRestaurantService.Location_ID =
RestaurantLocation.ID INNER JOIN Restaurant ON
RestaurantLocation.Restaurant_ID = Restaurant.ID INNER JOIN Service ON
ScheduledService.Service_ID = Service.ID WHERE
(ScheduledService.ServiceDate BETWEEN ? AND ?) AND (NOT
(ScheduledService.Status_ID = 6)) AND (ScheduledService.Service_ID IN
(17, 18, 23, 24, 25)) AND (InvoiceLineItem.Description IN ('Subtotal'))
AND (ScheduledRestaurantService.Location_ID = ?) SELECT
#Subtotal.Invoice_ID, InvoiceLineItem.Amount AS 'SalesTax' INTO
#SalesTax FROM #Subtotal LEFT OUTER JOIN InvoiceLineItem ON
#Subtotal.Invoice_ID = InvoiceLineItem.Invoice_ID WHERE
(InvoiceLineItem.Description IN ('Sales Tax')) SELECT
#Subtotal.Invoice_ID, CASE WHEN #Subtotal.Service_ID IN (17,23,25,26)
THEN 0.00 ELSE InvoiceLineItem.Amount END AS 'Tip' INTO #Tip FROM
#Subtotal LEFT OUTER JOIN InvoiceLineItem ON #Subtotal.Invoice_ID =
InvoiceLineItem.Invoice_ID WHERE (InvoiceLineItem.Description IN
('Tip')) Select #Subtotal.ServiceDate, #Subtotal.RestaurantName,
#Subtotal.Invoice_ID, #Subtotal.Location_ID, #Subtotal.Service_ID,
#Subtotal.Subtotal, #SalesTax.SalesTax, #Tip.Tip Into #Final From
#Subtotal LEFT OUTER JOIN #SalesTax ON #Subtotal.Invoice_ID =
#SalesTax.Invoice_ID LEFT OUTER JOIN #Tip ON #Subtotal.Invoice_ID =
#Tip.Invoice_ID SET NOCOUNT OFF; Select * From #Final Order By
#Final.Service_ID, #Final.ServiceDate Drop Table #Subtotal Drop Table
#SalesTax Drop Table #Tip Drop Table #Final", (firstDay,lastDay,ID))
rows = cursor.fetchall()
那里的一切都很好。第二个查询的结果基于第一个查询中创建的唯一ID
但是,当我尝试向第二个查询添加新的计算字段时,我从SQL数据库中得到了一个不正确的语法错误。以下是更新后的查询:
cursor = cnxn.cursor()
cursor.execute("SELECT RestaurantLocation.ID, Restaurant.DisplayName FROM
Restaurant INNER JOIN RestaurantLocation ON Restaurant.ID =
RestaurantLocation.Restaurant_ID WHERE (RestaurantLocation.Active = 1)")
row = cursor.fetchall()
columns = [column[0] for column in cursor.description]
for ID,DisplayName in row:
DisplayName = DisplayName.replace(" ","")
cursor = cnxn.cursor()
print(firstDay,lastDay,ID)
if ID == 13:
percentage = 0.18
else:
if ID == 25:
percentage = 0.18
else:
percentage = 0.20
cursor.execute("SET NOCOUNT ON; SELECT ScheduledService.ServiceDate,
Restaurant.DisplayName AS RestaurantName,
InvoiceLineItem.Invoice_ID, ScheduledRestaurantService.Location_ID,
ScheduledService.Service_ID, Service.DisplayName AS ServiceName,
InvoiceLineItem.Description, InvoiceLineItem.Amount AS 'Subtotal'
INTO #Subtotal FROM ScheduledService INNER JOIN Invoice ON
ScheduledService.Invoice_ID = Invoice.ID INNER JOIN InvoiceLineItem
ON Invoice.ID = InvoiceLineItem.Invoice_ID INNER JOIN Payment ON
Invoice.ID = Payment.RelatedInvoice_ID INNER JOIN
ScheduledRestaurantService ON ScheduledService.ID =
ScheduledRestaurantService.ID INNER JOIN RMenuAllocatedScheduleSlot
ON ScheduledRestaurantService.TimeSlot_ID =
RMenuAllocatedScheduleSlot.ID INNER JOIN [User] ON
ScheduledService.RelatedUser_ID = [User].ID INNER JOIN
RestaurantLocation ON ScheduledRestaurantService.Location_ID =
RestaurantLocation.ID INNER JOIN Restaurant ON
RestaurantLocation.Restaurant_ID = Restaurant.ID INNER JOIN Service
ON ScheduledService.Service_ID = Service.ID WHERE
(ScheduledService.ServiceDate BETWEEN ? AND ?) AND (NOT
(ScheduledService.Status_ID = 6)) AND (ScheduledService.Service_ID
IN (17, 18, 23, 24, 25)) AND (InvoiceLineItem.Description IN
('Subtotal')) AND (ScheduledRestaurantService.Location_ID = ?)
SELECT #Subtotal.Invoice_ID, InvoiceLineItem.Amount AS 'SalesTax'
INTO #SalesTax FROM #Subtotal LEFT OUTER JOIN InvoiceLineItem ON
#Subtotal.Invoice_ID = InvoiceLineItem.Invoice_ID WHERE
(InvoiceLineItem.Description IN ('Sales Tax')) SELECT
#Subtotal.Invoice_ID, CASE WHEN #Subtotal.Service_ID IN
(17,23,25,26) THEN 0.00 ELSE InvoiceLineItem.Amount END AS 'Tip'
INTO #Tip FROM #Subtotal LEFT OUTER JOIN InvoiceLineItem ON
#Subtotal.Invoice_ID = InvoiceLineItem.Invoice_ID WHERE
(InvoiceLineItem.Description IN ('Tip')) Select
#Subtotal.ServiceDate, #Subtotal.RestaurantName,
#Subtotal.Invoice_ID, #Subtotal.Location_ID, #Subtotal.Service_ID,
#Subtotal.Subtotal, #SalesTax.SalesTax, #Subtotal.Subtotal * .? AS
Discount, #Tip.Tip Into #Final From #Subtotal LEFT OUTER JOIN
#SalesTax ON #Subtotal.Invoice_ID = #SalesTax.Invoice_ID LEFT OUTER
JOIN #Tip ON #Subtotal.Invoice_ID = #Tip.Invoice_ID SET NOCOUNT OFF;
Select * From #Final Order By #Final.Service_ID, #Final.ServiceDate
Drop Table #Subtotal Drop Table #SalesTax Drop Table #Tip Drop Table
#Final", (firstDay,lastDay,ID,percentage))
rows = cursor.fetchall()
错误是由我分配给percentage的值引发的。我首先尝试使用int来解决这个问题,因此我的IF语句变成:
if ID == 13:
percentage = int(0.18)
else:
if ID == 25:
percentage = int(0.18)
else:
percentage = int(0.20)
我的错误是无法识别整数是使用无小数位数转换的。因此,我更新了IF语句以使用float:
if ID == 13:
percentage = float(0.18)
else:
if ID == 25:
percentage = float(0.18)
else:
percentage = float(0.20)
在使用float设置百分比后,我从SQL中得到了完全相同的错误。我尝试了上面IF语句的多种变体,但它们都会导致完全相同的错误
我做错了什么?错误是由第四个参数占位符前面的小数点引起的: ... 小计,小计*。?作为折扣 这导致pyodbc使用如下查询调用sp_prepexec 选择小计。小计*@P1作为小计的折扣 这是无效的语法 参数占位符应始终单独显示,并且永远不要依赖分隔符或命令文本的其他元素来修改其行为。在这种情况下, sql=选择id、小计、小计。小计*?作为小计的折扣 参数=十进制'0.05', crsr.executesql,参数 哪个发送 执行sp_prepexec@p1输出,N'@p1 numeric3,3',N'选择id,小计,小计。小计*@p1作为小计的折扣,50
并且执行时不会出错。以下是pyodbc如何将Python转换为ODBC数据类型的列表:能否尝试在if语句中使用Decimal而不是float?您需要使用“从十进制导入十进制”导入is。此外,您可以在cursor.execute代码中使用三重引号,这将允许您更好地为SQL分配空间。这有助于保持我的理智!我将研究使用三重引号。使用PYODBC让我发疯的原因之一是,我的所有查询都在一个长串接字符串中。这几乎不可能解决问题。下面是一个示例:如果您不关心空格,我不关心,您可以直接在cursor.execute.no中使用相同的示例。空格一点也不困扰我,事实上它使查询更易于阅读。谢谢你的参考,这肯定会对我正在进行的大量项目有所帮助。好吧,我完全忽略了这个问题。我将我的基本SQL查询转换为在Python中使用,插入了参数,并保留了多余的字符。感谢您的帮助和发现错误。现在我已经消除了杂散周期,它工作得非常完美。