如何在 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__
将 UPDATE
仅 John'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 中唯一标识一行外,不做任何事情。
所以首先你需要定义关系,这将需要
- 在两个 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
- 映射参考 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.
所以像上面那样,你需要做的就是更新任何你需要更新的东西。
- 注意以上不一定能反映你真正想要的,只是原理的示范。
我正在使用 __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__
将 UPDATE
仅 John'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 中唯一标识一行外,不做任何事情。
所以首先你需要定义关系,这将需要
- 在两个 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
- 映射参考 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 的名字更改为 FredUPDATE 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.
所以像上面那样,你需要做的就是更新任何你需要更新的东西。
- 注意以上不一定能反映你真正想要的,只是原理的示范。