.NET VisualStudioでSQLiteを使用する
今回は既存のOracleデータベースの選択したテーブルから、SQLiteにテーブルを作成しデータを移送するコードです。
データ移送がメンドイので作りました。自分用のメモです。
画面を表示するとリストボックスにOracleデータベースのテーブル一覧が表示されます。
SQLiteDB選択ボタンでデータを移送するSQLiteデータベースを選択してください。
データ移送ボタンで処理を実行します。
Imports System.Data.Common Public Class FrmOracleToSqlite Private Const CONNECTION_STRING_PC As String = "user id=xxxxx;password=xxxxx;data source=xxxxx" Private Const PROVIDER_NAME_PC As String = "System.Data.OracleClient" Private _ConnectionStringAndroid As String = "data source={0}" Private Const PROVIDER_NAME_ANDROID As String = "System.Data.SQLite" Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load SetTableNameList() End Sub Private Sub cmdSelectDb_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdSelectDb.Click Using dialog As New OpenFileDialog If dialog.ShowDialog() = Windows.Forms.DialogResult.OK Then Me._ConnectionStringAndroid = String.Format(Me._ConnectionStringAndroid, dialog.FileName) Me.lblDbNm.Text = Me._ConnectionStringAndroid End If End Using End Sub Private Sub cmdExec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExec.Click If Me.lstTableName.CheckedItems.Count = 0 Then MessageBox.Show("テーブルを選択して下さい。") Return End If System.Windows.Forms.Cursor.Current = Cursors.WaitCursor For Each sTableName As String In Me.lstTableName.CheckedItems CreateTableForAndroid(sTableName) Next MessageBox.Show("終了~!") End Sub '-----Private----- Private Sub SetTableNameList() Dim factory As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_PC) Dim tbl As New DataTable Using cnn As DbConnection = factory.CreateConnection() cnn.ConnectionString = CONNECTION_STRING_PC cnn.Open() Try Using cmd As DbCommand = cnn.CreateCommand cmd.CommandText = "select table_name from user_tables order by table_name" Using adp As DbDataAdapter = factory.CreateDataAdapter adp.SelectCommand = cmd adp.Fill(tbl) End Using End Using Finally cnn.Close() End Try End Using 'cnn For idx As Integer = 0 To tbl.Rows.Count - 1 Me.lstTableName.Items.Add(tbl.Rows(idx).Item(0).ToString, False) Next End Sub Private Sub CreateTableForAndroid(ByVal sTableName As String) Dim factoryPC As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_PC) Dim factoryAD As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_ANDROID) 'PC側テーブル情報を取得 Dim tblSchema As New DataTable Dim tblPKey As New DataTable Using cnn As DbConnection = factoryPC.CreateConnection() cnn.ConnectionString = CONNECTION_STRING_PC cnn.Open() Try Using adp As DbDataAdapter = factoryPC.CreateDataAdapter '--列情報 Using cmd As DbCommand = cnn.CreateCommand adp.SelectCommand = cmd Dim sbSql As New System.Text.StringBuilder With sbSql .AppendLine("select") .AppendLine(" C.Column_Name") .AppendLine(" ,C.Data_type") .AppendLine(" ,C.Data_precision") .AppendLine(" ,C.Data_scale") .AppendLine(" ,C.Nullable") .AppendLine("FROM USER_TAB_COLUMNS C") .AppendLine(" INNER JOIN USER_TABLES T ON") .AppendLine(" C.Table_Name = T.Table_Name") .AppendLine("WHERE") .AppendLine(" T.Table_Name='" & sTableName & "'") End With cmd.CommandText = sbSql.ToString adp.Fill(tblSchema) End Using '--主キー情報 Using cmd As DbCommand = cnn.CreateCommand adp.SelectCommand = cmd Dim sbSql As New System.Text.StringBuilder With sbSql .AppendLine("SELECT") .AppendLine(" B.COLUMN_NAME AS COL_NAME") .AppendLine("FROM USER_CONSTRAINTS A") .AppendLine(" LEFT JOIN USER_CONS_COLUMNS B ON") .AppendLine(" B.TABLE_NAME = A.TABLE_NAME") .AppendLine(" AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME") .AppendLine("WHERE") .AppendLine(" B.TABLE_NAME = '" & sTableName & "'") .AppendLine(" AND A.CONSTRAINT_TYPE = 'P'") End With cmd.CommandText = sbSql.ToString adp.Fill(tblPKey) End Using End Using Finally cnn.Close() End Try End Using 'cnn 'Android側にテーブル作成 '--Drop文作成 Dim sSqlDrop As String = "DROP TABLE " & sTableName '--主キーリスト作成 Dim lstPKey As New List(Of String) For Each r As DataRow In tblPKey.Rows lstPKey.Add(r.Item("COL_NAME").ToString) Next '--Create文作成 Dim sqlCreate As New System.Text.StringBuilder With sqlCreate .AppendLine("CREATE TABLE " & sTableName & "(") For idx As Integer = 0 To tblSchema.Rows.Count - 1 If idx <> 0 Then .Append(",") End If .Append(tblSchema.Rows(idx).Item("Column_Name").ToString) Select Case tblSchema.Rows(idx).Item("Data_type").ToString Case "VARCHAR2", "DATE" .Append(" TEXT") Case "NUMBER" If CInt(tblSchema.Rows(idx).Item("data_scale")) = 0 Then .Append(" NUMBER") Else .Append(" REAL") End If End Select If tblSchema.Rows(idx).Item("Nullable").ToString = "N" Then .Append(" NOT NULL") End If .AppendLine("") Next sqlCreate.AppendLine(",PRIMARY KEY (" & String.Join(",", lstPKey.ToArray) & ")") sqlCreate.AppendLine(")") End With '--テーブル作成 Using cnn As DbConnection = factoryAD.CreateConnection() cnn.ConnectionString = Me._ConnectionStringAndroid cnn.Open() Try Using adp As DbDataAdapter = factoryAD.CreateDataAdapter Using cmd As DbCommand = cnn.CreateCommand cmd.CommandText = sSqlDrop Try cmd.ExecuteNonQuery() Catch ex As Exception '何もしない End Try cmd.CommandText = sqlCreate.ToString cmd.ExecuteNonQuery() End Using End Using Finally cnn.Close() End Try End Using 'cnn 'データ移送 Const DATA_CNT As Integer = 100 Dim iSt As Integer = 0 Dim iEd As Integer = iSt + DATA_CNT - 1 '--PC側データのSELECT文の作成 Dim sqlSelect As New System.Text.StringBuilder With sqlSelect .AppendLine("SELECT TMPTABLE2.* FROM") .AppendLine(String.Format("(SELECT ROWNUM AS ROW_NUM, {0}.* FROM {0} ) TMPTABLE2", sTableName)) .AppendLine("WHERE ROW_NUM >= :ROW_NUM_Sta") .AppendLine("AND ROW_NUM <= :ROW_NUM_End") End With Dim cmdSelect As DbCommand = factoryPC.CreateCommand cmdSelect.CommandText = sqlSelect.ToString Dim pSt As DbParameter = factoryPC.CreateParameter pSt.ParameterName = "ROW_NUM_Sta" cmdSelect.Parameters.Add(pSt) Dim pEd As DbParameter = factoryPC.CreateParameter pEd.ParameterName = "ROW_NUM_End" cmdSelect.Parameters.Add(pEd) '--Android側のInsert文の作成 Dim lstColNm As New List(Of String) Dim lstPrmmNm As New List(Of String) For Each row As DataRow In tblSchema.Rows lstColNm.Add(row.Item("Column_Name").ToString) lstPrmmNm.Add("@" & row.Item("Column_Name").ToString) Next Dim sqlInsert As New System.Text.StringBuilder With sqlInsert .AppendLine("INSERT INTO " & sTableName & "(") .AppendLine(String.Join(","c, lstColNm.ToArray)) .AppendLine(")VALUES(") .AppendLine(String.Join(","c, lstPrmmNm.ToArray)) .AppendLine(")") End With Dim cmdInsert As DbCommand = factoryAD.CreateCommand cmdInsert.CommandText = sqlInsert.ToString For Each colnm As String In lstColNm Dim prm As DbParameter = factoryAD.CreateParameter prm.ParameterName = colnm prm.SourceColumn = colnm prm.SourceVersion = DataRowVersion.Current cmdInsert.Parameters.Add(prm) Next '--データをSelectしInsertをDATA_CNT件づつ繰り返す Using cnnPC As DbConnection = factoryPC.CreateConnection() cnnPC.ConnectionString = CONNECTION_STRING_PC cnnPC.Open() Try Using cnnAd As DbConnection = factoryAD.CreateConnection() cnnAd.ConnectionString = Me._ConnectionStringAndroid cnnAd.Open() Try cmdSelect.Connection = cnnPC cmdInsert.Connection = cnnAd Do '----Select実行 Dim tblSelect As New DataTable Using adp As DbDataAdapter = factoryPC.CreateDataAdapter adp.SelectCommand = cmdSelect cmdSelect.Parameters(pSt.ParameterName).Value = iSt cmdSelect.Parameters(pEd.ParameterName).Value = iEd adp.Fill(tblSelect) End Using If tblSelect.Rows.Count = 0 Then Exit Do End If '----取得したデータの行状態を追加にする For Each row As DataRow In tblSelect.Rows row.SetAdded() Next '----Insert実行 Using adp As DbDataAdapter = factoryAD.CreateDataAdapter adp.InsertCommand = cmdInsert adp.Update(tblSelect) End Using '----インクリメント iSt = iEd + 1 iEd = iSt + DATA_CNT - 1 Loop Finally cnnAd.Close() End Try End Using 'cnnAd Finally cnnPC.Close() End Try End Using 'cnnPC End Sub End Class
0 件のコメント:
コメントを投稿