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

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

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

Re[6]: int型数値のバイナリ変換方法を教えてください。


(過去ログ 72 を表示中)

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

■42177 / inTopicNo.1)  int型数値のバイナリ変換方法を教えてください。
  
□投稿者/ 裕猫 (22回)-(2009/10/09(Fri) 10:06:41)

分類:[C#] 

ここのところお世話になっています裕猫です。
 ORACLEにバイナリデータを保存するときに数値の変換と保存で困っています。
1000という数値をint型バイナリで保存すると E8-03-00-00 になりますが、ORACLEの中はこれが 00-00-03-E8 というバイト値が反対のデータで保存されています。なのでint型1000 をバイトデータの反転をして保存しなければならないのですが、その辺の知識不足でうまくいきません。とりあえず
 int I = int.Parse(textBox3.Text);
 byte[] bt3 = BitConverter.GetBytes(I);
 byte[] bt4 = new byte[4];
 Array.Copy(bt3, 3, bt4, 0, 1);
 Array.Copy(bt3, 2, bt4, 1, 1);
 Array.Copy(bt3, 1, bt4, 2, 1);
 Array.Copy(bt3, 0, bt4, 3, 1);
 string sqlstr = "insert into TEST_HI01(COL1, COL2, COL3) values('" + textBox1.Text + "','" + textBox2.Text + "', '" + bt4 + "')";
 cmd.CommandText = sqlstr;
 int i = cmd.ExecuteNonQuery();
としてみたのですが、
ORA-01465:16進数の指定が無効です。 というエラーが出てしまいます。どうしたらいいかお解かりのかたおられましたら、お助けください。
                                                  よろしくお願いいたします。
開発環境
 OS:WindowsXP SP3
 言語:VisualStudio2008Pro C#
 データベース:ORACLE 10g

引用返信 編集キー/
■42179 / inTopicNo.2)  Re[1]: int型数値のバイナリ変換方法を教えてください。
□投稿者/ ぽぴ王子 (454回)-(2009/10/09(Fri) 10:25:11)
ぽぴ王子 さんの Web サイト
No42177 (裕猫 さん) に返信
>  ORACLEにバイナリデータを保存するときに数値の変換と保存で困っています。
> 1000という数値をint型バイナリで保存すると E8-03-00-00 になりますが、ORACLEの中はこれが 00-00-03-E8 というバイト値が反対のデータで保存されています。なのでint型1000 をバイトデータの反転をして保存しなければならないのですが、その辺の知識不足でうまくいきません。

失礼ながら、知識不足というより考慮不足あるいはデバッグ不足かと思います。

>  string sqlstr = "insert into TEST_HI01(COL1, COL2, COL3) values('" + textBox1.Text + "','" + textBox2.Text + "', '" + bt4 + "')";

このコードの内容を見てみましたか?そもそも textBox1 と textBox2 の内容が示されていないのでわかりませんが

insert into TEST_HI01(COL1, COL2, COL3) values('1','2', 'System.Byte[]')

のようになっているかと思います。これでは全く意味がありません。
というか、そもそも COL3 にはどのような形で入るのが正しいのでしょうか。
00-00-03-E8 ?
000003E8 ?
BLOB 型を使っているというのであれば、そもそも SQL から変更しないといけませんし、その部分が明確になっていないので
回答は難しいです。

>  byte[] bt3 = BitConverter.GetBytes(I);
>  byte[] bt4 = new byte[4];
>  Array.Copy(bt3, 3, bt4, 0, 1);
>  Array.Copy(bt3, 2, bt4, 1, 1);
>  Array.Copy(bt3, 1, bt4, 2, 1);
>  Array.Copy(bt3, 0, bt4, 3, 1);

この部分も、Array.Copy を使う必要はまったくありません。

 byte[] bt3 = BitConverter.GetBytes(I);
 byte[] bt4 = new byte[4];
 bt4[0] = bt3[3];
 bt4[1] = bt3[2];
 bt4[2] = bt3[1];
 bt4[3] = bt3[0];

のように簡潔に書けるはずです。

引用返信 編集キー/
■42182 / inTopicNo.3)  Re[2]: int型数値のバイナリ変換方法を教えてください。
□投稿者/ 裕猫 (23回)-(2009/10/09(Fri) 11:06:32)
No42179 (ぽぴ王子 さん) に返信
早速の返信ありがとうございます。説明不足すみません。
> このコードの内容を見てみましたか?そもそも textBox1 と textBox2 の内容が示されていないのでわかりませんが
textBox1=英数字4バイト
textBox2=日本語30バイト
textBox3=数字10バイト ←----ここをint型4バイトにしたい

> insert into TEST_HI01(COL1, COL2, COL3) values('1','2', 'System.Byte[]')
ORACLEのカラム COL1,COL2,COL3 全てRAW型です。

> のようになっているかと思います。これでは全く意味がありません。
> というか、そもそも COL3 にはどのような形で入るのが正しいのでしょうか。
ここをどのように入れたらよいかがわかっていません。とにかく
000003E8 ←---------入ったORACLEの中がこうなるようにしたいのです。

>  byte[] bt3 = BitConverter.GetBytes(I);
>  byte[] bt4 = new byte[4];
>  bt4[0] = bt3[3];
>  bt4[1] = bt3[2];
>  bt4[2] = bt3[1];
>  bt4[3] = bt3[0];
>
> のように簡潔に書けるはずです。
早速まねさせていただきます。これでいいとは知らなかったもんですから。

COL1、COLをVARCHAR2型、COL3をint型でそのまま使うようにするなら今の知識で問題なくできるのですが、すでに全てRAW型につくられているもので、FBASICにて作られたプログラムにて運用中のものなのでORACLEの仕様を変更できません。SQL文も覚えながら使っているのでどのように記述するのか試しながらやっているので

>insert into TEST_HI01(COL1, COL2, COL3) values('1','2', 'System.Byte[]')
> のようになっているかと思います。これでは全く意味がありません。

ここはVARCHAR2型、int型のやりかたから推測で作ったものなんで、どう記述するのが正しいのかがわかっていない次第です。
そんな状況なのですがよろしくお願いいたします。
引用返信 編集キー/
■42187 / inTopicNo.4)  Re[3]: int型数値のバイナリ変換方法を教えてください。
□投稿者/ 774RR (409回)-(2009/10/09(Fri) 13:20:19)
そもそもデーターベースに16進を入れるという要望自体がよくわからない。

数値は数値。どんな表記をしても数としては同じ。
だからデーターベースには 1000 という数を入れるべきだろう。
INTEGER にするか DECIMAL にするかは当該数値の使われ方次第ということになる。

「1000 という数値」を 1000 と表記するか 3E8 と表記するか 000003E8 と表記するかは
あくまでも表記上=見た目だけの問題にすぎないぞ。
引用返信 編集キー/
■42188 / inTopicNo.5)  Re[4]: int型数値のバイナリ変換方法を教えてください。
□投稿者/ 裕猫 (24回)-(2009/10/09(Fri) 13:37:46)
No42187 (774RR さん) に返信
> そもそもデーターベースに16進を入れるという要望自体がよくわからない。
>
> 数値は数値。どんな表記をしても数としては同じ。
> だからデーターベースには 1000 という数を入れるべきだろう。
> INTEGER にするか DECIMAL にするかは当該数値の使われ方次第ということになる。
>
> 「1000 という数値」を 1000 と表記するか 3E8 と表記するか 000003E8 と表記するかは
> あくまでも表記上=見た目だけの問題にすぎないぞ。

返信ありがとうございます。おっしゃるとうりです。私もなんでこんな作り方してあるのかわかりません。データベースの中を見てもどんなデータなのかわからんし、何の意味があるのやら。しかし現行のプログラムがそのデータでの運用を前提に作成されており運用されている以上、こちらが合わせるしかないわけで、最初にこんな仕様にしたやつが悪い。社長や社長! Help me \(3 3)/!
引用返信 編集キー/
■42200 / inTopicNo.6)  Re[5]: int型数値のバイナリ変換方法を教えてください。
□投稿者/ 魔界の仮面弁士 (1352回)-(2009/10/09(Fri) 15:45:15)
No42188 (裕猫 さん) に返信
> データベースの中を見てもどんなデータなのかわからんし、

見ても分からないとは、どのように見た場合の事でしょうか?
数値 1000 を格納した RAW フィールドがあって、そのテーブルに対して
   SELECT RawToHex(COL3) RAW_HEX, DUMP(COL3, 16) DMP FROM TEST_HI01
の SQL を実行すると
   RAW_HEX              DMP 
   -------------------- ------------------------------------
   000003E8             Typ=23 Len=4: 0,0,3,e8
という結果が返される……という状況だと思ったのですが、違うのでしょうか。


> そもそも COL3 にはどのような形で入るのが正しいのでしょうか。
SQL で挿入するなら、Oracle の HEXTORAW 関数でどうぞ。
C# 側で、1000 を "000003E8" にしたいという意味であればこんな感じ。


// .NET Framework 3.5
Func<int, string> Dump = v => BitConverter.ToString(BitConverter.GetBytes(v).Reverse().ToArray()).Replace("-", "");

MessageBox.Show( Dump(1000) );

引用返信 編集キー/
■42202 / inTopicNo.7)  Re[6]: int型数値のバイナリ変換方法を教えてください。
□投稿者/ 裕猫 (25回)-(2009/10/09(Fri) 16:17:09)
No42200 (魔界の仮面弁士 さん) に返信
> ■No42188 (裕猫 さん) に返信
>>データベースの中を見てもどんなデータなのかわからんし、
>
> 見ても分からないとは、どのように見た場合の事でしょうか?
> 数値 1000 を格納した RAW フィールドがあって、そのテーブルに対して
> SELECT RawToHex(COL3) RAW_HEX, DUMP(COL3, 16) DMP FROM TEST_HI01
> の SQL を実行すると
> RAW_HEX DMP
> -------------------- ------------------------------------
> 000003E8 Typ=23 Len=4: 0,0,3,e8
> という結果が返される……という状況だと思ったのですが、違うのでしょうか。
>
その通りの状況です。見ても分からないというのはVARCHAR2型、int型で設定してテキストや数値でいれればORACLEのビュワーでそのままデータベースの中が、テキストで表示されて内容が分かるのに、バイナリで保存すると表示が000003E8等と表示されるので見ても内容がが理解できないという意味です。

>>そもそも COL3 にはどのような形で入るのが正しいのでしょうか。
ORACLEのCOL3には"000003E8"という形で記録されてくれればいいのですが。

> SQL で挿入するなら、Oracle の HEXTORAW 関数でどうぞ。
これ、試して見ます。アドバイスありがとうございます。
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -