如何在 sqlite3 中使用另一个 table 的 __rowid__ 来更新 table

How to UPDATE a table by using __rowid__ of another table in sqlite3

我正在使用 __rowid__ 进行 CRUD 操作,它是 sqlite table 的默认设置。我的任何 table 中都没有单独的 ID 列。
我的创建、读取和删除操作已完成。
我正在按客户名称搜索数据库。

表格

UPDATE 查询 customers table

cursor.execute("""
SELECT * FROM customers
WHERE name = ?""", (name_variable.get(),))

cursor.execute("""
UPDATE customers SET
'contact' = ?,
'mail' = ?,
'address' = ?
WHERE name = ?
""",
(
contact_variable.get(),
mail_variable.get(),
address_variable.get(),
name_variable.get()
)
)

我的问题是更新 services & charges table。
我想要的是,如果用户更改 John's 信息,那么我如何使用 __rowid__UPDATEJohn's 数据发送到这两个 table。我不明白如何执行该查询。
(我在 Ubuntu 20.04 上使用 sqlite3 版本 3.31.1)。

根据您显示的架构,客户、服务和费用之间没有任何关系,因此更新客户与其他 table 没有关系。因此,您可能想要一段关系以及您说

的含义

then how do I UPDATE only John's data to these two tables using rowid

答案是 rowid 列,因为没有关系,除了在各自的 table 中唯一标识一行外,不做任何事情。

所以首先你需要定义关系,这将需要

  1. 在两个 tables(服务和费用)中的每一个中的一列,以满足 parent(客户)children(服务将 children of a customer and charges will be children of a customer) aka two one (customer) to many (services and charges) relationship, or
  2. 映射参考 table 如果您需要 many-many 关系。

通常,mapping/reference/relating/linking/associating children 到 parents 最有效的方法是利用始终存在(但通常隐藏)的 rowid,将其别名为列名(例如 id整数主键)。

因此,您可能希望 table 定义类似于:-

CREATE TABLE IF NOT EXISTS customers (
    customer_id INTEGER PRIMARY KEY, 
    name TEXT, 
    contact TEXT, 
    mail TEXT, 
    address TEXT
);
  • customer_id是rowid列的别名

然后 :-

CREATE TABLE IF NOT EXISTS services (
    serviceid INTEGER PRIMARY KEY,
    service TEXT, subservice TEXT, 
    customer_id INTEGER REFERENCES customers(customer_id) ON DELETE CASCADE ON UPDATE CASCADE 
);
  • service_id列是rowid列的别名
  • customer_id 列引用 parent,即服务所属的客户。
  • REFERENCES 关键字连同 table 和关联的列定义了一个约束,表明 customer_id 列必须是客户 customer_id 列中存在的值 table(即外键约束(规则))。

然后 :- - ON DELETE CASCADE 表示,如果 parent 被删除,则 parent 的所有 children 将从 parent 向下删除。 - ON UPDATE 类似,但将任何更改级联到客户 table.

中的 customer_id 列
CREATE TABLE IF NOT EXISTS charges (
    initialcharges REAL, 
    taxes REAL, 
    discount REAL, 
    advance REAL, 
    total REAL, 
    customer_id INTEGER REFERENCES customers(customer_id) ON DELETE CASCADE ON UPDATE CASCADE 
);
  • 类似于服务

现在假设您然后插入一些 (2) 客户(请注意,对于演示特定的 customer_id 值是指定的,而不是允许它们自动生成)使用 :-

INSERT OR IGNORE INTO customers VALUES
    (10,'John','something','something','something')
    ,(20,'Jane','something','something','something')
;

然后使用:-

SELECT *,rowid FROM customers;

然后:-

  • 请注意,rowid 显示为 customer_id(1),因为它现在具有 customer_id 作为别名,并且它与 customer_id 列的值完全匹配。

现在我们使用以下方式向服务 table 添加一些行:-

INSERT INTO services (service,subservice,customer_id) VALUES
    ('Exterior','something',10)
    ,('Interior','something',10)
    ,('Interior','something',20)
;
  • 请注意 customer_id 是来自客户 table 的 customer_id 列的值,因此您如何将每个服务行与一个客户相关联。

使用:-

SELECT *,rowid FROM services;

结果:-

  • 再次 rowid 匹配它的别名 但是 两列都只是服务中行的唯一标识符 table 它对 a 之间的关系没有意义服务行,它是 parent 客户(因此 rowid 对您想要的东西没有用)。
  • 在关系方面,重要的行是 customer_id 行,它指定了 parent.

同样适用于费用 table :-

INSERT INTO charges (initialcharges,taxes,discount,advance,total,customer_id) VALUES
    (10.50,0.50,1.5,0,11.50,10),
    (105.00,05.00,1.5,0,115,20)
;
SELECT *,rowid FROM charges; 

现在说你用过-

SELECT customers.*,customers.rowid AS custid,' - ' AS ' ', services.*,services.rowid AS sid,' - ' AS ' ',charges.*,charges.rowid AS cid
FROM customers 
    JOIN services ON services.customer_id = customers.customer_id
    JOIN charges ON charges.customer_id = customers.customer_id
;

然后你得到:-

如果使用 :-

将 John 的名字更改为 Fred
UPDATE customers SET name = 'Fred' WHERE name = 'John';

然后当从特定行访问 John(现在是 Fred)时,在以后的查询中无需任何特殊处理即可看到它的更改,例如

SELECT customers.*,customers.rowid AS custid,' - ' AS ' ', services.*,services.rowid AS sid,' - ' AS ' ',charges.*,charges.rowid AS cid 
FROM customers 
    JOIN services ON services.customer_id = customers.customer_id
    JOIN charges ON charges.customer_id = customers.customer_id
; 

现在的结果是:-

但是,假设 Jane 的 ID 已更改为 10000,使用:-

UPDATE customers SET customer_id = 10000 WHERE customer_id = 20;

然后使用相同的查询结果:-

即 ne 值 (10000) 已自动应用于 children(并不是说您可能会经常更改 customer_id)。

  • 注意 如果您更新了 child 的列(如果它没有违反 FK 约束)那么该更改不会传播到parent。 parent 将被切换。

  • 删除方法类似,删除parent,children将被删除。删除一个 child 并且 child 就是 child.

所以像上面那样,你需要做的就是更新任何你需要更新的东西。

  • 注意以上不一定能反映你真正想要的,只是原理的示范。