我有一个主表,比如tbl
,它有三列。假设我创建了一个表格,该表格仅显示与col1
和col2
组合相关的第一条记录。这种表的SQL定义如下:
CREATE TABLE pseudo_view AS SELECT col1, col2, col3 FROM tbl GROUP BY col1 col2
现在,我在此新表中看到了col1
和col2
的所有独特组合。我更新此表,以便更改给定记录的col3
。我希望通过影响所有重复记录将其应用回主表tbl
。
我知道标准视图无法做到这一点。但是,有没有办法创建一个从属表,当它更新时,主表将按照选择机制的定义进行更新?我希望有一个解决方案,这个伪视图表可以自由更新和删除其记录,同时也影响父表。
答案 0 :(得分:1)
它可以在pseudo_view和tbl
上使用一些触发器对于tbl上的插入,更新和删除,“视图”需要相应地更新。通常这很容易。唯一困难的部分是当你删除最后一对col1和col2时。
对于pseudo_table的更新和删除,您需要定义主服务器上应该更改的内容。
在我的示例中,我选择将min(3)作为函数,因此当更新行时,同一行(曾经具有最小col3的行)更新并且新(可能是相同的)值对于psuedotable计算。
当一行被删除时,tbl中的所有行都需要去,否则它们也会伪造一行(并且刚被删除)。
CREATE TABLE tbl (col1 INT, col2 INT, col3 INT);
INSERT INTO tbl VALUES (1, 1, 1), (1, 1, 2), (2, 2, 3), (2, 2, 4);
CREATE TABLE pseudo_view
AS
SELECT
col1,
col2,
MIN(col3) AS col3
FROM tbl
GROUP BY col1, col2;
DELIMITER //
-- update the row that originally was the min() and make sure that the new row in pseudo is the new min()
CREATE TRIGGER upd_pseudo
BEFORE UPDATE ON
pseudo_view FOR EACH ROW
BEGIN
UPDATE tbl
SET col3 = NEW.col3
WHERE col1 = OLD.col1
AND col2 = OLD.col2
AND col3 = OLD.col3;
SET NEW.col3 := (SELECT
MIN(col3)
FROM tbl
WHERE col1 = OLD.col1
AND col2 = OLD.col2);
END //
-- delete all rows in tbl that has this col1 and col2
CREATE TRIGGER del_pseudo
AFTER DELETE ON
pseudo_view FOR EACH ROW
BEGIN
DELETE FROM tbl
WHERE col1 = OLD.col1 AND col2 = OLD.col2;
END //
-- update pseudo to make sure it's still true
CREATE TRIGGER upd_tbl
AFTER UPDATE ON
tbl FOR EACH ROW
BEGIN
UPDATE pseudo_view
SET col3 = (SELECT
min(col3)
FROM tbl
WHERE col1 = NEW.col1 AND col2 = NEW.col2)
WHERE col1 = NEW.col1 AND col2 = NEW.col2;
END//
-- update pseudo to make sure it's still true
CREATE TRIGGER ins_tbl
AFTER INSERT ON
tbl FOR EACH ROW
BEGIN
REPLACE pseudo_view
VALUES (NEW.col1, NEW.col2, (SELECT
min(col3)
FROM tbl
WHERE col1 = NEW.col1 AND col2 = NEW.col2));
END//
-- update pseudo to make sure it's still true
CREATE TRIGGER del_tbl
AFTER DELETE ON
tbl FOR EACH ROW
BEGIN
-- todo: add special case when the delete row was the last of that col1/col2-pair
REPLACE pseudo_view
VALUES (NEW.col1, NEW.col2, (SELECT
min(col3)
FROM tbl
WHERE col1 = NEW.col1 AND col2 = NEW.col2));
END//