0

问题:在ODBC(odbcad32.exe)中可见odbc驱动程序((称为“Pervasive ODBC引擎接口”),但在SQL服务器中不可见odbc驱动程序2008导入向导,虽然我可以在SQL Server 2000导入向导中看到相同的odbc驱动程序SQL Server 2008导入向导中有限的odbc连接

我使用的是SQL Server 2008,SQL Server 2000和普适SQL v11的32位win 7操作系统。有帮助...很多谢谢!

回答

0

在我的PSQL v11盒子里也安装了SQL Server 2008 R2,我没有看到SQL Server导入的“数据源”对话框中列出的“Pervasive ODBC Engine Interface”和导出向导,我确实看到了“Pervasive P SQL OLEDB Provider“和”Pervasive Provider,release v4.0“(以及3.5和3.2)。 Pervasive Provider是一个ADO.NET提供程序。我确实看到了“为ODBC .NET Framework数据提供程序”,如果我把一个DSN名称为普适DSN(如DEMODATA),它的工作原理。

+0

感谢Mirtheil。答案很有帮助。然而,当我试图用您的解决方案,我得到了在执行数据库的导入以下错误:“无法获取或者源和目标数据的数据源类型列的列信息没有被映射到目的地.....- - 找不到列-1“错误。我知道源表和目标表具有完全相同的列名和数据类型。我认为它是由.net框架odbc造成的问题'....有任何建议吗? – user2109347 2013-02-26 02:45:19

+0

请任何其他的答案 – user2109347 2013-02-26 20:15:58

+0

下面的链接修复了我在26/02/13评论中提到的问题http://blogs.msdn.com/b/dataaccesstechnologies/archive/2010/09/09/sql-server-import-export -wizard - 失败 - 同时,试图对检索-的数据,从无孔不入,database.aspx – user2109347 2013-02-27 03:13:19

1

我永远无法知道如何使“导入/导出”向导在Sql Server Management Studio中工作。我甚至尝试修改'ProviderResources.xml'文件,就像我在另一个回复中看到的那样。

我试图迁移使用专有'Timberline Data'ODBC驱动程序的Sage Timberline Office数据。当您在.NET中调用“GetSchema”函数时,该驱动程序缺少'ORDINAL_POSITION'列。因此,Sql Server Management Studio中的“导入/导出”失败。

我最终不得不编写自己的应用程序来将数据复制到SQL服务器。唯一的缺点是它不知道主键,索引或其他约束。尽管如此,我在MSSQL中获取数据,所以我很高兴。

我相信这个代码将是有用的人,所以在这里你去。

Program.cs的

using System; 
using System.Data.Odbc; 
using System.Data.SqlClient; 
using System.Data; 
using System.Collections.Generic; 
using System.Diagnostics; 

namespace TimberlineOdbcSync 
{ 
    class Program 
    { 
     static string currentTableName; 

     const string sourceOdbcDriver = "{Timberline Data}"; 
     const string sourceOdbcDsn = "timberline data source"; 
     const string sourceOdbcUid = "user1"; 
     const string sourceOdbcPwd = "user1a"; 

     const string destSqlServer = "SERVER5"; 
     const string destSqlDatabase = "TSData"; 
     const string destSqlUsername = ""; 
     const string destSqlPassword = ""; 
     const string destSqlOwner = "dbo"; 

     public static void Main(string[] args) 
     { 
      DateTime allStartDate = DateTime.Now; 
      DateTime allEndDate; 

      DateTime tableStartDate = DateTime.Now; 
      DateTime tableEndDate; 

      TimeSpan diff; 

      string errMsg; 

      int pCount; //pervasive record count 
      int sCount; //sql server record count 

      string sourceOdbcConnString = 
       "Dsn=" + sourceOdbcDsn + ";" + 
       "Driver="+ sourceOdbcDriver +";" + 
        (!string.IsNullOrEmpty(sourceOdbcUid) ? "uid="+ sourceOdbcUid +";" : "") + 
        (!string.IsNullOrEmpty(sourceOdbcUid) ? "pwd="+ sourceOdbcPwd +";" : ""); 

      string destSqlConnString = 
       "Server=" + destSqlServer + ";" + 
       "Database=" + destSqlDatabase+ ";" + 
       (!string.IsNullOrEmpty(destSqlUsername) && !string.IsNullOrEmpty(destSqlPassword) ? 
       "User Id=" + destSqlUsername + ";" + 
       "Password=" + destSqlPassword + ";" 
       : 
       "Trusted_Connection=true;"); 

      try{ 
       using(OdbcConnection pConn = new OdbcConnection(sourceOdbcConnString)){ 

        pConn.Open(); 

        List<string> tables = new List<string>(); 

        //get a list of all tables 
        using(DataTable tableschema = pConn.GetSchema("TABLES")) 
         foreach(DataRow row in tableschema.Rows) 
          tables.Add(row["TABLE_NAME"].ToString()); 

        foreach(string tableName in tables){ 

         //set the current table name 
         currentTableName = tableName; 

         try{ 

          //get the schema info for the table (from pervasive) 
          DataTable dtSchema = pConn.GetSchema("Columns", new string[]{null, null, tableName}); 

          //if we could not get the schema 
          if(dtSchema == null || dtSchema.Rows.Count <= 0){ 
           pConn.Close(); 
           errMsg = "Error: Could not get column information for table " + tableName; 
           Trace.WriteLine(errMsg); 
           WriteErrorEvent(errMsg); 
           return; 
          } 

          //emit the table name 
          Trace.Write("[" + tableName + "]"); 

          //get the number of records in this table 
          pCount = TableCount(tableName, pConn); 

          //emit the number of records in this table 
          Trace.Write(" = P:" + pCount); 

          //create a data reader to read the pervasive data 
          string sql = "select * from \""+ tableName + "\""; 
          OdbcCommand cmd = new OdbcCommand(sql, pConn); 
          OdbcDataReader dr = cmd.ExecuteReader(); 

          //create a connection to SQL Server 
          using (SqlConnection sConn = new SqlConnection(destSqlConnString)){ 

           //open the connection 
           sConn.Open(); 

           //if the table already exists 
           if(TableExists(tableName, sConn)){ 

            //get the record count for this table 
            sCount = TableCount(tableName, sConn); 

           } else { 

            //set the record count to zero 
            sCount = 0; 
           } 

           //output the record count 
           Trace.Write(", S: " + sCount); 

           //if the record counts match 
           if(pCount == sCount){ 

            //output an indicator that we are skipping this table 
            Trace.WriteLine(" -- Skipping"); 

            //skip this table and go to the next 
            continue; 

           } 

           //output a blank line 
           Trace.WriteLine(""); 

           //create the table in SQL Server using the schema info from Pervasive 
           CreateTableInDatabase(dtSchema, destSqlOwner, tableName, sConn); 

           // Copies all rows to the database from the data reader. 
           using (SqlBulkCopy bc = new SqlBulkCopy(sConn)) 
           { 
            // Destination table with owner - 
            // this example does not check the owner names! It uses dbo exclusively. 
            bc.DestinationTableName = "[" + destSqlOwner + "].[" + tableName + "]"; 
            bc.BulkCopyTimeout = 30; 
            bc.BatchSize = 3000; 
            bc.BulkCopyTimeout = 12000; 

            // User notification with the SqlRowsCopied event 
            bc.NotifyAfter = 1000; 
            bc.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnSqlRowsCopied); 

            //output the date and time so we know when we started 
            tableStartDate = DateTime.Now; 
            Trace.WriteLine("Copying " + pCount + " records to " + destSqlServer + " - " + tableStartDate.ToString("g")); 

            // Starts the bulk copy. 
            bc.WriteToServer(dr); 

            tableEndDate = DateTime.Now; 
            diff = tableEndDate - tableStartDate; 

            Trace.WriteLine(String.Format(
             "Completed {4} at {0}\r\nDuration: {1}:{2}:{3}", 
              tableEndDate.ToString("g"), 
              diff.Hours.ToString(), diff.Minutes.ToString(), diff.Seconds.ToString(), 
              tableName)); 

            // Closes the SqlBulkCopy instance 
            bc.Close(); 
           } 

           dr.Close(); 

          } 
         }catch(Exception ex){ 
          errMsg = "Error: " + ex.Message + Environment.NewLine + 
               "Stack: " + ex.StackTrace + Environment.NewLine; 
          Trace.WriteLine(errMsg); 
          WriteErrorEvent(errMsg); 
          if(!ReadBool("Do you want to continue? [y/n]")){ 
           break; 
          } 
         }//end try 
        }//end for 
       }//end using 

       allEndDate = DateTime.Now; 
       diff = allEndDate - allStartDate; 

       Trace.WriteLine(
        "Bulk copy operation complete" + Environment.NewLine + 
        "Started: " + allStartDate.ToString("g") + Environment.NewLine + 
        "Current: " + allEndDate.ToString("g") + Environment.NewLine + 
        String.Format("Duration: {0}:{1}:{2}", 
         diff.Hours.ToString(), 
         diff.Minutes.ToString(), 
         diff.Seconds.ToString())); 

      }catch(Exception ex){ 

       errMsg = 
        "Error: " + ex.Message + Environment.NewLine + 
        "Stack: " + ex.StackTrace; 

       Trace.WriteLine(errMsg); 
       WriteErrorEvent(errMsg); 

      }//end try 

      Console.Write("Press any key to continue . . . "); 
      Console.ReadKey(true); 
     } 

     static bool TableExists(string tableName, SqlConnection sqlConn){ 
      int retVal = 0; 
      try{ 
       using(SqlCommand command = sqlConn.CreateCommand()){ 
        command.CommandText = "IF OBJECT_ID('dbo." + tableName + "', 'U') IS NOT NULL SELECT 1 as res ELSE SELECT 0 as res"; 
        retVal = Convert.ToInt32(command.ExecuteScalar()); 
       } 
      }catch(Exception ex){ 
       string errMsg = 
        "Error: Could not determine if table " + tableName + " exists."+ Environment.NewLine + 
        "Reason: " + ex.Message + Environment.NewLine + 
        "Stack: " + ex.StackTrace; 
       Trace.WriteLine(errMsg); 
       WriteErrorEvent(errMsg); 
       retVal = 0; 
      }//end try 
      return (retVal==1); 
     } 

     static int TableCount(string tableName, IDbConnection anyConn){ 
      int retVal = 0; 
      try{ 
       using(IDbCommand command = anyConn.CreateCommand()){ 
        command.CommandText = "SELECT count(*) FROM \"" + tableName + "\""; 
        retVal = Convert.ToInt32(command.ExecuteScalar()); 
       } 
      }catch(Exception ex){ 
       string errMsg = 
        "Error: Could not get table count for " + tableName + "." + Environment.NewLine + 
        "Reason: " + ex.Message + Environment.NewLine + 
        "Stack: " + ex.StackTrace; 
       Trace.WriteLine(errMsg); 
       WriteErrorEvent(errMsg); 
       retVal = 0; 
      }//end try 
      return (retVal); 
     } 

     static bool ReadBool(String question) { 
      while (true) { 
       Console.WriteLine(question); 
       String r = (Console.ReadLine() ?? "").ToLower(); 
       if (r == "y" || r == "yes" || r == "1") 
        return true; 
       if (r == "n" || r == "no" || r=="0") 
        return false; 
       Console.WriteLine("Please Select a Valid Option!!"); 
      }//end while 
     } 

     static void OnSqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) { 
      Trace.WriteLine(String.Format("-- [{1}] Copied {0} rows.", e.RowsCopied, currentTableName)); 
     } 

     private static string s(object o){ 
      return (Convert.IsDBNull(o) ? "" : Convert.ToString(o)); 
     } 

     private static string _drToColSql(DataRow dr){ 
      string colName = s(dr["COLUMN_NAME"]); 
      string ret = "[" + colName + "] "; 
      string typeName = ((string)s(dr["TYPE_NAME"])).ToLower(); 
      switch(typeName){ 
       case "char": 
        ret += "CHAR(" + s(dr["LENGTH"]) + ")"; 
        break; 
       case "byte": 
        ret += "CHAR(" + s(dr["PRECISION"]) + ")"; 
        break; 
       case "text": 
        ret += "VARCHAR(" + s(dr["PRECISION"]) + ")"; 
        break; 
       case "date": 
        ret += "DATE"; 
        break; 
       case "time": 
        ret += "TIME(7)"; 
        break; 
       case "double": 
        ret += "DECIMAL(16,2)"; // + c(dr["PRECISION"]) + "," + c(dr["LENGTH"]) + ")"; 
        break; 
       case "usmallint": 
       case "smallint": 
        ret += "SMALLINT"; 
        break; 
       case "utinyint": 
       case "tinyint": 
        ret += "TINYINT"; 
        break; 
       case "identity": 
       case "integer": 
        ret += "BIGINT"; 
        break; 
       case "smallidentity": 
       case "short": 
        ret += "INT"; 
        break; 
       case "longvarchar": 
       case "memo": 
        ret += "TEXT"; 
        break; 
       case "checkbox": 
        ret += "BIT"; 
        break; 
       case "real": 
        ret += "REAL"; 
        break; 
       default: 
        //this was an unexpected column, figure out what happened 
        Trace.WriteLine("ERROR - Column '" + colName + "' Details: "); 
        Trace.WriteLine("\tCOLUMN_NAME: " + s(dr["COLUMN_NAME"])); 
        Trace.WriteLine("\tTYPE_NAME: " + s(dr["TYPE_NAME"])); 
        Trace.WriteLine("\tDATA_TYPE: " + s(dr["DATA_TYPE"])); 
        Trace.WriteLine("\tLENGTH: " + s(dr["LENGTH"])); 
        Trace.WriteLine("\tPRECISION: " + s(dr["PRECISION"])); 
        Trace.WriteLine("\tSCALE: " + s(dr["SCALE"])); 
        Trace.WriteLine("\tNULLABLE: " + s(dr["NULLABLE"])); 
        throw new Exception("Unexpected data type: " + typeName); 
      } 

      if(s(dr["NULLABLE"])=="1"){ 
       ret += " NULL"; 
      } 

      return ret; 
     } 

     private static bool CreateTableInDatabase(DataTable dtSchemaTable, string tableOwner, string tableName, SqlConnection sqlConn) { 
      // Generates the create table command. 
      string ctStr = "CREATE TABLE [" + tableOwner + "].[" + tableName + "](\r\n"; 
      for (int i = 0; i < dtSchemaTable.Rows.Count; i++) 
      { 
       ctStr += _drToColSql(dtSchemaTable.Rows[i]); 
       if (i < dtSchemaTable.Rows.Count) 
        ctStr += ","; 
       ctStr += "\r\n"; 
      } 
      ctStr += ")"; 

      // Emit SQL statement 
      Trace.WriteLine("-".PadLeft(30, '-')); 
      Trace.WriteLine(ctStr + Environment.NewLine); 

      // Runs the SQL command to make the destination table.  
      using(SqlCommand command = sqlConn.CreateCommand()){ 
       command.CommandText = "IF OBJECT_ID('dbo." + tableName + "', 'U') IS NOT NULL DROP TABLE dbo." + tableName; 
       command.ExecuteNonQuery(); 
       command.CommandText = ctStr; 
       command.ExecuteNonQuery(); 
      } 
      return true; 
     } 

     private static bool WriteErrorEvent(string errMsg){ 
      const string sSource = "PervasiveOdbcSync"; 
      const string sLog = "Application"; 
      try{ 
       if (!EventLog.SourceExists(sSource)) 
        EventLog.CreateEventSource(sSource,sLog); 
       EventLog.WriteEntry(sSource, errMsg); 
       EventLog.WriteEntry(sSource, errMsg, EventLogEntryType.Error, 128); 
       return true; 
      }catch(Exception ex){ 
       Trace.WriteLine("Unable to write error to event log. Reason: " + ex.Message); 
       return false; 
      } 
     } 

    } 
} 

你要一个System.Diagnostics.ConsoleTraceListener添加到您的app.config文件。这样你就可以看到输出的所有东西。如果您还添加了System.Diagnostics.TextWriterTraceListener,可以使应用程序还输出到所有日志文件。