【发布时间】:2019-03-13 16:43:16
【问题描述】:
我需要在不使用 OracleBulkCopy(使用托管数据访问)的情况下将表从 MS Access 复制到 Oracle。 第一步是创建表。
从下面的代码中可以看出,我现在在查询列长度时手动转换字段。
我想使用一个语句来为我转换字段,而不必手动为所有类型添加规则,因为有很多类型。 或者更好的是,只需提取某种我可以在 Oracle 中执行的 DDL。 这可能吗?
private int GetLength(string accessTableName, string columnName, OleDbConnection accessConnection)
{
columnName = $"[{columnName}]";
var accessCommand = new OleDbCommand($"select max(len({columnName})) from {accessTableName}", accessConnection);
return int.Parse(accessCommand.ExecuteScalar().ToString());
}
private void CreateEmptyTable(DataTable schemaTable, string tableName, OracleConnection oracleConnection, string accessTableName, OleDbConnection accessConnection)
{
var columnSpecs = new string[schemaTable.Rows.Count];
for (int i = 0; i < schemaTable.Rows.Count; ++i)
{
var name = schemaTable.Rows[i].ItemArray[0].ToString();
var dataType = schemaTable.Rows[i].ItemArray[5];
//var length = schemaTable.Rows[i].ItemArray[2];
var length = GetLength(accessTableName, name.ToString(), accessConnection);
var precision = schemaTable.Rows[i].ItemArray[3];
var scale = schemaTable.Rows[i].ItemArray[4];
var oracleDt = "";
switch (dataType.ToString())
{
case "System.String":
oracleDt = $"nchar({length})";
break;
case "System.Int32":
case "System.Int16":
var iLng = int.Parse(length.ToString()) * 2;
oracleDt = $"number({iLng},0)";
break;
case "System.Double":
case "System.Decimal":
oracleDt = $"number({length},{precision})";
break;
default:
throw new Exception();
}
name = name.ToString().ToUpper().Replace(' ', '_');
columnSpecs[i] = $"{name} {oracleDt}";
}
var query = $"create table MDB_{tableName.ToUpper().Replace(' ', '_')} ( {string.Join(",", columnSpecs)} )";
var oracleCommand = new OracleCommand(query, oracleConnection);
oracleCommand.ExecuteNonQuery();
}
【问题讨论】:
-
Access 没有任何生成DDL 的内置工具,尤其是与Oracle 兼容的方言。简短的回答:没有。
-
数据类型
nchar似乎是个糟糕的选择。当您使用CHAR(x)时,字符串会用空格字符填充,我怀疑这就是您想要的。现在NCHAR和NVARCHAR2通常是无用的,因为数据库中的默认字符集是AL32UTF8,即UTF-8。请改用简单的VARCHAR2。 -
@WernfriedDomscheit 谢谢,我不知道这会导致填充。将使用 varchar2 数据类型。
标签: c# oracle ms-access etl oracle.manageddataaccess