我正试图弄清楚如何在更新第二个表中的特定字段时向表中插入行。
假设我有表1(dif
):
CREATE TABLE dif
(
Position INT(10) UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
pKey SMALLINT(3) UNSIGNED NOT NULL,
Number SMALLINT(3) UNSIGNED DEFAULT 0 NOT NULL
);
ALTER TABLE dif
ADD CONSTRAINT dif_article_pKey_fk
FOREIGN KEY (pKey) REFERENCES article (pKey) ON UPDATE CASCADE;
和表2(article
):
CREATE TABLE IF NOT EXISTS article (
pKey smallint(3) unsigned NOT NULL AUTO_INCREMENT,
Name varchar(80) COLLATE utf8_roman_ci NOT NULL,
Number SMALLINT NOT NULL DEFAULT 0
PRIMARY KEY (pKey)
);
表格文章中填充了一些数据,应该只更新。表“dif”在开头是空的。所以,假设我正在更新“文章”中的字段,如下所示:
UPDATE article SET pKey = 15, Name = SomeName, Number = 22 WHERE pKey=15;
我可以以某种方式将UPDATE查询与此结合起来吗?
INSERT INTO dif (pKey, Number) VALUES (15, 12);
“12”是UPDATE之前和之后“article.Number”之间的差异。
答案 0 :(得分:1)
不,但您可以创建一个存储过程来执行这两个操作,然后在一个语句中执行它。
create procedure GiveThisABetterName
(
in pKey int,
in newNumber int,
in currentNumber int,
in newName varchar(100)
)
begin
update
article
set
Name = newName, Number = newNumber
where
pKey = pKey;
insert into dif (pKey, Number) values (pKey, newNumber);
end
我的mysql语法生锈了,但应该很接近。然后当你想执行它时:
call GiveThisABetterName(12, 15, 22, 'Some Name');
编辑:在再次阅读您的问题之后,在我看来,您正在尝试使您的数据模型跟踪审核信息,而这些信息并未设置为自然适应。你有控制模型吗?如果是这样,请考虑这样的事情(请参阅here以获取以下内容的工作示例):
CREATE TABLE IF NOT EXISTS article (
pKey smallint(3) unsigned NOT NULL AUTO_INCREMENT,
Name varchar(80) COLLATE utf8_roman_ci NOT NULL,
PRIMARY KEY (pKey)
);
CREATE TABLE ArticleNumbers
(
Counter int UNSIGNED PRIMARY KEY AUTO_INCREMENT,
pKey SMALLINT(3) UNSIGNED NOT NULL,
Number SMALLINT(3) DEFAULT 0 NOT NULL,
Difference SMALLINT(3)
);
ALTER TABLE ArticleNumbers
ADD CONSTRAINT ArticleNumbers_article_pKey_fk
FOREIGN KEY (pKey) REFERENCES article (pKey) ON UPDATE CASCADE;
可能会添加一些视图以简化操作:
CREATE VIEW GroupedArticleNumbers
as
select pKey, max(Counter) as Counter
from ArticleNumbers
group by pKey;
CREATE VIEW CurrentArticles
as
select article.pKey, article.Name, numbers.Number, numbers.Difference
from article
left outer join GroupedArticleNumbers filter on article.pKey = filter.pKey
left outer join ArticleNumbers numbers on filter.Counter = numbers.Counter;
由于您现在可以单独跟踪基本记录中的数字,但仍然可以轻松确定当前的数字,现在可以组合更新和插入语句功能。见下文。
首先,一些测试数据:
insert into article (Name) values ('Test');
insert into ArticleNumbers (pKey, Number, Difference) values (1, 10, null);
insert into ArticleNumbers (pKey, Number, Difference) select 1, 20, 20 - Number from CurrentArticles where pKey = 1;
insert into ArticleNumbers (pKey, Number, Difference) select 1, 50, 50 - Number from CurrentArticles where pKey = 1;
insert into ArticleNumbers (pKey, Number, Difference) select 1, 15, 15 - Number from CurrentArticles where pKey = 1;
一旦设置架构的开销已经完成,看看有多好用吗?
获取我们创建的文章的当前数字:
select * from currentarticles where pKey = 1
获取该文章的编号记录:
select * from article
left outer join articlenumbers on article.pkey = articlenumbers.pkey
order by counter asc
如果您愿意搞乱数据模型,可以选择存储过程。
或者,如果您想将触发器用作@Jonathan Leffler建议,那么这样的事情应该有效:
CREATE TABLE article (
pKey smallint(3) unsigned NOT NULL AUTO_INCREMENT,
Name varchar(80) COLLATE utf8_roman_ci NOT NULL,
Number SMALLINT(3) DEFAULT 0 NOT NULL,
PRIMARY KEY (pKey)
);
CREATE TABLE ArticleNumbers
(
Counter int UNSIGNED PRIMARY KEY AUTO_INCREMENT,
pKey SMALLINT(3) UNSIGNED NOT NULL,
Number SMALLINT(3) DEFAULT 0 NOT NULL,
Difference SMALLINT(3)
);
delimiter $
create trigger tr_u_article
before update on article
for each row
begin
insert into ArticleNumbers (pKey, Number, Difference) select old.pKey, new.Number, new.Number - old.Number
end;
delimiter ;