
特定のカラムが更新されたときのみ、そのレコードを別テーブルへ格納するトリガの作成方法を教えてください・
トリガ名:TEST_UPDATE
テーブル名:MV_ORACLE_MV_TEST
カラム名:ORAPRIME
ORACHANGE
ORANAME
CHANGENAME
対象カラム:CHANGENAME
格納先テーブル:TRITEST_ORACLE_MV_TEST
作成トリガ:
CREATE OR REPLACE TRIGGER TEST_UPDATE
after update of CHANGENAME on MV_ORACLE_MV_TEST
FOR EACH ROW
begin
INSERT INTO TRITEST_ORACLE_MV_TEST
SELECT MV_ORACLE_MV_TEST.ORAPRIME ,
MV_ORACLE_MV_TEST.ORACHANGe ,
MV_ORACLE_MV_TEST.ORANAME ,
MV_ORACLE_MV_TEST.CHANGENAME
FROM
MV_ORACLE_MV_TEST
where
MV_ORACLE_MV_TEST.CHANGENAME = :new.CHANGENAME
-- commit;
commit;
end
/
テーブルMV_ORACLE_MV_TESTのうち、CHANGENAMEカラムが変更(更新)されたレコードのみを、
TRITEST_ORACLE_MV_TESTテーブルに格納したいと思っております。
この時、他のカラムも一緒に格納することが必要でして、
(もしカラムに変更があった場合、そのカラムも変更する。変更されていない場合は元の値を格納する)
そのトリガを上記のように書いたのですが、
コンパイルエラーが発生しました。
どの部分が誤っているのか、ご教授願えませんでしょうか
No.7ベストアンサー
- 回答日時:
・・・ご自身で少しは考えていらっしゃいますか?
やりたいことはそういうことなのだろうと思っていましたが敢えて書きませんでした。
CHANGENAMEが変更されたら、というIF文を書けばいいだけなのではないですか?
if :old.CHANGENAME != :new.CHANGENAME THEN
--insert
end if;
CHANGENAMEにnullが入る場合は上記の条件では足りないと思いますが、
そこはご自身で書いてください。
ありがとうございました。
if文は最初考えていたのですが、
指定する場所を間違えていたために失敗して諦めていました。
nullに関しては、テーブル側でnot null 制約のあるカラムに指定することによって対処しました
No.6
- 回答日時:
No.1、No.4です。
なぜそうしようと思うのかが自分にはよく分かりません。
MV_ORACLE_MV_TESTは参照できないということも言っているのですが・・・
No.2さんが
>selectするんじゃなく、:new.xxxxxをinsertの値にしてください。
と回答してくれていますよね?
素直に
insert into TRITEST_ORACLE_MV_TEST
values
(
:new.ORAPRIME ,
:new.ORACHANGe ,
:new.ORANAME ,
:new.CHANGENAME
)
とすればいいのでは?
マニュアルは読みましたか?
ありがとうございます。
上記の形で先程実行したのですが、
その際、マテリアライズド・ビューへの更新が複数発生したときに
CHANGENAMEを変更していないレコードも抜き出してしまいましたため、
selectで別途絞ることが必要なのかと思ってselectが必要なのかと書きました。
言葉足らずで申し訳ございません。
下記の条件で不要なものが出てしまいました。
・マテリアライズド・ビューの更新の時、CHANGENAMEを変更したものとCHANGENAME以外のカラムを変更したものが混在して変更される
・別テーブルへの書き込みがマテリアライズド・ビューへのCHANGENAMEカラムの変更があった場合をトリガとしている
・そのため、トリガの起動条件(CHANGENAMEカラムの変更があるレコードが発生)を満たしているときに、CHANGENAMEカラム以外の変更がされたレコードがあった場合、そのレコードも一緒に書き出されてしまう
と言う事象です。
※
(1)MVIEWの更新で200件更新が実行される
(2)別テーブル抜き出しの対象となる、CHANGENAMEカラムが変更されたものはそのうちの40件
(3)MVIEWでCHANGENAMEカラムに変更があることをトリガとし、トリガはその時に更新されたすべてのレコードを別テーブルに抜き出しているため、別テーブルへは200件が抜き出されてしまう
→目的は、このようなケースで(2)に該当する40件を抜き出したい
No.5
- 回答日時:
INSERTする値が、UPDATEトリガーの対象の表なのですからSELECTで値を求める必要はないと思いますけどね。
全て、:new.項目名でいいんじゃないですか。
CREATE OR REPLACE TRIGGER Log_salary_increase
AFTER UPDATE ON Emp_tab
FOR EACH ROW
BEGIN
INSERT INTO Emp_log (Emp_id, Log_date, New_salary, Action)
VALUES (:new.Empno, SYSDATE, :new.SAL, 'NEW SAL');
END;
ありがとうございます。
ただ、上記の方法ですと、
(1)MVIEWの更新で200件更新が実行される
(2)別テーブル抜き出しの対象となる、CHANGENAMEカラムが変更されたものはそのうちの40件
(3)MVIEWでCHANGENAMEカラムに変更があることをトリガとし、トリガはその時に更新されたすべてのレコードを別テーブルに抜き出しているため、別テーブルへは200件が抜き出されてしまう
という事象が発生してしまったので、どこかでselect条件が必要なのかなと考え、
select文を条件指定に入れていました。
今回、MVIEWに反映されたもののうち、update of 句で指定したカラムが変更されたレコードのみを抽出したいので、その時に同時に出てくる別レコード(update of句以外の箇所が変更されたレコード)を抽出しないという条件がネックになっています。
No.4
- 回答日時:
No.1です。
>本件は元テーブル側に原因がありました。
とありますが、コンパイル自体が出来ないのはセミコロンが抜けているからなのではないですか?
実際は記載されたコードと違ったということなのでしょうか。
>トリガのupdate条件は、
>マテリアライズド・ビューの更新を見ることはできないのでしょうか?
高速リフレッシュならばupdate文が実行されるはずですので検知できると思います。
完全リフレッシュだとdelete(もしくはtruncate)→insertとなるはずなので、検知できないのではないでしょうか。
また、
>もしかして、トリガの場合、insert into ~ select ~
>のテーブルコピー文法は使用できないのですか?
トリガーでは変更表(今回であればMV_ORACLE_MV_TEST)を参照することはできません。
ですので、No.2さんのご指摘にあるようにINSERT文を修正してください。
http://otndnld.oracle.co.jp/document/products/or …
セミコロンについては申し訳ございません。
このページに貼るときにコピーが漏れていました
(where句の最終位置のセミコロンが抜けていました)
MVIEWのリフレッシュは高速リフレッシュになっています
また、非常に申し訳ないのですが、
insert文の変更イメージが良く沸かないのですが、
insert into TRITEST_ORACLE_MV_TEST
values
(
aaa,
bbb,
ccc,
ddd
)
で書くときに、予めそれぞれの値を文頭でdeclareすることが必要ということでしょうか?
つまり、
declare
aaa VARCHAR2(45) select ORAPRIME into ORAPRIME from MV_ORACLE_MV_TEST where MV_ORACLE_MV_TEST.CHANGENAME = :new.CHANGENAME;
bbb ~~~(以下、aaaに同じ)
をbeginの前に追加する方法と言う意味です
No.3
- 回答日時:
コンパイルエラーの内容がわかりませんので、これ以上のコメントは無理かと。
マニュアルの一部ですが、
トリガー本体で使用可能なSQL文
トリガー本体には、DML SQL 文を含めることができます。 また、SELECT 文を含めることはで
きますが、SELECT... INTO... 文またはカーソル定義内のSELECT 文を指定する必要があります。
すいません。
コンパイルエラーについては、元テーブル(MVIEW)の命名エラーでしあt。
ご迷惑をおかけいたしました。
>SELECT... INTO... 文またはカーソル定義内のSELECT 文を指定する必要があります。
というのは、declareが必要ということでしょうか?
あるいは、下記のような書き方なのでしょうか?
INSERT INTO TRITEST_ORACLE_MV_TEST
SELECT (
select ORAPRIME into oraprime from MV_ORACLE_MV_TEST,
select ORACHANGE into ORACHANGE from MV_ORACLE_MV_TEST ,
select ORANAME into ORANAME from MV_ORACLE_MV_TEST,
select CHANGENAME into CHANGENAME from MV_ORACLE_MV_TEST
)
FROM MV_ORACLE_MV_TEST
where MV_ORACLE_MV_TEST.CHANGENAME = :new.CHANGENAME;
No.1
- 回答日時:
>コンパイルエラーが発生しました。
エラーメッセージは読みましたか?どの行でエラーになっているかも出力されていると思います。
読んでも分からないのであれば、少しずつコードを追加していく等をして、
どこでエラーになっているのかを自分で見つけてください。
エラーの原因はただの文法ミスです。
余計なお世話ですが、これくらいは自分で見つけられるようにならないとこれからも大変だと思いますよ。
この回答への補足
すいません。
本件は元テーブル側に原因がありました。
お騒がせいたしました。
また、もう一つご教授願いたいのですが、
トリガのupdate条件は、
マテリアライズド・ビューの更新を見ることはできないのでしょうか?
本文を引用しますと、
after update of CHANGENAME on MV_ORACLE_MV_TEST
の「MV_ORACLE_MV_TEST」
がマテリアライズド・ビューであり、
元テーブルの変更→マテリアライズド・ビューの更新の発生した際に、
マテリアライズド・ビュー内の当該レコードを別テーブルに保管しようとしたのですが、
更新ができませんでした
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle sql(oracle)で質問です。 テーブルAのカラム名、日付(yyyymmdd)の値を テーブルB 2 2023/01/06 10:31
- MySQL テーブル作成時のカラムについて 2 2022/08/27 21:48
- YouTube YouTubeの歌ってみたのMVについて 1 2023/02/26 21:08
- 物理学 これについて教えていただきたいです。 Ft=mv‘-mvを使うんですか? 説明を添えて教えていただき 2 2023/04/05 07:07
- 中国語 阿肆の热爱105度的你というMV?の動画なんですがこの動画に写っている映像はMVのですか?それともド 1 2023/02/08 17:08
- 洋楽 初めまして 1、2年ほど前に聞いた洋楽でMVしか覚えていないのですが、わかる方いらっしゃるでしょうか 1 2022/03/22 20:45
- 物理学 物理この問題教えてください バネ振り子のエネルギー保存則で、 おもりを離すとその後、自然長の位置を中 2 2023/01/23 00:23
- Oracle Oracleですがsqlで質問です。 サブクエリ内で番号というカラムで昇順の1レコード目を取得したい 3 2023/05/22 10:02
- Excel(エクセル) EXCELの外部データ取得ができない 1 2023/03/23 09:03
- ロック・パンク・メタル 50代の男性で今の息子や娘が聴くような新しいロックンロールや洋楽やボカロやテクノポップをユーチューブ 3 2023/07/21 02:08
このQ&Aを見た人はこんなQ&Aも見ています
-
トリガって、自分自身のテーブルを操作することはできない?
MySQL
-
SQLローダーCSV取込で、囲み文字がデータ中に入っている場合について
Oracle
-
ORACLEのUPDATE処理
Oracle
-
-
4
異なるスキーマからデータを抽出するには?oracl、PL/SQL
Oracle
-
5
CSVファイルを読み込んでテーブルの更新
Oracle
-
6
既にテーブルが存在する場合のインポート
Oracle
-
7
シェルスクリプトでオラクルのエラーメッセージを取得するには
Oracle
-
8
NUMBER(N,M) としたときの、格納データサイズ(バイト)
Oracle
-
9
Statement ignored というエラー
Oracle
-
10
CASE文のエラーについて
Oracle
-
11
単一グループのグループ関数ではありません。
Oracle
-
12
SQL*LoaderでCSVから指定した列のみインポートしたい。
Oracle
-
13
SELECT INTOで一度に複数の変数へ代入をするにはどのようにすれがよいでしょうか?
PostgreSQL
-
14
トリガからプロシージャのコールについて
Oracle
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
特定のカラムが更新されたとき...
-
ROWNUMでUPDATEをしたいのです...
-
テーブルやカラムの物理名のネ...
-
sqlで質問です。 aテーブルとb...
-
あるテーブルだけをキャッシュ...
-
会社の飲み会の幹事になり、座...
-
「テーブルに座って……」という...
-
男性と2人で飲食店に行きテーブ...
-
PUTTYテーブルでエラーが...
-
オーダーの覚え方について
-
今度同じサークルだった女の子...
-
アクセス レコードセットを更...
-
下記、問題に対しての解答が以...
-
一つ前に戻るには…
-
会員が作成したデータを格納す...
-
ACCESS2010 SQL 結合キーにつ...
-
単純なselectが遅くなるのです...
-
複雑なSQL文について
-
マテリアライズドビューとスナ...
-
リサイクルビンのテーブル削除方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SQL、2つのテーブルで条件一致...
-
update文で改行を入れる
-
SQL*LoaderでCSVから指定した列...
-
sqlplusで表示が変なので、出力...
-
テーブル名をカラムとして取得...
-
SQL 複数テーブルのupdate
-
ROWNUMでUPDATEをしたいのです...
-
カラム位置変更
-
SQLでSUMなどの関数でデータが...
-
SQL(oracle)でご助言いただきた...
-
OracleのSQLで同テーブルのカラ...
-
SQLで違うテーブルの値を比較し...
-
特定のカラムが更新されたとき...
-
LONG型の先頭250バイトを Varch...
-
DBからタブ区切りのCSVデータを...
-
Viewのカラムの長さが不明?
-
distinct をexistsに変換する
-
oracle 複数列を1列にまとめる
-
件数とデータを同時に取得する...
-
数値をNUMBER型にするかCHAR型...
おすすめ情報