SQLの窓

2011年09月11日


VB.net : insert 構文によるインポート用ファイルの作成( つまりエクスポート )



接続処理等、その他のコードは上からダウンロードしてご確認下さい。テキストファイルのエンコードに関しては、以下を参照して下さい

VB.net での テキストファイルの読み書きを、出力時のみキャラクタセット毎に条件コンパイル指定する

データベースは MySQL を使っていますが、手法としてはどの RDBMS でも同じです。テーブル名を渡して自動的に作成する為に、OdbcDataReaderGetName というメソッドで列名を取り出しています。

また、データ型に応じて insert 構文のデータ部分を考慮している部分が以下のコードになります。NULL の扱いと、文字列と日付の場合は、シングルクォートで囲うという処理が重要な部分となります

データ型は、VB.net のネイティブな型ですが、この程度の処理であればこれで問題はありません。
( DB にとってのネイティブな型はもう少し面倒な処理をする必要があります )
' ********************************************************
' SQL文作成用列データ取得
'
' 列データを文字列として取得しますが、NULL の場合は
' "NULL" という文字列を返します
' ********************************************************
Function GetValue( myReader As OdbcDataReader, _
	strName As String) As String

	Dim ret As String = ""
	Dim fld As Integer = 0
	Dim TypeName As String

	' 指定された列名より、テーブル内での定義順序番号を取得
	fld = myReader.GetOrdinal(strName)
	' 定義順序番号より、NULL かどうかをチェック
	If myReader.IsDBNull(fld) Then
		' NULL の場合
		ret = "NULL"
	Else
		' NULL でなければ内容をオブジェクトとして取りだして文字列化する
		TypeName = myReader.GetFieldType(fld).ToString()

		' 文字列と日付の場合は、シングルクォートで囲う
		if TypeName = "System.String" or TypeName = "System.DateTime" then
			ret = "'" + myReader.GetValue(fld).ToString() + "'"
		else
			ret = myReader.GetValue(fld).ToString()
		end if
	End If

	' 列の値を返す
	Return ret

End Function




Sub Main()

	' SQL作成に必要なテーブル名を引数から取得する
	' 空白を指定したい場合は、"文字列 文字列" のように指定する
	Dim arguments As String() = Environment.GetCommandLineArgs()
	' 引数は二つのみ許可
	if arguments.Length <> 3 then
		Console.WriteLine("引数を指定して下さい")
		Return
	end if

	' 引数からエクスポート対象テーブル名を取得
	Dim TargetTable1 As String = arguments(1)
	' 引数からインポート対象テーブル名を取得
	Dim TargetTable2 As String = arguments(2)

	' 新しい OdbcConnection オブジェクトを作成
	Dim myCon As OdbcConnection = CreateConnection()

	if myCon is Nothing then
		Console.WriteLine("処理が異常終了しました")
		Return
	end if

	'---------------------------------------------------

	' レコードセットを取得する為の SQL を準備
	Dim myQuery As String = _
		"SELECT * from `" + TargetTable1 + "`"

	' SELECT 実行用のオブジェクトを作成( クラスは更新用と同じです )
	' コンストラクタを使うと以下のようになります
	' Dim execCommand As New OdbcCommand( myQuery, myCon )
	Dim myCommand As OdbcCommand = New OdbcCommand()
	' 実行する為に必要な情報をセット
	myCommand.CommandText = myQuery
	myCommand.Connection = myCon

	' 実行後にレコードセットを取得する為のオブジェクトを作成
	Dim myReader As OdbcDataReader
	' ここで SELECT を実行してその結果をオブジェクトに格納する
	myReader = myCommand.ExecuteReader()

	' 固定回数ループ用( 列名リスト作成 ) 変数
	Dim idx As Integer
	' insert 構文固定部分
	Dim InsertQueryBase As String = "insert into `" + TargetTable2 + "` ("
	' 行毎完成 insert 文 を格納する変数
	Dim InsertQuery As String = Nothing

	' フィールド数より自動で列名リストの作成
	For idx = 0 to myReader.FieldCount - 1
		' 文字列足し算で、初回は区切り文字を追加しない
		if idx <> 0 then
			InsertQueryBase += ","
		end if
		' MySQL 用として ` で囲う
		InsertQueryBase += "`" + myReader.GetName(idx) + "`"
	Next
	InsertQueryBase += ") values("


	' SHIFT_JIS で出力する為のテキストファイルの準備
	Dim SJIS_Enc As Encoding = Encoding.GetEncoding(932)
	Dim WriteFile As StreamWriter = New StreamWriter( TargetTable2 + ".sql", False, SJIS_Enc )

	' 読み出し
	' Rewad メソッドは、行が存在する場合は true、それ以外の場合は false を返します
	Do While myReader.Read()

		' 固定部分を作業変数にセット
		InsertQuery = InsertQueryBase
		For idx = 0 to myReader.FieldCount - 1
			if idx <> 0 then
				InsertQuery += ","
			end if
			' 値部分を文字列に追加
			InsertQuery += GetValue(myReader,myReader.GetName(idx))
		Next
		' 行の最後( 一括実行する為に、最後にセミコロンを付加 )
		InsertQuery += ");"

		' 一行の完成した insert 文
		WriteFile.WriteLine( InsertQuery )

	Loop

	' リソースの後片づけ
	myReader.Close()
	myReader.Dispose()
	WriteFile.Close()
	WriteFile.Dispose()

	'---------------------------------------------------

	Call EndConnection( myCon )

End Sub
posted by lightbox at 2011-09-11 14:06 | VB.NET : データベース | このブログの読者になる | 更新情報をチェックする
バッチ処理

Microsoft Office
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり