sqlite 是否可以将cursor.fetchall()赋值给一个变量?

fjaof16o  于 2022-12-19  发布在  SQLite
关注(0)|答案(2)|浏览(144)
rows_order = "SELECT COUNT (*) FROM 'Order'"
            cursor.execute(rows_order)
            ordernum = cursor.fetchall()
            connection.commit()

cursor.execute("INSERT INTO 'Order' (OrderNo, CustomerID, Date, TotalCost) VALUES (?,?,?,?)", (
                [ordernum], custid_Sorder, now, total_item_price))

这是我正在尝试的,但这个错误弹出;

sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.

我该如何解决这个问题?我想让订单号等于它之前的订单数量,因此我想给它赋值订单号。(我使用的是sqlite3)

jq6vz3qz

jq6vz3qz1#

因为只有一个值,所以只需要fetchone

import sqlite3
con = sqlite3.connect("tutorial.db")
cursor = con.cursor()
rows_order = "SELECT COUNT (*) FROM 'Order'"
cursor.execute(rows_order)
ordernum  = cursor.fetchone()[0]
cursor.execute("INSERT INTO 'Order' (OrderNo, CustomerID, Date, TotalCost) VALUES (?,?,?,?)", (
                ordernum, custid_Sorder, now, total_item_price))
mftmpeh8

mftmpeh82#

tl;dr不要这样做。请使用auto-incremented primary key

fetchall将所有行作为列表返回,即使只有一行。
相反,使用fetchone。这将返回一个元组,然后您可以选择第一项。ordernum = cursor.fetchone()[0]
但是,您似乎正在编写一个查询来获取下一个ID。使用count(*)是错误的。如果OrderNo中有任何空白,例如,如果删除了某些内容,它可能会返回一个重复。count(*)将返回3。请改用max(OrderNo)
此外,如果您试图同时插入两个订单,则可能会出现争用情况,其中一个订单将试图复制另一个订单。

process 1                  process 2
select max(orderNo)
fetchone # 4
                           select max(orderNo)
                           fetchone # 4
insert into orders...
                           insert into orders...  # duplicate OrderNo

要避免这种情况,必须在transaction中同时执行select和insert操作。

process 1                  process 2
begin
select max(orderNo)...
fetchone # 4               begin
                           select max(orderNo)
                           fetchone
insert into orders...      # wait
commit                     # wait
                           # 5
                           insert into orders...
                           commit

更好的是,将它们作为单个查询来执行。

insert into "Order" (OrderNo, CustomerID, Date, TotalCost)
select max(orderNo), ?, ?, ?
from "order"

更好的是***根本不做***。有一个内置的机制可以使用auto-incremented primary keys来做这件事。

-- order is a keyword, pluralizing table names helps to avoid them
create table orders (
  -- It is a special feature of SQLite that this will automatically be unique.
  orderNo integer primary key
  customerID int,
  -- date is also a keyword, and vague. Use xAt.
  orderedAt timestamp,
  totalCost int
)

-- orderNo will automatically be set to a unique number
insert into orders (customerID, orderedAt, totalCost) values (...)

相关问题