Files
StudyNote/山东理工大学/其他/lab3.md
2026-02-13 23:38:38 +08:00

260 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
```sql
-- 增删改
INSERT INTO products (maker, model, type)
VALUES ('I', '3008', 'printer');
INSERT INTO sales (customer_id, model, quantity, day, paid, type_of_payment)
VALUES ('1112223333', '3008', 2, '2024-01-01', 200, 'cash');
INSERT INTO customers (customer_id, firstname, lastname, city, address, email)
VALUES ('1112223333', 'Lisa', 'Smith', 'Dublin', '5 Main St.', 'lisa@example.com');
-- 更新
UPDATE pcs
SET price = 2200
WHERE model = '1001';
UPDATE sales
SET type_of_payment = 'visa credit'
WHERE customer_id = '1122334455' AND model = '2010';
UPDATE customers
SET email = 'norah.jones@yahoo.com'
WHERE customer_id = '9999999999';
-- 删除
DELETE FROM printers
WHERE model = '3006';
DELETE FROM sales
WHERE day = '2013-12-17';
DELETE FROM customers
WHERE customer_id = '1231231231';
-- 完成数据库新用户创建、
CREATE USER `zds`
-- 授权访问数据库、
GRANT SELECT, UPDATE, INSERT ON TABLE sales TO zds;
-- 授权用户传递权限with grant option
GRANT SELECT ON sdut.sales TO zds WITH GRANT OPTION
-- 收回用户的sales表更新权限
REVOKE UPDATE ON sdut.sales FROM zds;
-- 收回所有权限(彻底回收)
REVOKE ALL PRIVILEGES ON sdut.sales FROM zds
-- 删除创建的用户
DROP USER zds;
-- 触发器
-- 1
CREATE TABLE pcprice_log (
log_id INT AUTO_INCREMENT PRIMARY KEY,
model VARCHAR(10) NOT NULL,
old_price DECIMAL(10,2) NOT NULL,
new_price DECIMAL(10,2) NOT NULL
);
CREATE TRIGGER insert_pcpricelog_values_when_pc_price_changed
AFTER UPDATE ON pcs
FOR EACH ROW
BEGIN
IF OLD.price != NEW.price THEN
INSERT INTO pcprice_log (model, old_price, new_price)
VALUES (OLD.model, OLD.price, NEW.price);
END IF;
END;
-- 测试
-- INSERT INTO pcs (model, price, speed, ram, hd )
-- VALUES ('1005', 200, 3.0, 8, 512);
-- UPDATE pcs set price=22 WHERE model=1005
-- 2定义AFTER行级触发器当删除顾客表Customer中的一个顾客信息后同时删除购买信息表Sales中该顾客的所有购买记录
CREATE TRIGGER deleteCustomer
after DELETE on customers
for each row
BEGIN
DELETE FROM sales
WHERE customer_id = OLD.customer_id;
END
-- -- 测试
-- DELETE FROM customers WHERE customer_id=9999999999
-- 3需要对在表上进行DML操作的用户进行安全检查看是否具有合适的特权
-- 权限表存储用户可执行的DML权限JSON数组格式如["insert","update"]
CREATE TABLE IF NOT EXISTS userPrivilege (
id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(100) NOT NULL UNIQUE COMMENT '用户名格式user@host如root@localhost匹配CURRENT_USER()',
privilege JSON NOT NULL COMMENT '权限列表JSON数组值为"insert"/"update"/"delete"(统一小写)',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '权限创建时间'
);
-- 插入测试数据给用户zds@localhost分配INSERT/UPDATE权限不给DELETE权限
INSERT INTO userPrivilege (user_name, privilege)
VALUES ('zds@localhost', '["insert", "update"]');
-- 权限表存储用户可执行的DML权限JSON数组格式如["insert","update"]
CREATE TABLE IF NOT EXISTS userPrivilege (
id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(100) NOT NULL UNIQUE COMMENT '用户名格式user@host如root@localhost匹配CURRENT_USER()',
privilege JSON NOT NULL COMMENT '权限列表JSON数组值为"insert"/"update"/"delete"(统一小写)',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '权限创建时间'
);
-- 插入测试数据给用户zds@localhost分配INSERT/UPDATE权限不给DELETE权限
INSERT INTO userPrivilege (user_name, privilege)
VALUES ('zds@localhost', '["insert", "update"]');
DELIMITER //
CREATE TRIGGER trg_check_update_priv
BEFORE UPDATE ON customers -- 同样可替换为目标表
FOR EACH ROW
BEGIN
DECLARE user_priv JSON;
DECLARE has_update INT DEFAULT 0;
DECLARE curr_user VARCHAR(100) DEFAULT CURRENT_USER();
-- 查询当前用户权限
SELECT privilege INTO user_priv
FROM userPrivilege
WHERE user_name = curr_user;
-- 判断是否有"update"权限
IF user_priv IS NOT NULL THEN
SET has_update = JSON_CONTAINS(user_priv, '"update"');
END IF;
-- 无权限抛错
IF has_update = 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = CONCAT('安全检查失败:用户 [', curr_user, '] 无 ', TABLE_NAME, ' 表的 UPDATE 权限');
END IF;
END //
DELIMITER ;
DELIMITER //
CREATE TRIGGER trg_check_delete_priv
BEFORE DELETE ON customers -- 同样可替换为目标表
FOR EACH ROW
BEGIN
DECLARE user_priv JSON;
DECLARE has_delete INT DEFAULT 0;
DECLARE curr_user VARCHAR(100) DEFAULT CURRENT_USER();
-- 查询当前用户权限
SELECT privilege INTO user_priv
FROM userPrivilege
WHERE user_name = curr_user;
-- 判断是否有"delete"权限
IF user_priv IS NOT NULL THEN
SET has_delete = JSON_CONTAINS(user_priv, '"delete"');
END IF;
-- 无权限抛错
IF has_delete = 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = CONCAT('安全检查失败:用户 [', curr_user, '] 无 ', TABLE_NAME, ' 表的 DELETE 权限');
END IF;
END //
DELIMITER ;
-- 4如果某个特定客户ID的购买记录从销售表中删除后则从客户表中删除该客户。
CREATE TRIGGER deleteCustomer_by4
AFTER DELETE on sales
for each row
BEGIN
DELETE FROM customers
WHERE customer_id = OLD.customer_id;
END
CREATE TRIGGER discount AFTER INSERT ON sales FOR EACH ROW
BEGIN
DECLARE
sum_paid DECIMAL ( 12, 2 );
DECLARE
discount DECIMAL ( 5, 2 );
SELECT
sum( paid ) INTO sum_paid
FROM
sales
WHERE
customer_id = NEW.customer_id;
SELECT
discount INTO discount
FROM
customers
WHERE
customer_id = NEW.customer_id;
IF
SUM_paid > 10000
AND discount < 10.00 THEN
UPDATE customers
SET discount = 10.00
WHERE
customer_id = NEW.customer_id;
END IF;
END
-- 6在客户中添加一个新的"AllPaid"栏,如果插入或更新或删除一个销售元组,那么修改该客户的"AllPaid"的值
ALTER TABLE customers
ADD COLUMN AllPaid DECIMAL(12,2) NOT NULL DEFAULT 0.00
CREATE TRIGGER insert_value_customer
AFTER INSERT on customers
for each ROW
BEGIN
UPDATE customers
set AllPaid =(
SELECT SUM(paid) FROM sales
WHERE customer_id = NEW.customer_id
)
WHERE customer_id = NEW.customer_id;
END
CREATE TRIGGER UPDATE_value_customer
AFTER UPDATE on customers
for each ROW
BEGIN
UPDATE customers
set AllPaid =(
SELECT SUM(paid) FROM sales
WHERE customer_id = NEW.customer_id
)
WHERE customer_id = NEW.customer_id;
END
CREATE TRIGGER DELETE_value_customer
AFTER DELETE on customers
for each ROW
BEGIN
UPDATE customers
set AllPaid =(
SELECT SUM(paid) FROM sales
WHERE customer_id = old.customer_id
)
WHERE customer_id = old.customer_id;
END
-- 测试
```