我在这个数据库中使用了sqlite3。
对于作业,我为您的典型食品订购网站建立了一个数据库。此数据库中名为customer_order
的表包含客户发出的所有订单。此表还包含订购食物的人的递送地址列。该数据库还包含一个名为customer
的表,其中包含每个客户的家庭地址(客户的家庭地址以前缀preffered_
为特征)。
由于您可能希望在您不在家时向您的人提供食物,因此在插入customer_order
时,与送货地址对应的列可以是除客户家庭地址之外的其他地址
我想要做的是创建一个触发器,当在customer_order
表的插入中没有指定传递地址时,该触发器会自动用客户的家庭地址填充传递地址的列。< / p>
到目前为止我的代码是:
CREATE TRIGGER update_delivery_address BEFORE INSERT ON customer_order
WHEN address_street IS NULL
BEGIN
UPDATE customer_order SET address_street = (SELECT customer.preferred_address_street FROM customer WHERE customer.user_id = customer_order.user_id);
UPDATE customer_order SET address_number = (SELECT customer.preferred_address_number FROM customer WHERE customer.user_id = customer_order.user_id);
UPDATE customer_order SET address_zipcode = (SELECT customer.preferred_address_zipcode FROM customer WHERE customer.user_id = customer_order.user_id);
UPDATE customer_order SET address_city = (SELECT customer.preferred_address_city FROM customer WHERE customer.user_id = customer_order.user_id);
END;
当我声明数据库时,我没有收到任何错误,但是当我尝试插入数据库时,我收到以下错误:
Error: near line 108: no such column: address_street
如果有人知道如何解决这个或更好的方法,我们非常感谢任何帮助。
CREATE TABLE `customer_order` (
`customer_order_id` int(11) NOT NULL PRIMARY KEY,
`user_id` int(11) DEFAULT NULL,
`restaurant_id` int(11) NOT NULL,
`date_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`preferred_delivery_time` datetime NOT NULL,
`full_name` varchar(300) NOT NULL,
`phone_number` varchar(14) NOT NULL,
`email_address` varchar(300) NOT NULL,
`address_street` varchar(300) DEFAULT NULL,
`address_number` varchar(8) DEFAULT NULL,
`address_zipcode` varchar(6) DEFAULT NULL,
`address_city` varchar(300) DEFAULT NULL,
`geolocation` VARCHAR(30) NOT NULL,
`is_paid` tinyint(4) NOT NULL,
`notes` text DEFAULT NULL,
`active` tinyint(4) NOT NULL DEFAULT '1',
FOREIGN KEY(user_id) REFERENCES user(user_id),
FOREIGN KEY(restaurant_id) REFERENCES restaurant(restaurant_id)
);
和
CREATE TABLE `customer` (
`user_id` int(11) NOT NULL PRIMARY KEY,
`preferred_address_street` varchar(300) NOT NULL,
`preferred_address_number` varchar(8) NOT NULL,
`preferred_address_zipcode` varchar(6) NOT NULL,
`preferred_address_city` varchar(300) NOT NULL,
`geolocation` VARCHAR(30) NOT NULL,
`discount_points_collected` int(11) NOT NULL,
FOREIGN KEY(user_id) REFERENCES user(user_id)
);
答案 0 :(得分:1)
我认为你的问题是WHEN子句,它应该使用 new / 旧表而不是实际表(因为它只是一个INSERT触发器) 新是可用的)。
按照: -
WHEN子句和触发器操作都可以访问 使用引用插入,删除或更新的行 形成“NEW.column-name”和“OLD.column-name”,其中column-name是 与触发器关联的表中列的名称。 OLD和NEW引用只能用于事件触发器 它们是相关的,如下:
INSERT 新引用有效
更新新和 OLD 引用 有效
DELETE OLD 引用有效
我也相信你需要一个WHERE子句来限制UPDATE。我还建议一个UPDATE。
因此我建议使用: -
CREATE TRIGGER IF NOT EXISTS update_delivery_address AFTER INSERT ON customer_order
WHEN new.address_street IS NULL
BEGIN
UPDATE customer_order SET address_street = (SELECT customer.preferred_address_street FROM customer WHERE customer.user_id = customer_order.user_id),
address_number = (SELECT customer.preferred_address_number FROM customer WHERE customer.user_id = customer_order.user_id),
address_zipcode = (SELECT customer.preferred_address_zipcode FROM customer WHERE customer.user_id = customer_order.user_id),
address_city = (SELECT customer.preferred_address_city FROM customer WHERE customer.user_id = customer_order.user_id)
WHERE customer_order_id = new.customer_order_id;
END;
以上内容已经过测试,但只有一个新订单和有限的客户/用户,还删除了外国餐厅参考,以下用于测试: -
INSERT INTO customer_order VALUES(1,1,10,'2018-10-10','20:30','Fred Bloggs','1234567890','fred@fred.com',null,null,null,null,'????','0','',1);
结果行为: -
CREATE TRIGGER IF NOT EXISTS update_delivery_address
AFTER INSERT ON customer_order
WHEN new.address_street IS NULL
BEGIN
UPDATE customer_order
SET (address_street, address_number, address_zipcode, address_city) =
(SELECT preferred_address_street,
preferred_address_number,
preferred_address_zipcode,
preferred_address_city
FROM customer
WHERE customer.user_id = customer_order.user_id
)
WHERE customer_order_id = new.customer_order_id;
END
;
注意我认为这至少需要SQLite发布 3.16.1 (上面是在3.21.0上测试过的。)
修复有关在触发器中使用行值的错误(请参阅ticket 8c9458e7)版本3.15.0但直到之后才报告 发布3.16.0版本后的片刻。
DROP TABLE IF EXISTS customer_order;
CREATE TABLE IF NOT EXISTS `customer_order` (
`customer_order_id` int(11) NOT NULL PRIMARY KEY,
`user_id` int(11) DEFAULT NULL,
`restaurant_id` int(11) NOT NULL,
`date_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`preferred_delivery_time` datetime NOT NULL,
`full_name` varchar(300) NOT NULL,
`phone_number` varchar(14) NOT NULL,
`email_address` varchar(300) NOT NULL,
`address_street` varchar(300) DEFAULT NULL,
`address_number` varchar(8) DEFAULT NULL,
`address_zipcode` varchar(6) DEFAULT NULL,
`address_city` varchar(300) DEFAULT NULL,
`geolocation` VARCHAR(30) NOT NULL,
`is_paid` tinyint(4) NOT NULL,
`notes` text DEFAULT NULL,
`active` tinyint(4) NOT NULL DEFAULT '1',
FOREIGN KEY(user_id) REFERENCES user(user_id)
--FOREIGN KEY(restaurant_id) REFERENCES restaurant(restaurant_id)
);
DROP TABLE IF EXISTS customer;
CREATE TABLE `customer` (
`user_id` int(11) NOT NULL PRIMARY KEY,
`preferred_address_street` varchar(300) NOT NULL,
`preferred_address_number` varchar(8) NOT NULL,
`preferred_address_zipcode` varchar(6) NOT NULL,
`preferred_address_city` varchar(300) NOT NULL,
`geolocation` VARCHAR(30) NOT NULL,
`discount_points_collected` int(11) NOT NULL,
FOREIGN KEY(user_id) REFERENCES user(user_id)
);
DROP TABLE IF EXISTS user;
CREATE TABLE IF NOT EXISTS user (
user_id INTEGER PRIMARY KEY,
user_name TEXT
);
DROP TRIGGER IF EXISTS update_delivery_address;
CREATE TRIGGER IF NOT EXISTS update_delivery_address
AFTER INSERT ON customer_order
WHEN new.address_street IS NULL
BEGIN
UPDATE customer_order
SET (address_street, address_number, address_zipcode, address_city) =
(SELECT preferred_address_street,
preferred_address_number,
preferred_address_zipcode,
preferred_address_city
FROM customer
WHERE customer.user_id = customer_order.user_id
)
WHERE customer_order_id = new.customer_order_id;
END
;
INSERT INTO user (user_name) VALUES ('Fred'),('Bert'),('Harry'),('Tom');
INSERT INTO customer (
user_id,
preferred_address_street,
preferred_address_number,
preferred_address_zipcode,
preferred_address_city,
geolocation,discount_points_collected)
VALUES (1,'Somerset Blvd','1','12345','Syndey','?????',100);
INSERT INTO customer_order (
customer_order_id,
user_id,
restaurant_id,
preferred_delivery_time,
full_name,
phone_number,
email_address,
geolocation,
is_paid,
notes
)
VALUES(1,1,20,'21:30','Fred Bloggs','0000 000 000','Fred@Bloggs.com','x',0,'not to note');
答案 1 :(得分:-1)
使用insert join for trigger分别更新每一列。您需要after insert
触发器
试试这个
CREATE TRIGGER update_delivery_address ON customer_order
AFTER INSERT
AS
BEGIN
UPDATE c
SET address_street = cu.preferred_address_street
FROM customer_order c
INNER JOIN INSERTED i ON c.user_id = i.user_id
INNER JOIN Customer cu ON c.user_id = cu.user_id
WHERE c.Address_street IS NULL
UPDATE c
SET address_number = cu.preferred_address_number
FROM customer_order c
INNER JOIN INSERTED i ON c.user_id = i.user_id
INNER JOIN Customer cu ON c.user_id = cu.user_id
WHERE c.Address_street IS NULL
UPDATE c
SET address_zipcode = cu.preferred_address_zipcode
FROM customer_order c
INNER JOIN INSERTED i ON c.user_id = i.user_id
INNER JOIN Customer cu ON c.user_id = cu.user_id
WHERE c.Address_street IS NULL
UPDATE c
SET address_city = cu.preferred_address_city
FROM customer_order c
INNER JOIN INSERTED i ON c.user_id = i.user_id
INNER JOIN Customer cu ON c.user_id = cu.user_id
WHERE c.Address_street IS NULL
END;