今日仕事で発生した障害を書き残しておきます。
こういうのもたまにはいいかな…
といっても仕事のことだから良くないか(笑)。
開発環境
○VisualStudio2005 SP2(C#)
○SQLServer2005 SP2
○Windows2003Server
☆現象☆
①SQLServerManagementStudioでデータのインポート・
エクスポートウィザードを利用してデータベースAから
データベースBへデータをコピーしました。
②このデータベースBに接続するシステムから
更新プログラム(UPDATE文)を実行するとエラーが
発生する。
発生したエラーのメッセージ
「データ型 varchar を numeric に変換中にエラーが発生しました。(8114)」
通常の環境では発生せず、上記の環境で発生しました。
データのインポート・エクスポートウィザードを利用すると
TableやViewのデータをコピーするけれどIndexやKeyなどは
コピーされません。その影響か、それともそれ以外?
原因が掴めず怪しい個所は掴めた感じで6時間以上格闘。
結局、更新プログラムで更新されるテーブルAにNumeric型の
カラムがあり、このテーブルに対してUPDATE文を実行する
ときにUPDATE文にISNULL関数が使われていると発生して
いるようでした。
実行しようとしているSQL①(抜粋)
UPDATE SAMPLE_TBL
SET NUMBER = @PARAM
WHERE ISNULL(NUMBER, '') <> ISNULL(@PARAM, '')
※NUMBERはNumeric型、@PARAMはパラメータ
@PARAMに「0」を設定してSQLを実行するとSAMPLE_TBLに
データがなくてもIndexが貼られていないとエラーが
発生します。
ということは、Indexのせい?
でも他のTableでUPDATE文を実行しても発生しない…なぜ?
ということで、以下のように改善しました。
するとIndexが貼られていなくてもエラーは
出ませんでした。
実行しようとしているSQL②(抜粋)
UPDATE SAMPLE_TBL
SET NUMBER = @PARAM
WHERE ISNULL(NUMBER, '0') <> ISNULL(@PARAM, '')
※NUMBERはNumeric型、@PARAMはパラメータ
このように見ると、ISNULL関数の使い方に問題がある?
ということでISNULL関数を調べました。
ISNULL(A,B)
A:比較対象
B:NULLの場合の置換値
EX)ISNULL(PARAM,0)⇒変数PARAMがNULLの場合、0に置き換えます。
これで上記のSQL①を考えると、NUMBERがNumeric型
なので、置き換えたときにNumericを空文字に変換
できないからではないかと思いました。
となると…NULLの扱い方の問題?
こうやっていろいろ原因を追求したけれど、
TableにIndexを貼ると現象が出なくなるので、
それで問題は解決になりました。
ただ、上記の内容から言えば、PG開発にも問題があるし、
IndexとNumeric型の関係が気になるところで、
本当の原因と解決には至ってはいません…。
何か知っている人がいればご教授をお願いします。
こういうのもたまにはいいかな…
といっても仕事のことだから良くないか(笑)。
開発環境
○VisualStudio2005 SP2(C#)
○SQLServer2005 SP2
○Windows2003Server
☆現象☆
①SQLServerManagementStudioでデータのインポート・
エクスポートウィザードを利用してデータベースAから
データベースBへデータをコピーしました。
②このデータベースBに接続するシステムから
更新プログラム(UPDATE文)を実行するとエラーが
発生する。
発生したエラーのメッセージ
「データ型 varchar を numeric に変換中にエラーが発生しました。(8114)」
通常の環境では発生せず、上記の環境で発生しました。
データのインポート・エクスポートウィザードを利用すると
TableやViewのデータをコピーするけれどIndexやKeyなどは
コピーされません。その影響か、それともそれ以外?
原因が掴めず怪しい個所は掴めた感じで6時間以上格闘。
結局、更新プログラムで更新されるテーブルAにNumeric型の
カラムがあり、このテーブルに対してUPDATE文を実行する
ときにUPDATE文にISNULL関数が使われていると発生して
いるようでした。
実行しようとしているSQL①(抜粋)
UPDATE SAMPLE_TBL
SET NUMBER = @PARAM
WHERE ISNULL(NUMBER, '') <> ISNULL(@PARAM, '')
※NUMBERはNumeric型、@PARAMはパラメータ
@PARAMに「0」を設定してSQLを実行するとSAMPLE_TBLに
データがなくてもIndexが貼られていないとエラーが
発生します。
ということは、Indexのせい?
でも他のTableでUPDATE文を実行しても発生しない…なぜ?
ということで、以下のように改善しました。
するとIndexが貼られていなくてもエラーは
出ませんでした。
実行しようとしているSQL②(抜粋)
UPDATE SAMPLE_TBL
SET NUMBER = @PARAM
WHERE ISNULL(NUMBER, '0') <> ISNULL(@PARAM, '')
※NUMBERはNumeric型、@PARAMはパラメータ
このように見ると、ISNULL関数の使い方に問題がある?
ということでISNULL関数を調べました。
ISNULL(A,B)
A:比較対象
B:NULLの場合の置換値
EX)ISNULL(PARAM,0)⇒変数PARAMがNULLの場合、0に置き換えます。
これで上記のSQL①を考えると、NUMBERがNumeric型
なので、置き換えたときにNumericを空文字に変換
できないからではないかと思いました。
となると…NULLの扱い方の問題?
こうやっていろいろ原因を追求したけれど、
TableにIndexを貼ると現象が出なくなるので、
それで問題は解決になりました。
ただ、上記の内容から言えば、PG開発にも問題があるし、
IndexとNumeric型の関係が気になるところで、
本当の原因と解決には至ってはいません…。
何か知っている人がいればご教授をお願いします。