2009-02-06 2 views
5

내 코드가 작동합니다. 약 10 개의 테이블을 복사 한 후에 오류가 발생합니다. Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not return any key column information. 좋아요, 기본 키를 생성해야합니다. 하지만 왜 10 개 정도의 테이블을 복사 할 수 있습니까? 그런 다음 오류가 발생합니다. 각 행은 기본 키를 반환해야합니까? 행에 기본 키가 없으면 어떻게 생성합니까?해결 방법 : DeleteCommand에 대한 동적 SQL 생성이 키 열 정보를 반환하지 않는 SelectCommand에 대해 지원되지 않습니다.

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Data.OleDb; 
using System.IO; 
using System.Linq; 
using System.Text; 

namespace LCR_ShepherdStaffupdater_1._0 
{ 
    public class DatabaseHandling 
    { 
     static DataTable datatableB = new DataTable(); 
     static DataTable datatableA = new DataTable(); 
     public static DataSet datasetA = new DataSet(); 
     public static DataSet datasetB = new DataSet(); 
     static OleDbDataAdapter adapterA = new OleDbDataAdapter(); 
     static OleDbDataAdapter adapterB = new OleDbDataAdapter(); 
     static string connectionstringA = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationA(); 
     static string connectionstringB = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationB(); 
     static OleDbConnection dataconnectionB = new OleDbConnection(connectionstringB); 
     static OleDbConnection dataconnectionA = new OleDbConnection(connectionstringA); 
     static DataTable tableListA; 
     static DataTable tableListB; 

     static public void addTableA(string table, bool addtoDataSet) 
     { 
      dataconnectionA.Open(); 
      datatableA = new DataTable(table); 
      try 
      { 
       OleDbCommand commandselectA = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionA); 
       adapterA.SelectCommand = commandselectA; 
       adapterA.Fill(datatableA); 
      } 
      catch 
      { 
       Logging.updateLog("Error: Tried to get " + table + " from DataSetA. Table doesn't exist!", true, false, false); 
      } 

      if (addtoDataSet == true) 
      { 
       datasetA.Tables.Add(datatableA); 
       Logging.updateLog("Added DataTableA: " + datatableA.TableName.ToString() + " Successfully!", false, false, false); 
      } 

      dataconnectionA.Close(); 
     } 

     static public void addTableB(string table, bool addtoDataSet) 
     { 
      dataconnectionB.Open(); 
      datatableB = new DataTable(table); 

      try 
      { 
       OleDbCommand commandselectB = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionB); 
       adapterB.SelectCommand = commandselectB; 
       adapterB.Fill(datatableB); 
      } 
      catch 
      { 
       Logging.updateLog("Error: Tried to get " + table + " from DataSetB. Table doesn't exist!", true, false, false); 
      } 



      if (addtoDataSet == true) 
      { 
       datasetB.Tables.Add(datatableB); 
       Logging.updateLog("Added DataTableB: " + datatableB.TableName.ToString() + " Successfully!", false, false, false); 
      } 

      dataconnectionB.Close(); 
     } 

     static public string[] getTablesA(string connectionString) 
     { 
      dataconnectionA.Open(); 
      tableListA = dataconnectionA.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" }); 
      string[] stringTableListA = new string[tableListA.Rows.Count]; 

      for (int i = 0; i < tableListA.Rows.Count; i++) 
      { 
       stringTableListA[i] = tableListA.Rows[i].ItemArray[2].ToString(); 
      } 
      dataconnectionA.Close(); 
      return stringTableListA; 
     } 

     static public string[] getTablesB(string connectionString) 
     { 
      dataconnectionB.Open(); 
      tableListB = dataconnectionB.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" }); 
      string[] stringTableListB = new string[tableListB.Rows.Count]; 

      for (int i = 0; i < tableListB.Rows.Count; i++) 
      { 
       stringTableListB[i] = tableListB.Rows[i].ItemArray[2].ToString(); 
      } 
      dataconnectionB.Close(); 
      return stringTableListB; 
     } 

     static public void createDataSet() 
     { 

      string[] tempA = getTablesA(connectionstringA); 
      string[] tempB = getTablesB(connectionstringB); 
      int percentage = 0; 
      int maximum = (tempA.Length + tempB.Length); 

      Logging.updateNotice("Loading Tables..."); 
      Logging.updateLog("Started Loading File A", false, false, true); 
      for (int i = 0; i < tempA.Length ; i++) 
      { 
       if (!datasetA.Tables.Contains(tempA[i])) 
       { 
        addTableA(tempA[i], true); 
        percentage++; 
        Logging.loadStatus(percentage, maximum); 
       } 
       else 
       { 
        datasetA.Tables.Remove(tempA[i]); 
        addTableA(tempA[i], true); 
        percentage++; 
        Logging.loadStatus(percentage, maximum); 
       } 
      } 
      Logging.updateLog("Finished loading File A", false, false, true); 
      Logging.updateLog("Started loading File B", false, false, true); 
      for (int i = 0; i < tempB.Length ; i++) 
      { 
       if (!datasetB.Tables.Contains(tempB[i])) 
       { 
        addTableB(tempB[i], true); 
        percentage++; 
        Logging.loadStatus(percentage, maximum); 
       } 
       else 
       { 
        datasetB.Tables.Remove(tempB[i]); 
        addTableB(tempB[i], true); 
        percentage++; 
        Logging.loadStatus(percentage, maximum); 
       } 
      } 
      Logging.updateLog("Finished loading File B", false, false, true); 
      Logging.updateLog("Both files loaded into memory successfully", false, true, false); 


     } 

     static public DataTable getDataTableA() 
     { 
      datatableA = datasetA.Tables[Settings.textA]; 

      return datatableA; 
     } 
     static public DataTable getDataTableB() 
     { 
      datatableB = datasetB.Tables[Settings.textB]; 
      return datatableB; 
     } 

     static public DataSet getDataSetA() 
     { 
      return datasetA; 
     } 

     static public DataSet getDataSetB() 
     { 
      return datasetB; 
     } 

     static public void InitiateCopyProcessA() 
     { 
      DataSet tablesA; 
      tablesA = DatabaseHandling.getDataSetA(); 
      int percentage = 0; 
      int maximum = (tablesA.Tables.Count); 

       foreach (DataTable table in tablesA.Tables) 
       { 
        Logging.loadStatus(percentage, maximum); 
        OverwriteTable(table, table.TableName); 
        Logging.updateLog("Copied " + table.TableName + " successfully.", false, true, false); 
        percentage++; 
       } 

     } 

     static void OverwriteTable(DataTable sourceTable, string tableName) 
     { 
      using (var destConn = new OleDbConnection(connectionstringA)) 
      using (var destCmd = new OleDbCommand(tableName, destConn) { CommandType = CommandType.TableDirect }) 
      using (var destDA = new OleDbDataAdapter(destCmd)) 

      { 
       // Since we're using a single table, we can have the CommandBuilder 
       // generate the appropriate INSERT and DELETE SQL statements 
       using (var destCmdB = new OleDbCommandBuilder(destDA)) 
       { 
        destCmdB.QuotePrefix = "["; // quote reserved column names 
        destCmdB.QuoteSuffix = "]"; 
        destDA.DeleteCommand = destCmdB.GetDeleteCommand(); 
        destDA.InsertCommand = destCmdB.GetInsertCommand(); 

        // Get rows from destination, and delete them 
        var destTable = new DataTable(); 
        destDA.Fill(destTable); 
        foreach (DataRow dr in destTable.Rows) 
        { 
         dr.Delete(); 
        } 

        destDA.Update(destTable); 

        // Set rows from source as Added, so the DataAdapter will insert them 
        foreach (DataRow dr in sourceTable.Rows) 
        { 
         dr.SetAdded(); 
        } 
        destDA.Update(sourceTable); 
       } 
      } 
     } 



     }   
    } 

구글이에 나에게 매우 도움이되지이었다

여기 내 코드입니다. 코딩 예를 제공해주십시오.

답변

2

코딩 예제가 실제로 작동하지 않습니다. 테이블에 대한 고유 한 식별자는 무엇인지 결정해야합니다. 기본 키가 없거나 (최소한 고유 인덱스가있는 경우) 행운이 없습니다.

이 문제를 해결할 수있는 유일한 방법은 테이블의 모든 값을 삭제할 레코드와 비교하는 동적 명령을 직접 만드는 것입니다. 동일하면 삭제하십시오.

그러나 동일한 값을 가진 테이블에 여러 행이있을 수 있으므로 테이블에서 여러 행을 삭제할 위험이 있습니다.

관련 문제