2017-10-20 24 views
0

現在、SQL ServerからC#経由でAccessにテーブルを再構築しています。OleDbParameterを使用してアクセス用テーブルを作成する

私はSQL Serverで使用されるデータ型を取得し、それらをOleDbTypeオブジェクトにマッピングしています。

残念ながら、私はAccess用の文を実行しようとするたびに、 "Create Table"文に構文エラーがあるという例外がスローされます。私はマップされたデータ型をOleDbParametersとしてではなくテキストとして追加するだけなので、これを推測しています。

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(); // Exception 

マッパー:

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) 
+2

AFAIKできませんパラメータを使用して達成する。あなたがそれを行う方法は正しいです。 'oleCommand.CommandText'の値をトラブルシューティングするだけです。問題はそこにあると確信しています。デバッガを使用して取得できるCommandTextに割り当てられた完全な値を送信します。 – andrews

+2

の場合、 'VARCHAR'カラムに**明示的な長さ**を定義する必要があります。そうしないと、最大長1のカラムになります.....通常はあなたが望むものではありません.... 'VARCHAR(n)'を使い**、長さ 'n'を定義する**! –

答えて

2

あなたの主な問題はMapDataTypesです。 MS-Accessエンジンが期待する文字列を返し、一般的な列挙型SqlDbTypeの文字列への自動変換に依存しないようにしてください。

たとえば、 、integer型のフィールドのために、あなたはもちろん、「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 

    } 
} 

これを文字列を必要としているときに、文字列「TEXT」を渡す必要がVARWCHARタイプの列の場合、フィールドのサイズが続きます、テキストフィールドのサイズの問題を紹介し、同じのGetSchemaTableはColumnSizeが名前の欄にタイプを見つけ、MapDataTypesにこのサイズを渡すために使用されるから、あなたがそれを取得することができますが、一部は許さ見つけることができます

public static string MapDataTypes(SqlDbType sqlDataType, int size) 
{ 
    switch (sqlDataType) 
    { 
     case SqlDbType.Int: 
      return "INT"; 
     case SqlDbType.VarChar: 
      return "TEXT(" + size +)"; 
     ..... 


    } 
} 

をMETHOD-このタイプはSQL Data Types

関連する問題