C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[12]: ORACLEへのバイナリデータの書き込みについて


(過去ログ 84 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■49600 / inTopicNo.1)  ORACLEへのバイナリデータの書き込みについて
  
□投稿者/ 裕猫 (101回)-(2010/05/11(Tue) 08:44:12)

分類:[C#] 

まいどお世話になります。
開発環境
 OS:WindowsXP SP3
 言語:VisualStudio2008Pro C#
 データベース:ORACLE 10g
 ODAで接続しています。

  以前にバイナリデータのORACLEへの書き込みでお世話になりました裕猫ですが、その後(かなりたちますが)いまだに書き込めないでおります。
        private void button2_Click(object sender, EventArgs e)
        {
            byte[] bt = new byte[38];
            byte[] at = Encoding.GetEncoding("shift_jis").GetBytes(textBox1.Text);
            byte[] ct = Encoding.GetEncoding("shift_jis").GetBytes(VBStrings.LeftB(textBox2.Text.PadRight(30), 30));
            int value = Convert.ToInt32(textBox3.Text);
            byte[] bytes = BitConverter.GetBytes(value);
            byte[] et = new byte[4];
            for (int i = 0; i < 4; i++) { et[i] = bytes[3 - i]; }
            using (OracleConnection con = new OracleConnection())
            {
                con.ConnectionString = "User ID=****;Password=ASC;Data Source=DB01";
                try
                {
                    con.Open();
                }
                catch
                {
                    MessageBox.Show("データベースの接続に失敗しました。");
                    return;
                }
                OracleCommand cmd = con.CreateCommand();
//                cmd.CommandText = "insert into GN30X(コード,適用,番号) values('" + at + "', '" + ct + "', " + et + ")";
                cmd.CommandText = "insert into GN30X(コード,適用,番号) values(" + at + ", " + ct + ", " + et + ")";
                try
                {
                    int i = cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }
                MessageBox.Show("終了");
            }
        }
で実行するのですが、どうやっても書き込みできません。INSERT文の書き方が悪いのか、VALUESの中が悪いのはわかりますが、どう書けばいいのか調べてみましたが解答にたどりつきませんでした。アドバイスよろしくお願いいたします。

引用返信 編集キー/
■49609 / inTopicNo.2)  Re[1]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 魔界の仮面弁士 (1643回)-(2010/05/11(Tue) 10:16:55)
2010/05/11(Tue) 10:35:35 編集(投稿者)

No49600 (裕猫 さん) に返信
>  ODAで接続しています。
ODA というのは何の事でしょうか?
System.Data.OracleClient.OracleDataAdapter の事でしょうか。

# それとも、ODP.NET (Oracle Data Provider for .NET) の誤記とか
# ADO (ActiveX Data Objects) の誤記とか?



>   以前にバイナリデータのORACLEへの書き込みでお世話になりました裕猫ですが、
覚えていないので検索してみました。どれでしょうか?

No29873 , 2008/12/16 , [文字のバイト数での取り出し方法について]
文字のバイト数での取り出し方法について
http://bbs.wankuma.com/index.cgi?mode=al2&namber=29873&KLOG=53

No42177 , 2009/10/09 , [int型数値のバイナリ変換方法を教えてください。]
http://bbs.wankuma.com/index.cgi?mode=al2&namber=42177&KLOG=72


> private void button2_Click(object sender, EventArgs e)
> {
>  byte[] bt = new byte[38];
変数 bt が使われていないように見えます。これは何のための物でしょうか?

>  byte[] at = Encoding.GetEncoding("shift_jis").GetBytes(textBox1.Text);
これは良いとして…。

>  byte[] ct = Encoding.GetEncoding("shift_jis").GetBytes(VBStrings.LeftB(textBox2.Text.PadRight(30), 30));
VBStrings.LeftB というのは、何のことでしょうか?

Microsoft.VisualBasic.Strings.Left とも違うようですし、もしかして
http://jeanne.wankuma.com/tips/csharp/string/leftb.html
のことでしょうか? だとしたら、2バイト文字の分断は考慮しなくてよいのでしょうか?

たとえば、textBox2 の中身が
 "int型数値のバイナリ変換方法を教えてください。"
だった場合、それを上記の構文で30バイトに区切ろうとすると、「教」の文字が
分断されることになります。その場合はどのようなデータが必要ですか?

 (案1) "int型数値のバイナリ変換方法を"  …29バイトに収める
 (案2) "int型数値のバイナリ変換方法を教" …31バイトに拡張
 (案3) "int型数値のバイナリ変換方法を*"  …30バイト=29バイト+何か適当な1バイト文字(空白、?、*など)
 (案4) 事前に TextBox の内容をチェックして、そのようなデータが渡されないようにする。


>  int value = Convert.ToInt32(textBox3.Text);
>  byte[] bytes = BitConverter.GetBytes(value);
>  byte[] et = new byte[4];
>  for (int i = 0; i < 4; i++) { et[i] = bytes[3 - i]; }
ループ処理する以外に、
 byte[] et = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
あるいは
 byte[] et = BitConverter.GetBytes(value).Reverse().ToArray();
といった手法もありますね。


>  OracleCommand cmd = con.CreateCommand();
> // cmd.CommandText = "insert into GN30X(コード,適用,番号) values('" + at + "', '" + ct + "', " + et + ")";
>  cmd.CommandText = "insert into GN30X(コード,適用,番号) values(" + at + ", " + ct + ", " + et + ")";
この CommandText に、どのような文字列(SQL文)が格納されているか、確認されましたか?

byte[] をそのまま string と連結しても意味が無いですよ。
(Byte配列を String と連結する場合、VB ならエラーになってくれるけれど、C# だと通ってしまうんですね…)

それと、データは SQL 中に埋め込むのでは無く、cmd.Parameters を使って
パラメーター化するようにしましょう。その方が問題が少ないです。


で、幾つか逆質問。

* GN30X のテーブル定義はどのようになっているのでしょうか?
 それぞれの列(コード,適用,番号)のデータ型を公開してください。

* それぞれの TextBox の内容と、そこから期待される GN30X への格納結果を
 具体例として提示して欲しいです。
引用返信 編集キー/
■49613 / inTopicNo.3)  Re[2]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 裕猫 (102回)-(2010/05/11(Tue) 11:39:34)
No49609 (魔界の仮面弁士 さん) に返信
返信ありがとうございます。
> ODA というのは何の事でしょうか?
> System.Data.OracleClient.OracleDataAdapter の事でしょうか。
System.Data.OracleClient.OracleDataAdapterを使用していたのでODAとかいてしまいました。ODP.NETでした。似たような名前がたくさんあるので混同してしまいました。すみません。
>>  以前にバイナリデータのORACLEへの書き込みでお世話になりました裕猫ですが、
> 覚えていないので検索してみました。どれでしょうか?
すみません私もよく覚えてないです。
>> byte[] bt = new byte[38];
> 変数 bt が使われていないように見えます。これは何のための物でしょうか?
GN30のデータは38byteの長さです。テスト時に38byteのバイナリデータを作って渡せるのかと試したときに作ったもので、ここでは使っていません。
>> byte[] at = Encoding.GetEncoding("shift_jis").GetBytes(textBox1.Text);
> これは良いとして…。
>
>> byte[] ct = Encoding.GetEncoding("shift_jis").GetBytes(VBStrings.LeftB(textBox2.Text.PadRight(30), 30));
> VBStrings.LeftB というのは、何のことでしょうか?
> Microsoft.VisualBasic.Strings.Left とも違うようですし、もしかして
> http://jeanne.wankuma.com/tips/csharp/string/leftb.html
> のことでしょうか?
そうです。
>だとしたら、2バイト文字の分断は考慮しなくてよいのでしょうか?
日本語を記録するところで、トータル30バイト以内になるようにしてもらっていますのでとりあえず、区切りは考慮しなくてよいです。
>> int value = Convert.ToInt32(textBox3.Text);
>> byte[] bytes = BitConverter.GetBytes(value);
>> byte[] et = new byte[4];
>> for (int i = 0; i < 4; i++) { et[i] = bytes[3 - i]; }
> ループ処理する以外に、
>  byte[] et = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
> あるいは
>  byte[] et = BitConverter.GetBytes(value).Reverse().ToArray();
> といった手法もありますね。
参考にさせていただきます。
>> OracleCommand cmd = con.CreateCommand();
>>// cmd.CommandText = "insert into GN30X(コード,適用,番号) values('" + at + "', '" + ct + "', " + et + ")";
>> cmd.CommandText = "insert into GN30X(コード,適用,番号) values(" + at + ", " + ct + ", " + et + ")";
> この CommandText に、どのような文字列(SQL文)が格納されているか、確認されましたか?
>
> byte[] をそのまま string と連結しても意味が無いですよ。
> (Byte配列を String と連結する場合、VB ならエラーになってくれるけれど、C# だと通ってしまうんですね…)
>
> それと、データは SQL 中に埋め込むのでは無く、cmd.Parameters を使って
> パラメーター化するようにしましょう。その方が問題が少ないです。
はいわかりました。そのように直してみます。
> で、幾つか逆質問。
>
> * GN30X のテーブル定義はどのようになっているのでしょうか?
>  それぞれの列(コード,適用,番号)のデータ型を公開してください。
GN30の構造は 4byteの英数字 30byteの日本語 4byteの整数の合計38byteのデータが ORACLEの中に4byte+30byte+4byteのバイナリデータで記録されています。 4byteの整数はC#int型とbyteの並びが逆になっているのでその処理が必要です。

> * それぞれの TextBox の内容と、そこから期待される GN30X への格納結果を
>  具体例として提示して欲しいです。
textbox1 = "AC01"
textbox2 = "銀行残高"
textbox3 = "123456"
textbox1,2を文字、textbox3をint型のバイナリデータにして記録したいのです。
以上の説明でわかりますでしょうか?
引用返信 編集キー/
■49621 / inTopicNo.4)  Re[3]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 魔界の仮面弁士 (1644回)-(2010/05/11(Tue) 14:40:10)
No49613 (裕猫 さん) に返信
> System.Data.OracleClient.OracleDataAdapterを使用していたのでODAとかいてしまいました。
No29031 でも ODA と表記されていたようですが、一般的な略称ではないように思います。

> ODP.NETでした。似たような名前がたくさんあるので混同してしまいました。すみません。
すみません。ODP.NET の名を出してしまって、かえって混乱させてしまったのかも知れません。

裕猫さんが、もしも
 アセンブリ:System.Data.OracleClient.dll
  名前空間:System.Data.OracleClient
の事を説明されているのだとすれば、それは ODP.NET ではありません。

ODP.NET (Oracle Data Provider for .NET) というのは、
 アセンブリ:Oracle.DataAccesss.dll
  名前空間:Oracle.DataAccess.Client
にあたります。

いずれも ADO.NET 準拠の Oracle 用プロバイダという点では同じですが、別のライブラリです。
(前者は Microsoft 製、後者は Oracle 製)


なお OracleClient は .NET Framework 2.0 より登場したライブラリですが、
.NET Framework 4 では非推奨(下位互換性のために Obsolete 扱い)になっており、
将来のバージョンでは削除される可能性があります。
http://msdn.microsoft.com/ja-jp/library/77d8yct7.aspx

今後、Visual Studio 2010 以降のバージョンへの移行も検討しているのであれば、
ODP.NET や Connect for ADO.NET 等への切り替えも検討しておいた方が良いかも知れません。


>>> 以前にバイナリデータのORACLEへの書き込みでお世話になりました裕猫ですが、
>>> その後(かなりたちますが)いまだに書き込めないでおります。
>> 覚えていないので検索してみました。どれでしょうか?
> すみません私もよく覚えてないです。
失念されているなら仕方ないですね。
以前のスレッドも参考にしておきたいので、こちらで勝手に探す事にします。

ところで、当時の投稿先はココで間違いないですか? 投稿者名は同じですよね?


>>それと、データは SQL 中に埋め込むのでは無く、cmd.Parameters を使って
>>パラメーター化するようにしましょう。その方が問題が少ないです。
> はいわかりました。そのように直してみます。

イメージ的には、こうかな?
 cmd.CommandText = "INSERT INTO GN30X (コード,適用,番号) VALUES (:P1, :P2, :P3)";
 cmd.Parameters.Add("P1", OracleType…);
 cmd.Parameters.Add("P2", OracleType…);
 cmd.Parameters.Add("P3", OracleType…);
 cmd.Parameters["P1"].Value = 〜;
 cmd.Parameters["P2"].Value = 〜;
 cmd.Parameters["P3"].Value = 〜;
 cmd.ExecuteNonQuery();


>>* GN30X のテーブル定義はどのようになっているのでしょうか?
>> それぞれの列(コード,適用,番号)のデータ型を公開してください。
> GN30の構造は
GN30X ですよね、GN30 ではなく。


> 4byteの英数字 30byteの日本語 4byteの整数の合計38byteのデータが
> ORACLEの中に4byte+30byte+4byteのバイナリデータで記録されています。
繰り返しの質問になりますが、それぞれの「データ型」は何に設定されているのでしょうか?

No42179 で、ぽぴ王子さんが「その部分が明確になっていないので回答は難しいです。」と
書かれていますが、それと同じ理由による質問だと思ってください。

以前の質問にあった TEST_HI01(COL1, COL2, COL3) は、すべて RAW 型だったようですが、
http://bbs.wankuma.com/index.cgi?mode=al2&namber=42177&KLOG=72
今回の GN30X(コード,適用,番号) は、それぞれ何型なのでしょうか?


たとえば『4byteの英数字』を格納する場合、それが文字列として保持するならば、Oracle 側では
 VARCHAR2(4 CHAR)
 VARCHAR2(4 BYTE)
 NVARCHAR2(4)
 CHAR(4 CHAR)
 CHAR(4 BYTE)
 NCHAR(4)
などが使われるかと思います。しかし、今回は文字列ではなくバイナリなのですよね。

4バイトのバイナリを格納するのであれば、これらの文字列型に加えて、さらに
 NUMBER(10)
 RAW(4)
 BLOB
などのデータ型も候補に挙げる事ができます。あるいは、他の型なのかも知れませんが、
実際のところはどうなのでしょうか?


>>* それぞれの TextBox の内容と、そこから期待される GN30X への格納結果を
>> 具体例として提示して欲しいです。
> textbox1 = "AC01"
> textbox2 = "銀行残高"
> textbox3 = "123456"
> textbox1,2を文字、textbox3をint型のバイナリデータにして記録したいのです。
textBox1 の "AC01" が示す内容というのは、0xAC,0x01 の意味ではなく、
0x41,0x43,0x30,0x31 のデータとして保存されれば良いのですよね?

> 以上の説明でわかりますでしょうか?
これで TextBox の内容はわかりましたが…肝心の格納結果についての具体例が提示されていません。
期待する「格納後のバイナリデータの内容」は、具体的にはどういったものですか?
(int というのは C# の型であって、Oracle の型ではありませんよね)

要するに、上記のデータを正しく格納できていたとしたら、
 SELECT DUMP(コード, 1016), DUMP(適用, 1016), DUMP(番号, 1016) FROM GN30X
からは、どのようなデータが返されるようにしたいのでしょうか、という事です。

たとえば、[コード]列に 0x41,0x43,0x30,0x31 の 4 バイトを格納するにしても、
格納先の Oracle 側の型によって、複数のパターンが想定されます。たとえば:
 Typ=1 Len=4: 41,43,30,31
 Typ=23 Len=4: 41,43,30,31
 Typ=96 Len=4 CharacterSet=JA16SJIS: 41,43,30,31
 Typ=96 Len=4 CharacterSet=JA16SJISTILDE: 41,43,30,31
など。そして、そのそれぞれにおいて、記述すべき C# のコードも微妙に異なる事になります。
引用返信 編集キー/
■49628 / inTopicNo.5)  Re[4]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 裕猫 (103回)-(2010/05/11(Tue) 16:02:16)
No49621 (魔界の仮面弁士 さん) に返信
> ODP.NET (Oracle Data Provider for .NET) というのは、
>  アセンブリ:Oracle.DataAccesss.dll
>   名前空間:Oracle.DataAccess.Client
> にあたります。
こちらで間違いありません。
> ところで、当時の投稿先はココで間違いないですか? 投稿者名は同じですよね?
はい同じです
>
> イメージ的には、こうかな?
>  cmd.CommandText = "INSERT INTO GN30X (コード,適用,番号) VALUES (:P1, :P2, :P3)";
>  cmd.Parameters.Add("P1", OracleType…);
>  cmd.Parameters.Add("P2", OracleType…);
>  cmd.Parameters.Add("P3", OracleType…);
>  cmd.Parameters["P1"].Value = 〜;
>  cmd.Parameters["P2"].Value = 〜;
>  cmd.Parameters["P3"].Value = 〜;
>  cmd.ExecuteNonQuery();
>
> GN30X ですよね、GN30 ではなく。
そうです。すみません。オリジナルがGN30で、コピーしてGN30Xにして GN30Xでテストしていたので間違えました。
>
> > 4byteの英数字 30byteの日本語 4byteの整数の合計38byteのデータが
> > ORACLEの中に4byte+30byte+4byteのバイナリデータで記録されています。
> 繰り返しの質問になりますが、それぞれの「データ型」は何に設定されているのでしょうか?
> 以前の質問にあった TEST_HI01(COL1, COL2, COL3) は、すべて RAW 型だったようですが、
> 今回の GN30X(コード,適用,番号) は、それぞれ何型なのでしょうか?
全く同じで全てRAW型です。
> たとえば『4byteの英数字』を格納する場合、それが文字列として保持するならば、Oracle 側では
>  VARCHAR2(4 CHAR)
>  VARCHAR2(4 BYTE)
>  NVARCHAR2(4)
>  CHAR(4 CHAR)
>  CHAR(4 BYTE)
>  NCHAR(4)
> などが使われるかと思います。しかし、今回は文字列ではなくバイナリなのですよね。
そうしたいのですが現行システムによってRAW型にバイナリデータで記録されています。一気にシステムを変えることができないので作った順にプログラムをC#のものに変更していくため、型を変えることが出来ません。
> >>* それぞれの TextBox の内容と、そこから期待される GN30X への格納結果を
> >> 具体例として提示して欲しいです。
> 期待する「格納後のバイナリデータの内容」は、具体的にはどういったものですか?
> (int というのは C# の型であって、Oracle の型ではありませんよね)
>
> 要するに、上記のデータを正しく格納できていたとしたら、
>  SELECT DUMP(コード, 1016), DUMP(適用, 1016), DUMP(番号, 1016) FROM GN30X
> からは、どのようなデータが返されるようにしたいのでしょうか、という事です。
以下に実際のデータを1つ記します。
textbox1(コード) = "KR00" textbox2(適用) = "営業起動日" textbox3(番号) = "100511"
これをORACLE EnterpriseManagerコンソールからみた内容は
4B523030 89638BC68B4E93AE93FA2020202020202020202020202020202020202020 0001889F
(コード)  (適用)                             (番号)
これはDUMPリストと内容同一かな?わかりませんが、このようになっています。これでわかるでしょうか?
引用返信 編集キー/
■49633 / inTopicNo.6)  Re[5]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 魔界の仮面弁士 (1645回)-(2010/05/11(Tue) 16:47:54)
No49628 (裕猫 さん) に返信
> textbox1(コード) = "KR00" textbox2(適用) = "営業起動日" textbox3(番号) = "100511"
> これをORACLE EnterpriseManagerコンソールからみた内容は
> 4B523030 89638BC68B4E93AE93FA2020202020202020202020202020202020202020 0001889F
> (コード)  (適用)                             (番号)
> これはDUMPリストと内容同一かな?

DUMP(列名, 1016) ではなく、RAWTOHEX(列名) に相当しますね。

DUMP と違って型やサイズの情報は含まれていませんが、それぞれのデータ型が
RAW(4)/RAW(30)/RAW(4)だと教えていただいたので、生データだけでも大丈夫です。


で。バイナリへの変換手順については、最初に提示していただいた
Encoding や BitConverter のままで問題無いはずです。

// 元データ
string val1 = "KR00";
string val2 = "営業起動日".PadRight(30);
int val3 = 100511;

// バイナリ変換
byte[] コード = Encoding.ASCII.GetBytes(val1);
byte[] 適用 = new byte[30];
Array.Copy(Encoding.GetEncoding(932).GetBytes(val2), 適用, 30);
byte[] 番号 = BitConverter.GetBytes(IPAddress.NetworkToHostOrder(val3));

// 内容確認
string col1 = BitConverter.ToString(コード).Replace("-", "");
string col2 = BitConverter.ToString(適用).Replace("-", "");
string col3 = BitConverter.ToString(番号).Replace("-", "");


問題になるのは、Oracle への格納部分ですね。
このパターンであれば、cmd.Parameters には、OracleType.Raw を指定すれば良いでしょう。
Parameter の Value に指定する値は、現状の byte[] 型のままで OK です。


なお、(おすすめはしませんが)パラメーター化せずに、データを SQL に直接埋め込みたいのであれば、
SQL 中で「HEXTORAW('4B523030')」の表記を使えば RAW 型の 0x4B523030 なデータとして処理できます。

# 実際には、'4B523030' という文字列を渡しても INSERT で登録できるようですけれども。
引用返信 編集キー/
■49657 / inTopicNo.7)  Re[6]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 裕猫 (104回)-(2010/05/12(Wed) 08:20:46)
No49633 (魔界の仮面弁士 さん) に返信
ご指導ありがとうございます。早速試してみて後ほど結果を報告させていただきます。m(_ _)m
引用返信 編集キー/
■49788 / inTopicNo.8)  Re[7]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 裕猫 (105回)-(2010/05/17(Mon) 13:20:15)
No49633 (魔界の仮面弁士 さん) に返信
かなり時間が立ってしまって申し訳ありませんでした。システムにODP.NETが入ってなく組み込み時にトラブったり、現状のシステムに問題が出て、原因究明してたりで遅れてしまいました。で、試したところエラーの連続でいまだに成功していません。SQL文のパラメータの指定が悪いと思うのですが、
 cmd.CommandText = "insert into GN30X(コード,適用,番号) values (HEXTORAW('" + at + "') , HEXTORAW('" + ct + "'), HEXTORAW('" + et + "'))";
とするとORA-0146516進数の指定が無効です。
 cmd.CommandText = "insert into GN30X(コード,適用,番号) values (HEXTORAW(" + at + ") , HEXTORAW(" + ct + "), HEXTORAW(" + et + "))";
とするとORA-00907:右カッコがありません。
cmd.CommandText = "insert into GN30X(コード,適用,番号) values (HEXTORAW(at) , HEXTORAW(ct), HEXTORAW(et))";
とするとORA-00984:ここで列は使用できません。
というエラーを出してきます。どう書けばよいのでしょう?それとも何か参照が足りないのでしょうか?

>byte[] 番号 = BitConverter.GetBytes(IPAddress.NetworkToHostOrder(val3));
ですがIPAddressは何を入れるのでしょう?上記のように書くと現在のコンテキストの中にはありません。とエラーになってしまいます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Oracle;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
using DBA;
using DB構造;
using 構造体;
using STK;
現在USINGで指定しているのはこれだけです。DBAから4つは自分で作ったものです。
すみませんがよろしくお願いいたします。
引用返信 編集キー/
■49789 / inTopicNo.9)  Re[8]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 魔界の仮面弁士 (1649回)-(2010/05/17(Mon) 14:08:42)
2010/05/17(Mon) 14:38:43 編集(投稿者)

No49788 (裕猫 さん) に返信
> SQL文のパラメータの指定が悪いと思うのですが、
であれば、SQL を直接
 cmd.CommandText = "insert into …
と代入しようとするのではなく、
 string sql = "insert into …
 label1.Text = sql;
などとして、TextBox なり Label なりイミディエイトなりに、
HEXTORAW を使ったコードの内容を確認しておくのが先決かと思いますよ。

そしてその SQL 構文が、SQL/Plus 等から利用できることを確認しておいてください。

> ORA-0146516進数の指定が無効です。
HEXTORAW の中に、正しい16進数文字列が指定されていないのでしょう。
実際の SQL を確認してみてください。
No49633 で例示した「HEXTORAW('4B523030')」のような構文になっていますか?

> とするとORA-00907:右カッコがありません。
括弧の位置あるいは対応がおかしかったのでしょう。SQL の内容を確認してみて下さい。

> cmd.CommandText = "insert into GN30X(コード,適用,番号) values (HEXTORAW(at) , HEXTORAW(ct), HEXTORAW(et))";
> とするとORA-00984:ここで列は使用できません。
at,ct,et というのは C# 側の変数名であって、Oracle 側には何の関係もありませんよね。
なので Oracle 側は、それを列名だと解釈して ORA-00984 のエラーを発したのでしょう。

> どう書けばよいのでしょう?それとも何か参照が足りないのでしょうか?
以前も書きましたが、データを埋め込む形にするのではなく、cmd.Parameters 経由で渡すようにしましょう。
もしもデータを埋め込みたいのであれば、実行前に、SQL の内容が適切かを確認しましょう。少なくとも、
適切な 16 進数文字列を埋め込んであるかどうかまでは、ご自身でチェックできますよね。

> >byte[] 番号 = BitConverter.GetBytes(IPAddress.NetworkToHostOrder(val3));
> ですがIPAddressは何を入れるのでしょう?
NetworkToHostOrder は、System.Net.IPAddress の静的メソッドです。

インスタンスメソッドではありませんので、IPAddress に何かを代入する必要はありませんし、
追加の参照設定等も通常は不要です(アセンブリは System.dll ですが、既に参照設定されているはず)。
http://msdn.microsoft.com/ja-jp/library/653kcke1%28VS.90%29.aspx

> 現在USINGで指定しているのはこれだけです。DBAから4つは自分で作ったものです。
System.Net 名前空間も追加するか、もしくは、IPAddress を System.Net.IPAddress に書き換えて下さい。

> 現在のコンテキストの中にはありません。とエラーになってしまいます。
エラー箇所に波線が付いていますよね。では、波線のある IPAddress をクリックしてみてください。
波線の右端に入力補正のためのボックスが現れるかと思います。
それを使えば、上記いずれか(名前空間の補正)は自動的に行われるかと思いますよ。
引用返信 編集キー/
■49798 / inTopicNo.10)  Re[9]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 裕猫 (106回)-(2010/05/18(Tue) 08:51:30)
No49789 (魔界の仮面弁士 さん) に返信
>  string sql = "insert into …
>  label1.Text = sql;
> などとして、TextBox なり Label なりイミディエイトなりに、
> HEXTORAW を使ったコードの内容を確認しておくのが先決かと思いますよ。
やりましたが結果は同じでした。
> そしてその SQL 構文が、SQL/Plus 等から利用できることを確認しておいてください。
まだ未確認です。
>>ORA-0146516進数の指定が無効です。
> HEXTORAW の中に、正しい16進数文字列が指定されていないのでしょう。
> 実際の SQL を確認してみてください。
> No49633 で例示した「HEXTORAW('4B523030')」のような構文になっていますか?
なっていました。
> NetworkToHostOrder は、System.Net.IPAddress の静的メソッドです。
> インスタンスメソッドではありませんので、IPAddress に何かを代入する必要はありませんし、
> 追加の参照設定等も通常は不要です(アセンブリは System.dll ですが、既に参照設定されているはず)。
> http://msdn.microsoft.com/ja-jp/library/653kcke1%28VS.90%29.aspx
使えるようになりました。ありがとうございます。

新しい問題が出てしまいました。ご指導のとうりパラメータを使った方法に変えているのですが、
cmd.Parameters.Add("P1", のところでOracleTypeを指定しようとしますが、OracleTypeがコードスニペットに出てきません。
何かusing文とかが不足しているのでしょうか? OracleTypeExceptionというものしか出てきませんでした。これを使えばいいのでしょうか?質問ばかりですみませんがよろしくお願いいたします。
引用返信 編集キー/
■49806 / inTopicNo.11)  Re[10]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 裕猫 (107回)-(2010/05/18(Tue) 11:40:17)
No49789 (魔界の仮面弁士 さん) に返信
いろいろご指導ありがとうございました。ようやく保存に成功いたしました。ODPを使用するときはusing Oracle.DataAccess.Clientを使うものだと思っていましたが、HEXTORAWやOracleTypeを使うときはusing Oracle.DataAccess.Clientをusing System.Data.OracleClientに変えなければならないのですね、知りませんでした。これにより保存ができるようになりました。未熟者に長くお付き合いいただき感謝いたしております。ありがとうございました。
解決済み
引用返信 編集キー/
■49811 / inTopicNo.12)  Re[11]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ もりお (222回)-(2010/05/18(Tue) 13:11:50)
2010/05/18(Tue) 13:12:25 編集(投稿者)
No49806 (裕猫 さん) に返信

> ODPを使用するときはusing Oracle.DataAccess.Clientを使うものだと思って
> いましたが、HEXTORAWやOracleTypeを使うときは
> using Oracle.DataAccess.Clientをusing System.Data.OracleClientに変えな
> ければならないのですね、知りませんでした。

System.Data.OracleClient 名前空間の OracleType 列挙体を利用するときに
using System.Data.OracleClient を記述するという意味ではその通りなのです
が、ODP.NET を利用する場合に System.Data.OracleClient 名前空間の
OracleType 列挙体を利用する必然性はありません。

ODP.NET の OracleParameter にて型指定を行う場合はマニュアル通り
Oracle.DataAccess.Client 名前空間の OracleDbType 列挙体を利用するのが自
然かと思います。
Oracle Data Provider for .NET開発者ガイド
http://otndnld.oracle.co.jp/document/products/oracle10g/102/windows/B31247-01/OracleParameterClass.htm#i1010814

HEXTORAW 関数に関しても ODP.NET を利用する場合には
System.Data.OracleClient 名前空間は必要としません。

解決済み
引用返信 編集キー/
■49819 / inTopicNo.13)  Re[12]: ORACLEへのバイナリデータの書き込みについて
□投稿者/ 裕猫 (108回)-(2010/05/18(Tue) 16:37:30)
No49811 (もりお さん) に返信
> System.Data.OracleClient 名前空間の OracleType 列挙体を利用するときに
> using System.Data.OracleClient を記述するという意味ではその通りなのです
> が、ODP.NET を利用する場合に System.Data.OracleClient 名前空間の
> OracleType 列挙体を利用する必然性はありません。
>
> ODP.NET の OracleParameter にて型指定を行う場合はマニュアル通り
> Oracle.DataAccess.Client 名前空間の OracleDbType 列挙体を利用するのが自
> 然かと思います。
> Oracle Data Provider for .NET開発者ガイド
> http://otndnld.oracle.co.jp/document/products/oracle10g/102/windows/B31247-01/OracleParameterClass.htm#i1010814
>
> HEXTORAW 関数に関しても ODP.NET を利用する場合には
> System.Data.OracleClient 名前空間は必要としません。
アドバイスありがとうございます。まだまだ知らないことが多いなあと実感しています。参考URLで勉強してOracle.DataAccess.Client を使用した形にしようと思います。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -