🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

Q&A

1回答

5261閲覧

SQL Server 2008 から 2012 変更でのRAISERROR文の修正について

ponpopo

総合スコア8

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Transact-SQL

Transact-SQLはSybase ASEとMIcrosoft SQLサーバで対応されているSQLの機能拡張版です。

0グッド

0クリップ

投稿2019/10/26 00:58

編集2019/10/28 02:11

前提・実現したいこと

SQL Server 2008 から 2012 変更でのトリガーの修正

2008から2012へ変更の為、互換性レベルを上げてアタッチしました。
読み込みや一部のテーブルの更新には問題がなかったのですが、いくつかのテーブルでINSERTとUPDATEのエラーが出てしまい
トリガーのRAISERROR文が原因である事が分かりました。

最初に発生していたエラー

メッセージ 102、レベル 15、状態 1、プロシージャ SEIZOU_更新トリガ、行 8
'44444' 付近に不適切な構文があります。
メッセージ 102、レベル 15、状態 1、プロシージャ SEIZOU_更新トリガ、行 17
'44444' 付近に不適切な構文があります。

トリガーではNULLのチェックをしています(「該当のソースコード」参照)
また、テーブル構造は下記のようになっています。

SID int 主キー
登録日 datetime 主キー
枝番 int NULL許容する
場所 varchar(5) NULL許容する

アドバイス頂きたいのは下記です
・主キー、NULL許容しない項目の場合、トリガーで処理をする必要がないと言えるでしょうか?
(このようなチェックだけのトリガー自体を消す方が早いように思える為)

・上記のような項目以外で、わざと値のチェックとエラーを出すような場合
「試したこと」に書いたような文で動作はしますが
旧文とエラーNoの扱いが違う為、’44444’のようなエラー番号を出したい場合、全く同じことができていないように思えます。
もう少し良い書き方はあるでしょうか?

該当のソースコード

SQL

1ALTER TRIGGER [dbo].[SEIZOU_更新トリガ] ON [dbo].[SEIZOU] FOR UPDATE AS 2/* 3 * 'SID' に Null 値を許可しない 4 */ 5IF (SELECT Count(*) FROM inserted WHERE SID IS NULL) > 0 6 BEGIN 7 RAISERROR 44444 '''SID'' フィールドでは Null 値は使えません。' ←エラー箇所 8 ROLLBACK TRANSACTION 9 END 10ELSE 11/* 12 * '登録日' に Null 値を許可しない 13 */ 14

試したこと

一先ず、下記のように変更してみました。

SQL

1IF (SELECT Count(*) FROM inserted WHERE SID IS NULL) > 0 2 BEGIN 3 RAISERROR 44444 '''SID'' フィールドでは Null 値は使えません。' 4 ROLLBACK TRANSACTION 5 END 6```7```SQL 8IF (SELECT Count(*) FROM inserted WHERE SID IS NULL) > 0 9 BEGIN 10 RAISERROR('44444 ''SID'' フィールドでは Null 値は使えません。',16,1); 11 ROLLBACK TRANSACTION 12 END

上記の書き換えで、NULL値以外の更新で「'44444' 付近に不適切な構文」のエラーは出なくなりました。
改めてNULL更新の確認をすると下記のエラーが表示されます。

メッセージ 515、レベル 16、状態 2、行 3
テーブル '生産管理システム.dbo.SEIZOU' の列 'SID' に値 NULL を挿入できません。この列では NULL 値が許可されていません。UPDATE は失敗します。

※トリガーの判定に行かない

##追記:2019/10/28
回答から:
RAISERROR(Transact-SQL)
RAISERROR issue since migration to SQL Server 2012

(※ソースコードの変更点のコードを見やすく分けました)RAISERROR文は
RAISERROR( msg_str, severity ,state) の形が例文にもあるので引数の順番は大丈夫だと思うのですが
Serverityの値に細かい決まりがあった事と、例文ではTRY~CATCHの中で使っているようですので原文をどう書き直せばいいか考えてみます。

また、sys.messages カタログビューに一度登録して、RAISERROR ( msg_id ,severity ,state}のようにする方法があるようですが
こっちの方が意図した方法のような気がしました。こっちの方が書き直すのが難しそうですが…

THROW文は特にTRY~CATCHを使わなければいけないようですので、書いたことがないですが余裕ができたときに試せればと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

試してないですが、これとかこれ読む限りは変更後のRAISERRORの引数の順番がそもそもおかしい気が。
あとTHROWを試してみたらどうでしょうか。

投稿2019/10/26 05:18

gentaro

総合スコア8947

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ponpopo

2019/10/28 02:18

ご回答ありがとうございます。追記しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問