我正在尝试使用截断来自oracle db table“ded_limit_analysis”和 insert 的数据来自ms访问表“Ded-Limit-Analysis” ADODB连接。
到目前为止,我能够设置连接并能够在进行大量研究后将截断查询执行到oracle db table,请参阅下面的代码。我在这方面几乎是新手,所以如果有人帮助实现这个目标会很棒。
为了您的信息,ms数据库名称是Ded-Limit-ACCM.accdb并且我已经使两个表的列名相同,请帮助...
Private Sub CheckCon()
Dim rs As New ADODB.Recordset
'Dim db As Database
' Dim cntr As Long
Dim con As New ADODB.Connection
Dim str As String
'con.Open ("Provider=PROVIDER;Data Source=SOURCE;User ID=USERID; Password=PASSWORD;")
str = "Provider=PROVIDER;Data Source=SOURCE;Persist Security Info=True;Password=PASSWORD;User ID=USERID"
'Set cnn = CreateObject(“ADODB.Connection”)
con.Open str
'Set rs = CreateObject(“ADODB.Recordset”)
If con.State = adStateOpen Then
MsgBox "Welcome to database!"
Else
MsgBox "Sorry. No database."
End If
strSQL = "truncate table ded_limit_analysis"
rs.Open strSQL, con
Do Until rs.EOF
MsgBox rs.Fields(0)
rs.MoveNext
Loop
End Sub
添加我到目前为止所做的代码,但没有运气,我也没有收到任何错误,请参阅下面的代码。
Private Sub comInsert_Click()
Dim rs As New ADODB.Recordset
Dim con As New ADODB.Connection
Dim strSQL As String
Dim str As String
Dim dbs As Database
Set dbs = OpenDatabase("C:\Users\cthoud01\Documents\Ded-Limit-ACCM.accdb")
str = "Provider=MSDAORA;Data Source=SOURCE;Persist Security Info=True;Password=PASSWORD;User ID=USERID"
con.Open str
If con.State = adStateOpen Then
MsgBox "Welcome to database!"
Else
MsgBox "Sorry. No database."
End If
strSQL = "Insert Into ded_limit_analysis (PDPD_ID,PDDS_DESC,PRODUCT_CAT,BASE_PDPD_ID,PROD_CYCLE,HMO_IND_DED,HMO_FAM_DED,HMO_DED_TO_OOP,HMO_IND_FAC_DED,HMO_FAM_FAC_DED,HMO_DED_PFX_RQD,INN_IND_DED,INN_FAM_DED,INN_DED_TO_OOP,OON_IND_DED,OON_FAM_DED,OON_DED_TO_OOP,INN_OON_DED_PFX_RQD,DED_CARRY_OVR,PLAN_TIER,INN_OON_DED_REL,HMO_IND_OOP,HMO_FAM_OOP,INN_IND_OOP,INN_FAM_OOP,OON_IND_OOP,OON_FAM_OOP,INN_OON_OOP_REL,RX_DED_AMT,RX_DED_TO_MED_DED,RX_DED_TO_OOP,LMT1_SERV,LMT1_TYPE,LMT1_VALUE,LMT1_NTWK,LMT2_SERV,LMT2_TYPE,LMT2_VALUE,LMT2_NTWK,LMT3_SERV,LMT3_TYPE,LMT3_VALUE,LMT3_NTWK,LMT4_SERV,LMT4_TYPE,LMT4_VALUE,LMT4_NTWK,LMT5_SERV,LMT5_TYPE,LMT5_VALUE,LMT5_NTWK,LMT6_SERV,LMT6_TYPE,LMT6_VALUE,LMT6_NTWK,LMT7_SERV,LMT7_TYPE,LMT7_VALUE,LMT7_NTWK,LMT8_SERV,LMT8_TYPE,LMT8_VALUE,LMT8_NTWK,HMO_LTLT_PFX_RQD,INN_LTLT_PFX_RQD,OON_LTLT_PFX_RQD) " _
& "select * " _
& "from [Ded-Limit-Analysis];"
con.Execute strSQL
con.Close
dbs.Close
End Sub
答案 0 :(得分:0)
我和你的要求完全相同。我正在为我的解决方案提供评论,但它在c#中。你必须将所有方法捆绑到一个类中,定义任何缺少的变量并调用类方法ReadAndInsertIntoDB(),你就完成了。
您可以从Visual Studio运行它或准备exe(控制台应用程序) 建议 并从dos提示符执行。它将继续在后台工作。
我假设源表和目标表的列名和数据类型相同或等效。我已经通过app.config文件设置了所有变量。
string msAccessFilepath, oracleConnStr, msAccessConnectString;
string destinationTable, isTruncateDestinationTable, sourceDBfileExtension;
OleDbConnection oleDBConnection = null;
int DBCommitRecordBatchSize;
// Open oledbconnection based on file type extension
public CopyAccessToOracle() //Constructor
{
try
{
msAccessFilepath = ConfigurationManager.AppSettings["MDBDataSource"];
oracleConnStr = ConfigurationManager.ConnectionStrings["OracleConnectionString"].ConnectionString;
isTruncateDestinationTable = ConfigurationManager.AppSettings["DestinationTableToTruncate"].Trim().ToUpper(); // YES or NO
DBCommitRecordBatchSize = ConfigurationManager.AppSettings["DBCommitRecordBatchSize"].Length > 0 ? Convert.ToInt32(ConfigurationManager.AppSettings["DBCommitRecordBatchSize"].Trim()) : 10000;
sourceDBfileExtension = Path.GetExtension(msAccessFilepath).Trim().ToUpper();
if (sourceDBfileExtension == ".MDB")
{
msAccessConnectString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + msAccessFilepath;
}
else if (sourceDBfileExtension == ".ACCDB")
{
msAccessConnectString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + msAccessFilepath;
}
oleDBConnection = new OleDbConnection(msAccessConnectString);
oleDBConnection.Open();
}
catch (Exception Ex)
{
....
}
}
从目标数据库获取要更新的表列表
private List<string> GetOracleDBTableList()
{
List<string> oracleTables = new List<string>();
try
{
OracleConnection connection = new OracleConnection(oracleConnStr);
OracleDataAdapter adap = new OracleDataAdapter("select Table_Name from tabs", connection);
DataTable dt = new DataTable();
adap.Fill(dt);
oracleTables = dt.AsEnumerable().Select(col => col.Field<string>("Table_Name")).ToList().ConvertAll(t => t.ToUpper());
}
catch (Exception Ex)
{
.....
}
return oracleTables;
}
获取源数据库中的表列表以读取数据
private List<string> GetMsAccessDBTableList()
{
// Microsoft Access provider factory
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
DataTable userTables = null;
List<string> tableNames = new List<string>();
try
{
using (DbConnection connection = factory.CreateConnection())
{
if (sourceDBfileExtension == ".MDB")
connection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + msAccessFilepath;
else if (sourceDBfileExtension == ".ACCDB")
connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + msAccessFilepath;
string[] restrictions = new string[4];
restrictions[3] = "Table";
connection.Open();
userTables = connection.GetSchema("Tables", restrictions);
}
for (int i = 0; i < userTables.Rows.Count; i++)
tableNames.Add(userTables.Rows[i][2].ToString().ToUpper());
}
catch (Exception Ex)
{
.....
}
return tableNames;
}
目标表中存在检查列的扩展方法
public static class DataRecordExtensions
{
public static bool HasColumn(this IDataRecord dr, string columnName)
{
for (int i = 0; i < dr.FieldCount; i++)
{
if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
return true;
}
return false;
}
public static bool HasColumn(this string[] columnList, string columnsToFind)
{
if (columnList.Length == 1 && (string.IsNullOrWhiteSpace(columnList[0]) || string.IsNullOrEmpty(columnList[0])))
return false;
return columnList.Any(col => string.Equals(col.Trim().ToLower(), columnsToFind.Trim().ToLower()));
}
}
此实现假设源和目标db具有相同列名和相同数据类型的表。
public void ReadAndInsertIntoDB()
{
OleDbDataReader reader = null;
OracleDataAdapter oraAdapter = null;
DataSet oraDS = null;
OracleCommandBuilder oraCommandBuilder = null;
OracleConnection oraConnection = null;
OleDbCommand oleDBCommand = null;
OracleCommand oracleDBCommand = null;
DataTable tblDestination;
DataRow orderRow;
int recordCount = 0;
bool isRecordExist = false;
string tableSuccessfullyCopied = string.Empty;
List<string> oracleTables = new List<string>();
List<string> msAccessTables = new List<string>();
try
{
oracleTables = GetOracleDBTableList();
msAccessTables = GetMsAccessDBTableList();
List<string> sourceTables = msAccessTables.Where(aTab => oracleTables.Contains(aTab)).ToList();
foreach (string sourceTable in sourceTables)
{
destinationTable = sourceTable;
string selectSourceQuery = "SELECT * FROM " + sourceTable;
//This will give no records but blank table
string selectDestinationQuery = "SELECT * from " + destinationTable + " where 1=2 ";
//Trucate existing records from table. This is to avaoid conflict if there is matching primary key.you can comment this step.
string truncateDestinationTableQuery = "TRUNCATE TABLE " + destinationTable;
//Create an OleDbCommand Object.
oleDBCommand = new OleDbCommand(selectSourceQuery, oleDBConnection);
reader = oleDBCommand.ExecuteReader();
oraConnection = new OracleConnection(oracleConnStr);
oraConnection.Open();
if (isTruncateDestinationTable == "YES")
{
oracleDBCommand = new OracleCommand(truncateDestinationTableQuery, oraConnection);
int rowsDeleted = oracleDBCommand.ExecuteNonQuery();
}
oraAdapter = new OracleDataAdapter(selectDestinationQuery, oraConnection);
// Create a Empty Dataset to Fill with data Read Through Data Reader.
oraDS = new DataSet();
oraCommandBuilder = new OracleCommandBuilder(oraAdapter);
// Set the MissingSchemaAction property to AddWithKey because Fill will not cause primary
// key & unique key information to be retrieved unless AddWithKey is specified.
oraAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
oraAdapter.Fill(oraDS);
tblDestination = oraDS.Tables[0];
//Exclude Some of the Columns Who has Default Value at Destination Table
if (destinationTableColumnToSkip.Length > 0)
{
for (int index = 0; index < destinationTableColumnToSkip.Length; index++)
{
tblDestination.Columns.Remove(destinationTableColumnToSkip[index].Trim());
}
}
//Reading All Column Names of source Table of Dataset.
string[] sourceColumnNames = Enumerable.Range(0, reader.FieldCount)
.Select(reader.GetName)
.ToArray();
//Reading All Column Names of Destination Table of Dataset.
string[] destinationColumnNames = tblDestination.Columns.Cast<DataColumn>()
.Select(x => x.ColumnName)
.ToArray();
//Begin Reading Data from Source and Assigning to Destination .
recordCount = 0;
while (reader.Read())
{
orderRow = tblDestination.NewRow();
isRecordExist = false;
foreach (string columnName in destinationColumnNames)
{
if (sourceColumnNames.HasColumn(columnName))
{
isRecordExist = true;
orderRow[columnName] = reader[reader.GetOrdinal(columnName)] ?? DBNull.Value;
}
else
{
isRecordExist = true;
//If Column is not matching then add your logic to get correct column name and assign the value
}
}
if (isRecordExist) // Add new row if record exists
oraDS.Tables[0].Rows.Add(orderRow);
// if Record count is more than Batch Size. Save the records in batch
if (recordCount % DBCommitRecordBatchSize == 0)
{
oraAdapter.Update(oraDS);
//Delete all rows from table after saving it to database
oraDS.Tables[0].Clear();
}
}
//Inserting Records Into Oracle Database Using Dataset.
// Commit records if its less than 1000
oraAdapter.Update(oraDS);
}
//Clearing Oracle Connection Pool So that Next Connection to DB will Not Fail
OracleConnection.ClearAllPools();
}
catch (Exception Ex)
{
....
}
finally
{
if (null != oleDBConnection) oleDBConnection.Close();
if (null != reader) reader.Close();
if (null != oraAdapter) oraAdapter.Dispose();
if (null != oraDS) oraDS.Dispose();
if (null != oraConnection) oraConnection.Close();
}
}
在创建类
后调用此实现CopyAccessToOracle objCopyAccessToOracle = new CopyAccessToOracle()
objCopyAccessToOracle.ReadAndInsertIntoDB();