2016-07-09 13 views
-1

2番目のテーブルの特定のフィールドを更新する際にテーブルに行を挿入する方法を理解しようとしています。最初のテーブルの行を更新し、1つのクエリで2番目のテーブルに行を挿入してください

のは、私は表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」の違いです。

+1

だけトランザクションを持つストアドプロシージャを作成します。呼び出し側には1つのクエリ – Drew

+1

更新されるテーブルの[トリガを作成する](https://dev.mysql.com/doc/refman/5.7/en/create-trigger.html)が必要ですか?アクションは、他のテーブルに挿入することですか? –

答えて

1

いいえ、しかし、これらの両方を実行し、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'); 

EDIT:もう一度あなたの質問を読んだ後、あなたがちょうど自然に適応するように設定されていないことを、あなたのデータモデルトラック監査情報を作成しようとしているように私には思えます。あなたはモデルをコントロールできますか?もしそうなら、(以下何の作業例えばhereを参照)、このような何かを考えてみましょう。あなたが個別に番号を追跡することができますので

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; 

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; 

たぶん物事を簡単にするために、いくつかのビューを追加現在の基本レコードから現在の番号が何であるかを簡単に判別できるようになりました。これで、更新および挿入文機能を組み合わせることができます。下記参照。

まず、いくつかのテストデータ:

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

彼はネットを計算したがっているかもしれませんが、それがどのように実行されるかについての質問は明確ではありません(前の値、0に変換されたヌルなど) – Drew

+0

ありがとう@S.S.C。残念ながら、テーブルのデザインを変更すると、あまりにも多くのことが破られます。トリガーは、私が実際に必要とするものです。 – 0xbadc0de

関連する問題