- PR -

SQLServer トリガを仕掛けたところテーブル更新ができない

投稿者投稿内容
ハチャ
会議室デビュー日: 2007/10/01
投稿数: 11
投稿日時: 2007-11-09 16:25
返信ありがとうございます。

TableAはいっせいに更新される場合もあるはずです。
と言うことは…

いっせいに更新されたときは
同じコードが複数あったときにエラーということでしょうか?
ちなみにTableBはNEWIDでキーを割り振っています。

避ける方法はあるのでしょうか??
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2007-11-09 17:08
引用:

同じコードが複数あったときにエラーということでしょうか?



TableA の更新された行に同じコードがなくても、直積を求めたら結合結果として同じコードができあがっちゃうでしょ?

引用:

避ける方法はあるのでしょうか??



SQL Server では行トリガを使用することはできません。inserted テーブル、deleted テーブルには複数行格納されているという前提で上手に結合させるか、もしくはカーソルループを使って、inserted, deleted から 1行ずつ取り出して処理するか。

書き忘れ。newid() をセットしようとしている TableB の先頭列がプライマリキーなら一意制約違反は発生しないから、原因は他かな。まあ、トリガーの作りが全体的に悪いので時間をかけて見直したら。


[ メッセージ編集済み 編集者: 未記入 編集日時 2007-11-09 17:18 ]
ハチャ
会議室デビュー日: 2007/10/01
投稿数: 11
投稿日時: 2007-11-09 21:50
返信ありがとうございます。

超初心者なものでソースをひどいと言われましても
ただただお恥ずかしい限りです。。^^;

申し訳ありません、具体的にどのように書けばよろしいのでしょうか?
まだ、初めて数ヶ月なもので見当がつきません。。

本当に申し訳ありませんがよろしくお願いします。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-10 19:00
そもそもその処理をトリガで作成しないといけないものなのかを検討すべきだと思いますが。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-10 19:01
ともあれエラーの内容がわからないと何も確定できないのでエラーの内容を教えてください。
主キー重複だったんですか?

[ メッセージ編集済み 編集者: Anthyhime 編集日時 2007-11-10 19:02 ]
ハチャ
会議室デビュー日: 2007/10/01
投稿数: 11
投稿日時: 2007-11-12 14:28
返信ありがとうございます。

今、PG(私が作ったのではないのですが…)見てるのですが
SQLでTableAにsqlCmd.ExecuteNonQuery()でINSERTにいっているときに落ちていました。
return値は2です。
確かにトリガを外すと流れるようです。
また、失敗後にそのSQLをSQLServerから直接流すと
普通にトリガも起動してINSERTします。

いったい原因は何でしょう。。。
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2007-11-12 15:31
引用:

SQLでTableAにsqlCmd.ExecuteNonQuery()でINSERTにいっているときに落ちていました。
return値は2です。


 ExecuteNonQueryのreturn(戻り値)は、処理された件数即ち『INSERTで2件データを
書き込みました。』って事ですね。
2件書き込むのは処理的に問題ないんですか?

引用:

また、失敗後にそのSQLをSQLServerから直接流すと
普通にトリガも起動してINSERTします。


 本当に全く同じSQLですか?
プログラム中でフラグの値が変わってたりしませんか?

インプット・アウトプットのテーブル構造も載せた方がよろしいかと。
(ユニークキー云々も含めて)
上総
大ベテラン
会議室デビュー日: 2006/06/22
投稿数: 107
投稿日時: 2007-11-12 16:46
連投ですみません、プログラムで気になった点があったもので。

・DELETED_INS_FLAG・INSERTED_INS_FLAGが数値型であるにも関わらず、コード内では
 文字列型と比較。

・変数の初期化が行われていない。

・変数の初期化が行われていない事と、INSERT・DELETEでそれぞれの対象件数を
 抽出していない(見ていない)為、IF NOT EXISTSでのフラグ設定で誤ったフラグが
 設定される恐れあり。

 TABLE_Bに何もデータが存在しない場合に、TABLE_Aにデータを追加した場合、
 TABLE_Bに該当データが無い為、INSERTED_INS_FLAGがオンになる。
 が、DELETEDの件数を見ていない為、変数の初期値でTABLE_Bを検索し、これ又
 データが存在しない為、DELETED_INS_FLAGがオンになる。

 逆のパターンでも同様です。

・未記入さん(2007-11-09 16:10の書き込み)が指摘されてた、FROM句での複数
 テーブル指定([Inserted],[Deleted])

 正直この箇所は本当に『何がしたいのか判りません』、INSERT・DELETEがそれぞれ
 一件であれば問題は発生しません。(SQL上は無駄が発生しますが。)
 INSERT・DELETEがそれぞれ複数件であれば、INSERT件数×DELETE件数文のデータが
 TABLE_Bに作成されます。
 しかもデータ追加ではそれぞれの何れかのみというつくり。
 (カラム指定でDELETEDからが2箇所・INSERTからが1箇所で、複数テーブルを指定する
  意味が全くといっていいほどありません)

 カウントや合計値を求める集計処理を行った際は、面白いデータが出来る事
 請け合いです。

 未記入さん(2007-11-09 17:08の書き込み)が指摘されてるように、カーソルを
 使用して一件一件処理を行うのが無難です。

・『失敗後にそのSQLをSQLServerから直接流すと普通にトリガも起動してINSERT
 します。』・・・・sqlCmd側でトランザクションの管理をされてますか?

悪い事は言いません、作り直してください。

スキルアップ/キャリアアップ(JOB@IT)