質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

DB2

DB2(IBM Database2)は、IBMのリレーショナルデータベース管理システム製品です。 UNIXとWindows、IBM社のメインフレームOS用が用意されており、 幅広いプラットフォームに対応しています。

Q&A

解決済

3回答

5026閲覧

DB2のホスト変数を使用したSQLで不規則に演算子の比較不能エラーが発生します。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

DB2

DB2(IBM Database2)は、IBMのリレーショナルデータベース管理システム製品です。 UNIXとWindows、IBM社のメインフレームOS用が用意されており、 幅広いプラットフォームに対応しています。

0グッド

1クリップ

投稿2016/09/09 08:52

編集2016/11/07 00:59

###前提・実現したいこと
C#でOracleを使用していたプログラムをDB2でも使用できるようにしようとしています。
修正範囲を出来るだけ少なくするために、SQLの変更は出来るだけ行わずにしたいと思っています。

エラーの回避方法が分かればいいのですが、エラーの発生条件や、プログラム側での効率的な対処方法など何か分かることがありましたら、アドバイスをお願いします。

###発生している問題・エラーメッセージ
DB2からホスト変数を使用した同じ内容のSQLを連続で使用した時に以下のエラーが発生します。

0ERROR [42818] [IBM][DB2/NT64] SQL0401N 演算 "=" のオペランドのデータ・タイプが非互換または比較不能です。

###該当のソースコード

C#

1using IBM.Data.DB2; 2 3namespace DB2Sample 4{ 5 public partial class Form1 : Form 6 { 7 DB2Connection _conn = null; 8 9 public Form1() 10 { 11 InitializeComponent(); 12 } 13 14 // 接続 15 private void button1_Click(object sender, EventArgs e) 16 { 17 try 18 { 19 /// 接続 20 string[] connParam = new string[5]; 21 //[0] alias 22 //[1] server 23 //[2] portN 24 //[3] userId 25 //[4] pass 26 connParam[0] = "mydb2"; 27 connParam[1] = "localhost"; 28 connParam[2] = "50000"; 29 connParam[3] = "hogehoge"; 30 connParam[4] = "********"; 31 32 _conn = ConnectDb(connParam); 33 } 34 catch (Exception ex) 35 { 36 MessageBox.Show(ex.Message); 37 } 38 } 39 40 // 切断 41 private void button2_Click(object sender, EventArgs e) 42 { 43 try 44 { 45 _conn.Close(); 46 _conn.Dispose(); 47 } 48 catch (Exception ex) 49 { 50 MessageBox.Show(ex.Message); 51 } 52 } 53 54 // 実行 55 private void button3_Click(object sender, EventArgs e) 56 { 57 try 58 { 59 DB2Command cmd = null; 60 61 DB2DataAdapter adp = new DB2DataAdapter(); 62 cmd = _conn.CreateCommand(); 63 cmd.CommandText = " SELECT * " 64 + " FROM TABLE " 65 + " WHERE KEY = :KEY "; 66 //+ " WHERE KEY = CAST(:KEY AS VARCHAR(100))"; 67 68 adp.SelectCommand = new DB2Command(cmd.CommandText, _conn); 69 70 DB2Parameter param = new DB2Parameter(); 71 param.ParameterName = "KEY"; 72 param.Value = "KEY001"; 73 param.Direction = ParameterDirection.Input; 74 param.DB2Type = DB2Type.VarChar; 75 param.DbType = DbType.String; 76 param.Precision = 255; 77 param.Size = 255; 78 79 adp.SelectCommand.Parameters.Add(param); 80 81 DataTable table = new DataTable(); 82 adp.Fill(table); 83 84 cmd.Dispose(); 85 adp.Dispose(); 86 87 } 88 catch (Exception ex) 89 { 90 MessageBox.Show(ex.Message); 91 } 92 } 93 94--- 以下IBMのサンプルコード 95 // Helper method: This method establishes a connection to a database 96 public static DB2Connection ConnectDb(String[] argv) 97 { 98 String server = ""; 99 String alias = ""; 100 String userId = ""; 101 String password = ""; 102 Int32 portNumber = -1; 103 String connectString; 104 105 if (argv.Length > 5 || 106 (argv.Length == 1 && 107 (String.Compare(argv[0], "?") == 0 || 108 String.Compare(argv[0], "-?") == 0 || 109 String.Compare(argv[0], "/?") == 0 || 110 String.Compare(argv[0], "-h", true) == 0 || 111 String.Compare(argv[0], "/h", true) == 0 || 112 String.Compare(argv[0], "-help", true) == 0 || 113 String.Compare(argv[0], "/help", true) == 0))) 114 { 115 throw new Exception( 116 "Usage: prog_name [dbAlias] [userId passwd] \n" + 117 " prog_name [dbAlias] server portNum userId passwd"); 118 } 119 switch (argv.Length) 120 { 121 case 0: // Use all defaults 122 alias = "sample"; 123 userId = ""; 124 password = ""; 125 break; 126 case 1: // dbAlias specified 127 alias = argv[0]; 128 userId = ""; 129 password = ""; 130 break; 131 case 2: // userId & passwd specified 132 alias = "sample"; 133 userId = argv[0]; 134 password = argv[1]; 135 break; 136 case 3: // dbAlias, userId & passwd specified 137 alias = argv[0]; 138 userId = argv[1]; 139 password = argv[2]; 140 break; 141 case 4: // use default dbAlias 142 alias = "sample"; 143 server = argv[0]; 144 portNumber = Convert.ToInt32(argv[1]); 145 userId = argv[2]; 146 password = argv[3]; 147 break; 148 case 5: // everything specified 149 alias = argv[0]; 150 server = argv[1]; 151 portNumber = Convert.ToInt32(argv[2]); 152 userId = argv[3]; 153 password = argv[4]; 154 break; 155 } 156 157 if (portNumber == -1) 158 { 159 connectString = "Database=" + alias; 160 } 161 else 162 { 163 connectString = "Server=" + server + ":" + portNumber + 164 ";Database=" + alias; 165 } 166 167 if (userId != "") 168 { 169 connectString += ";UID=" + userId + ";PWD=" + password; 170 } 171 connectString += ";HostVarParameters=True;"; 172 173 DB2Connection conn = new DB2Connection(connectString); 174 conn.Open(); 175 Console.WriteLine(" Connected to the " + alias + " database"); 176 return conn; 177 178 } // ConnectDb 179 180 } 181} 182

###試したこと
接続し連続でSQLを発行した場合に発生しました。
接続→実行→切断→接続→実行としてもエラーが発生しました。
コメントしてありますがCAST( )を使用すれば、問題のエラーは発生しなくなります。
ただ、その場合全てのSQL文を修正する必要があるため避けたいです。

###補足情報(言語/FW/ツール等のバージョンなど)
DB2 express-c v11.1.0.1527 64bit
C#
Windows server 2012R2

DB2をOracle互換モードで設定しています
DB2_DEFERRED_PREPARE_SEMANTICS=YES
DB2_COMPATIBILITY_VECTOR=ORA

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

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

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

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

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

guest

回答3

0

ベストアンサー

これをYESにしていたのが原因だったぽいです。
DB2_DEFERRED_PREPARE_SEMANTICS=NO

投稿2017/05/18 04:03

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

すみません。
環境がなく検証できないので、以下は確実な回答ではありません。
(推測ばかりです)
が、気になるところをいくつか。

DB2からホスト変数を使用した同じ内容のSQLを連続で使用した時に以下のエラーが発生します。

Visual Studio でステップ実行し、最初の実行時と2回目の実行時で何が違うのか見てみるとよいのではないでしょうか。
特にDB2Parameterのプロパティが怪しい気がします。

csharp

1param.Value = "KEY001"; 2param.Direction = ParameterDirection.Input; 3param.DB2Type = DB2Type.VarChar; 4param.DbType = DbType.String; 5param.Precision = 255; 6param.Size = 255;

param.DbType = DbType.String;は不要な気がします。直前でDB2Typeを設定していますし。
param.Precision = 255;は不要だと思います。Precisionは数値型のときに指定するものです。
param.Value = "KEY001";で値をセットするのは、DB2TypeSizeの設定が終わった後の方が良いように思えます。

csharp

1cmd.CommandText = " SELECT * " 2 + " FROM TABLE " 3 + " WHERE KEY = :KEY "; 4 //+ " WHERE KEY = CAST(:KEY AS VARCHAR(100))";

このTABLEKEY列の型と長さはどうなっているでしょうか?
VARCHAR(100)でしょうか。

投稿2016/09/17 11:24

alg

総合スコア2019

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

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

退会済みユーザー

退会済みユーザー

2016/09/20 00:34

ご指摘ありがとうございます >param.DbType = DbType.String;は不要な気がします。直前でDB2Typeを設定していますし。 >param.Precision = 255;は不要だと思います。Precisionは数値型のときに指定するものです。 DB2Parameterのプロパティは、明示的に型や桁数を指定すればいいのではと考え、追加して行った結果です。 algさんの予想通り実際には不要です。 最低限のプロパティであれば以下の3つを設定すれば動作致します。 param.ParameterName = "KEY"; param.Value = "KEY001"; param.Direction = ParameterDirection.Input; >param.Value = "KEY001";で値をセットするのは、DB2TypeやSizeの設定が終わった後の方が良いように思えます。 Valueのセットを最後に持ってきて試しましたが、動作は変わりませんでした。 DB2Parameterを正常時と異常時で比較してみましたが、違いを発見することはできませんでした。 >このTABLEのKEY列の型と長さはどうなっているでしょうか? >VARCHAR(100)でしょうか。 作成した項目のは「 KEY VARCHAR(80) not null 」です。 CASTで指定した型は、テーブルの型と一致していなくてもValueで渡す文字数より大きければ問題なさそうでした。 DB2だけで考えれば、桁数を指定しないVARCHARやVARCHAR2に変更してもOKでした。Oracleで桁数なしのCASTでエラーが出たため、とりあえず余裕のある桁数を指定してあります。
guest

0

SQL0401N
要するに比較するデータの型が違うということです。(例えば数値と文字では比較できない)
また、DB2はデータの暗黙的キャストをサポートしています。
param.Value = "KEY001";
とありますが、実データは「1」みたいにそのまま数値に変換できるような内容が渡っていたりしませんか?

投稿2016/09/12 01:46

ishi9

総合スコア1294

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

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

退会済みユーザー

退会済みユーザー

2016/09/12 02:37

実データとしては、テストした環境では「ABC」の様な英字のみを渡しています。 渡している値は、記載したソースの様に実行する度に変更はしていません。 型変換のエラーであれば、毎回エラーとなっても良さそうに思うのですが、正常に実行される時もあるため、原因がよくわからなくなっています。
ishi9

2016/09/12 02:45 編集

試しに param.Value = "KEY001"; のところを param.Value = "'" + "KEY001" + "'"; // 必ずシングルクォーテーションで囲むようにする としてみたらどうでしょうか?
退会済みユーザー

退会済みユーザー

2016/09/15 07:20

それだと"'KEY001'"というシングルクォーテーションを含んだ文字列で検索することになってしまいます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問