2016-07-09 66 views
-1

我想知道如何在更新第二個表中的特定字段時將表插入到表中。更新第一個表中的行並在單個查詢中向第二個表中插入一行

比方說,我有表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; 

我可以以某種方式與此結合更新查詢?

INSERT INTO dif (pKey, Number) VALUES (15, 12); 

「12」是UPDATE之前和之後的「article.Number」之間的差異。

+1

只是使具有事務的存儲過程。對於調用者來說,它是一個查詢 – Drew

+1

你是否需要[正在創建觸發器](https://dev.mysql.com/doc/refman/5.7/en/create-trigger.html)在正在更新的表上行動是插入到其他表? –

回答

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 ; 
+1

感謝分號,陌生人! –

+0

他可能希望計算淨值,但問題不清楚如何執行(prev值,null轉換爲0等等) – Drew

+0

Thanks @ S.C。不幸的是修改表格設計會破壞太多的東西。觸發器是我真正需要的。 – 0xbadc0de

相關問題