我目前正在从Server重建表,以便通过C#进行访问。
为此,我将获取Server中使用的数据类型,并将它们映射到OleDbType对象。
不幸的是,每次我试图执行我的访问语句时,都会抛出一个异常,即我的"Create“-语句中有语法错误。我猜这是因为我只是将映射的数据类型添加为文本而不是OleDbParameters。
是否有一种方法可以创建包含"Create“-语句的列名和数据类型的OleDbParameter对象?
String accessConnectionString = "Provider=Microsoft.JET.OLEDB.4.0;Data
Source=" + filepath;
using (OleDbConnection accessConnection = new OleDbConnection(accessConnectionString))
{
ADOX.Catalog cat = new ADOX.Catalog();
cat.Create(accessConnectionString);
OleDbCommand oleCommand = new OleDbCommand();
oleCommand.Connection = accessConnection;
oleCommand.CommandType = CommandType.Text;
accessConnection.Open();
String columnsCommandText = "(";
for (int i = 0; i < reader.GetSchemaTable().Rows.Count; i++) // reader contains data from SQL Server
{
var column = reader.GetName(i); // name of attribute
SqlDbType type = (SqlDbType)(int)reader.GetSchemaTable().Rows[i]["ProviderType"]; // data type
var accessType = SQLAccessMapper.MapDataTypes(type);
columnsCommandText += " " + column + " " + accessType + ",";
}
columnsCommandText = columnsCommandText.Remove(columnsCommandText.Length - 1);
columnsCommandText += ")";
oleCommand.CommandText = "CREATE TABLE " + tablename + columnsCommandText;
oleCommand.ExecuteNonQuery(); // ExceptionMapper:
static class SQLAccessMapper
{
public static OleDbType MapDataTypes(SqlDbType sqlDataType)
{
switch (sqlDataType)
{
case SqlDbType.Int:
return OleDbType.Integer;
case SqlDbType.SmallInt:
return OleDbType.SmallInt;
case SqlDbType.TinyInt:
return OleDbType.TinyInt;
case SqlDbType.Decimal:
return OleDbType.Decimal;
case SqlDbType.Float:
case SqlDbType.Real:
return OleDbType.Single;
case SqlDbType.BigInt:
return OleDbType.BigInt;
case SqlDbType.Char:
return OleDbType.Char;
case SqlDbType.NChar:
return OleDbType.WChar;
case SqlDbType.NText:
case SqlDbType.NVarChar:
case SqlDbType.Text:
return OleDbType.VarWChar;
case SqlDbType.VarChar:
return OleDbType.VarChar;
case SqlDbType.Time:
return OleDbType.DBTime;
case SqlDbType.Date:
return OleDbType.DBDate;
case SqlDbType.DateTime:
case SqlDbType.DateTime2:
case SqlDbType.DateTimeOffset:
case SqlDbType.SmallDateTime:
case SqlDbType.Timestamp:
return OleDbType.DBTimeStamp;
case SqlDbType.Binary:
return OleDbType.Binary;
case SqlDbType.VarBinary:
return OleDbType.VarBinary;
case SqlDbType.Money:
case SqlDbType.SmallMoney:
return OleDbType.Currency;
case SqlDbType.Bit:
return OleDbType.Boolean;
default: return OleDbType.Error;
}
}
}示例Create Table语句:
CREATE TABLE GrTable(
GrtId Integer,
CaseId Integer,
GrDrg VarChar,
GrDrgText VarWChar,
Mdc VarChar,
MdcText VarWChar,
GrPartition VarChar,
Baserate Decimal,
LosUsed Integer,
Htp Integer,
PricePerDay Decimal,
Ltp Integer,
LtpPricePerDay Decimal,
AverLos Decimal,
AverlosPricePerDay Decimal,
Eff Decimal,
Std Decimal,
Adj Decimal,
Gst VarChar,
Pccl Integer,
PriceEff Decimal,
PriceStd Decimal,
PriceAdj Decimal,
DaysExcHtp Integer,
DaysBelowLtp Integer,
DaysBelowAverLos Integer,
TotalPrice Decimal,
BaseratePeriod VarChar)发布于 2017-10-20 16:01:37
您的主要问题在MapDataTypes中。您应该返回MS-Access引擎所期望的字符串,而不是像现在这样依赖于通用枚举SqlDbType到字符串的自动转换。
例如。对于类型为VarWChar的列,需要传递字符串"TEXT“后面跟着字段的大小,而对于类型为整数的字段,则需要字符串"INT”。
public static string MapDataTypes(SqlDbType sqlDataType)
{
switch (sqlDataType)
{
case SqlDbType.Int:
return "INT";
case SqlDbType.VarChar:
return "TEXT(80)";
... AND SO ON FOR EVERY POSSIBLE TYPE
}
}当然,这引入了文本字段的大小问题,但是您可以从相同的GetSchemaTable中检索它,该类型用于在名为ColumnSize的列中查找类型,并将此大小传递给MapDataTypes方法-
public static string MapDataTypes(SqlDbType sqlDataType, int size)
{
switch (sqlDataType)
{
case SqlDbType.Int:
return "INT";
case SqlDbType.VarChar:
return "TEXT(" + size + )";
.....
}
}您可以在此SQL数据类型找到一些允许的类型。
https://stackoverflow.com/questions/46852637
复制相似问题