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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

3回答

3670閲覧

VB.NETとoracleのShift-JISエンコードについて

koji2017

総合スコア30

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

2クリップ

投稿2018/07/24 12:31

編集2018/08/03 22:26

Shift-JISに変換できない文字をoracleのDB(キャラクターセットはシフトJIS)にいれると半角ハテナになるかどうかを
oracleに入れる前にVB.NET上で判定する方法はありますか?
半角ハテナになるか全角ハテナになるのかを事前に判定したいのです。
(oracleの文字化けには「半角ハテナ」と「全角ハテナ」になるケースがあるがどちらになるか判定したい)
よろしくお願いします。

文字化けの例)
森鷗外の「鷗」 → 全角ハテナ(?)
ℓ(リットル) → 半角ハテナ(?)

判定したい目的)
文字化け後の文字がファイル名に使えるかどうか判定したいから
(半角ハテナはファイル名に使用不可、全角は使用可)

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/07/24 12:38

「環境依存文字等」=「Shift-JISに変換できない文字」ではないと思うのですが? 質問者さんが言う「環境依存文字」の定義をきちんと書いてください。
kenshirou

2018/08/01 04:41 編集

oracleのDBでは、キャラクターセットをシフトJISにしているのでしょうか。 また、例えば「JIS-X0208で定義された文字」以外を含むかどうかチェックしたい、というような明確な目的があるのでしょうか? あと、「半角ハテナになるか全角ハテナになるのかを事前に判定したい」とありますが、「文字化けするかしないか」の判定では不十分でしょうか?(oracleの文字化けには「半角ハテナ」と「全角ハテナ」になるケースがあるのでしょうか?)
koji2017

2018/08/01 11:20

補足を追記しました。説明不足で申し訳ありませんでした。
YAmaGNZ

2018/08/03 22:41 編集

どのような処理順序なのか分かりませんが、DBに格納し文字化けOKのデータをファイル名として利用するなら、文字化け後の半角?を置き換えすればいいだけなのでは?
koji2017

2018/08/04 07:49

ちょっと違いますね。oracleに入れた後文字化けするかを判定したいのです。
guest

回答3

0

ベストアンサー

ちょっと面白そうなので前回回答のあと色々と調べていたところ、同じクエリを発行してもクライアントによって結果が異なることに気づきました。
例えば、select '€' chr from dualというクエリをVB.NETから投げると'?'(半角)が返ってきますが、A5SQLから投げると'?'(全角)が返ってきます。
もしかしたらクライアント依存の部分があるのでは。

そこでVB.NETで全文字1文字ずつselectして試してみました。
以下検証コード。

VBNET

1Imports Oracle.ManagedDataAccess.Client 2Public Class Form1 3 Dim ds As New List(Of EncData) 4 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load 5 For i = 0 To 55295 6 Try 7 Dim d As New EncData 8 d.codep = i 9 d.orig = Char.ConvertFromUtf32(i) 10 ds.Add(d) 11 Catch ex As Exception 12 End Try 13 Next 14 ora_convert(ds) 15 to_file(ds) 16 DataGridView1.DataSource = ds 17 End Sub 18 Private Sub ora_convert(ByRef lds As List(Of EncData)) 19 Dim constr = "User Id=xxxx;Password=xxxx;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)))" 20 Dim conn = New OracleConnection(constr) 21 conn.Open() 22 Dim sql = "select :val from dual" 23 Dim cmd = conn.CreateCommand 24 cmd.Connection = conn 25 cmd.CommandType = CommandType.Text 26 cmd.CommandText = sql 27 lds.ForEach(Sub(s) 28 cmd.Parameters.Clear() 29 cmd.Parameters.Add("val", s.orig) 30 Dim result = cmd.ExecuteScalar 31 s.convto = result.ToString 32 End Sub) 33 conn.Close() 34 conn.Dispose() 35 End Sub 36 Private Sub to_file(ByRef lds As List(Of EncData)) 37 Dim fp = My.Computer.FileSystem.OpenTextFileWriter("output.txt", False) 38 For Each item In lds 39 fp.Write(item.codep) 40 fp.Write(vbTab) 41 fp.Write(item.orig) 42 fp.Write(vbTab) 43 fp.Write(item.convto) 44 fp.Write(vbTab) 45 fp.Write(item.isWideOrSmallQs) 46 fp.Write(vbTab) 47 fp.WriteLine() 48 Next 49 fp.Close() 50 fp.Dispose() 51 End Sub 52End Class 53Public Class EncData 54 Public Property codep As Integer 55 Public Property orig As String 56 Public Property convto As String 57 Public ReadOnly Property isWideOrSmallQs As String 58 Get 59 If IsNothing(convto) Then 60 Return "-" 61 ElseIf convto = "?" Then 62 Return "Wide" 63 ElseIf convto = "?" Then 64 Return "Small" 65 Else 66 Return "-" 67 End If 68 End Get 69 End Property 70End Class

結果は、U2FFF以下かつSJISにエンコードできない文字は半角クエスチョンに、U3000以上は全角クエスチョンになりました。全部試していませんがA5SQLからだとおそらくすべて全角クエスチョンになります。

つまり、変換できない文字がどのように扱われるかは環境依存となり、解決策は実環境で全文字変換してリストを作り、そのリストをもとに個別にどう扱うか検討する必要がある、ということでしょう。

なお、上のコードはOracle.ManagedDataAccessで実行した結果で、クライアント側のドライバが変わると結果が変わる可能性があるので、質問者さんのほうでも個別検証して結果を取得すべきと思います。

8/4 追記を受けて

判定したい目的)

文字化け後の文字がファイル名に使えるかどうか判定したいから
(半角ハテナはファイル名に使用不可、全角は使用可)

という理由なら、本回答で例示した変換表をもって事前変換するか、処理の都度検証コードでも書いたselect :var from dualをOracle側に投げて変換後の文字列を事前取得。それをもってファイル名のバリデーションをかければいいのではないかと。
前述したとおりクライアントによって変換の仕様が異なるので試しに投げてみるのが一番だと考えます。

投稿2018/08/02 11:42

編集2018/08/04 06:06
hope_mucci

総合スコア4447

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

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

koji2017

2018/08/04 07:55

insertしなくてもselectだけで確認できるのですね。 ありがとうございました!
guest

0

.NET側で文字列をSJISバイト配列へ変換→SJIS文字列に戻してやれば、少なくとも.NET(Windows)でSJISとして扱えない文字列が?になるので元の文字列と比較してやればわかります。

今実行できる環境がC#しかなかったためC#で書いていますがVB.NETでもほぼ同じ構文です。

C#

1using System.IO; 2using System; 3using System.Text; 4 5class Program 6{ 7 static void Main() 8 { 9 String target = "あいうえお㎖かきくけこ"; //㎖はUnicodeにはあるがsjisにはない 10 Encoding enc = System.Text.Encoding.GetEncoding(932); 11 String target_to = enc.GetString(enc.GetBytes(target)); 12 Console.WriteLine(target_to); // あいうえお?かきくけこ 13 } 14}

ただし、厳密にはOracleDBで扱うSJIS(正確にはJA16SJISTILDE)とWindowsのSJIS(MS932)は微妙に違うかもしれませんが申し訳ないですがうろおぼえです。簡易的な判定方法としてご紹介します。

実際にシステムで使用する文字をテストしてから導入してくださいね。

投稿2018/08/01 14:11

hope_mucci

総合スコア4447

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

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

koji2017

2018/08/01 14:48

ありがとうございます。 しかしこの方法ではoracleに入れたときに全角ハテナになるかどうかは判定できないですね。
hope_mucci

2018/08/01 22:14

実際に全角クエスチョンマークに変換される文字を例示してください。 どんな文字がありますか?
kenshirou

2018/08/02 04:36 編集

koji2017様 全角ハテナとは「?」のことですか、それとも「�」(U+FFFD)のことですか? あと、hope_mucci様ご指摘のように、どのような文字で全角ハテナに文字化けするかが分かれば、ある程度は傾向が見えてくるかも知れません。 ただ、そもそも、文字化けの種類の判定が必要な理由は何なのでしょうか?
koji2017

2018/08/03 22:27

文字化けの例と判定が必要な理由を追記しました
guest

0

直接の回答ではありませんが、Oracleのテーブルに異なるキャラクタセットの文字列を入れたい でNCHARやNVARCHAR2データ型にutf-8 のデータを入れられるようですので、文字化けを避けられるか試してみては?

追記
以下のようにUnicodeは変更されます。
Unicode 各バージョンとその特徴 プログラム・コードできちんと対応できているユーザーはたぶんないでしょう。運用でカバーがほとんどかと。
もっと建設的な方向に労力を費やした方がよろしいかと。

投稿2018/07/24 14:20

編集2018/07/26 13:39
Orlofsky

総合スコア16415

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

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

koji2017

2018/07/26 10:32

ご回答ありがとうございます! 文字化けを避けたいわけではないのです。 どのように化けるか事前に判定したいのです。 わかりにくくて申し訳ありません。
Orlofsky

2018/07/26 13:40

回答を追記しました。Unicodeは変更が付きまといますから、文字化けを事前に判定するのは難しいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問