从列表中调用数据

Calling data from a list

我一直在编写一个程序来从 SQL 服务器数据库中提取数据,然后推送到 Visual Foxpro 数据库,但我遇到了障碍。

我已经定义了到两个服务器的连接:

var exportConnection = new SqlConnection(connectionString:
    "Data Source=Localhost;"
    + "Trusted_Connection=yes;"
    + @"connection timeout=30;"
    + @"database=001-CARL_V4");

var importConnection = new OleDbConnection(connectionString:
    "Data Source=Localhost;"
    + @"connection timeout=30;"
    + @"Provider=vfpoledb.1;"
    + @"data source=C:\Users\Joshua.cameron\Desktop\PCHomesImportTestBlank\PCHomesServer\DATABASE\pchomes.dbc");

我已经测试了这两个,没问题。

我已经使用访问器从 SQL 服务器中提取数据:

 public string OwTitle { get; set; }
 public string OwForenames { get; set; }
 public string OwSurname { get; set; }

并将这些值分配给列表:

ImportArray[] exportArray = null;

SqlCommand exportCommand = new SqlCommand(@"select * from dbo.CARL_Owners", exportConnection);
{
    exportConnection.Open();
    using (var exportReader = exportCommand.ExecuteReader())
    {
        Console.WriteLine("Populating Array...");
        try
        {

            var list = new List<ImportArray>();
            //while(exportReader.Read())
            var read = exportReader.Read();
            list.Add(item: new ImportArray
            {
                OwTitle = exportReader.GetValue(0).ToString(),
                OwForenames = exportReader.GetValue(1).ToString(),
                OwSurname = exportReader.GetValue(2).ToString(),                          
            });

            exportArray = list.ToArray();
            Console.WriteLine("Array populated");
           // Console.Write(list);
            Console.ReadKey();

然后我尝试从列表中提取数据并将其推送到 FoxPro Table

try
{
    importConnection.Open();
    Console.WriteLine("Foxpro connection open");
    OleDbCommand deleteOleDbCommand = new OleDbCommand(@"TRUNCATE TABLE CLIENT",
        importConnection);

    Console.WriteLine("writing to table");
    Console.ReadKey();
    using (
        var importCommand =
            new OleDbCommand(
                string.Format(@"INSERT INTO CLIENT (Title,Fname,Sname) VALUES ({0},{1},{2}",
                    exportReader.GetValue(0), exportReader.GetValue(1), exportReader.GetValue(2)),
                importConnection))
    {
        importCommand.ExecuteNonQuery();
        Console.ReadKey();
    }

}
catch (Exception exception)
{
    Console.Write("Foxpro Database unreachable");
    Console.WriteLine(exception.ToString());
}
finally
{
    importConnection.Close();
    Console.WriteLine("Connection closed");
    Console.ReadKey();
}

这就是问题所在。似乎它跳过了本节的一部分。

Output running

从输出中可以看出,它甚至不显示 Console.writeline("writing to table") 部分。

谁能看出我错在哪里?

您的代码可能存在两个问题。

  1. 我认为您没有执行 deleteOleDb 命令。您初始化了它,但您没有在任何地方执行该命令。

  2. @"INSERT INTO CLIENT (Title,Fname,Sname) VALUES ({0},{1},{2}"。您的查询中缺少结束括号。它应该像 @"INSERT INTO CLIENT (Title,Fname,Sname) VALUES ({0},{1},{2})"

这两个可能是您的代码存在的问题。

此问题与您的其他问题相关。 VFP 没有 "Truncate table" 命令,你需要引用值,更好的是你需要使用参数。这是连接两个问题的修订代码:

void Main()
{
  using (var exportConnection = new SqlConnection(connectionString:
      "Data Source=Localhost;"
      + "Trusted_Connection=yes;"
      + @"connection timeout=30;"
      + @"database=001-CARL_V4"))
  using (var importConnection = new OleDbConnection(connectionString:
      @"Provider=vfpoledb.1;" +
      @"data source=C:\Users\Joshua.cameron\Desktop\PCHomesImportTestBlank\PCHomesServer\DATABASE\pchomes.dbc"))
  using (OleDbCommand importCommand = new OleDbCommand(
      @"INSERT INTO CLIENT (Title,Fname,Sname) VALUES (?,?,?)",
      importConnection))
  using (SqlCommand exportCommand = new SqlCommand(@"select 
      title as [title], firstName as [fname], lastName as [sname] 
      from dbo.CARL_Owners", exportConnection))
  {
    importCommand.Parameters.AddWithValue("title", "");
    importCommand.Parameters.AddWithValue("fname", "");
    importCommand.Parameters.AddWithValue("sname", "");

    {
      importConnection.Open();
      Console.WriteLine("Foxpro connection open");
      new OleDbCommand(@"Delete from CLIENT", importConnection).ExecuteNonQuery();

      Console.WriteLine("writing to table");
      exportConnection.Open();

      var exportReader = exportCommand.ExecuteReader();
      while (exportReader.Read())
      {
        importCommand.Parameters["title"].Value = (string)exportReader["title"];
        importCommand.Parameters["fname"].Value = (string)exportReader["fname"];
        importCommand.Parameters["sname"].Value = (string)exportReader["sname"];
        importCommand.ExecuteNonQuery();
      }
      importConnection.Close();
      exportConnection.Close();
    }
  }
}

您还可以创建从 VFP 代码内部到 SQL 服务器的连接,从而使用 "ExecScript" 一次性完成更好的优化插入。即:

void Main()
{
  var vfpCode = @"
  local lnHandle
  lnHandle = SQLStringConnect('driver={SQL Server Native Client 11.0};'+;
      'server=.;Trusted_Connection=yes;database=001-CARL_V4')
  SQLExec( m.lnHandle, ;
   'select  title as [title], firstName as [fname], lastName as [sname] from CARL_Owners', ;
   'crsOwners')
  SQLDisconnect(0)


  * if you can use exclusive locks then:
  * zap    
  * assuming you cant

  delete from Client
  insert into Client (Title,Fname,Sname) ;
      select Title,Fname,Sname from crsOwners";


  using (var importConnection = new OleDbConnection(connectionString:
      @"Provider=vfpoledb.1;" +
      @"data source=C:\Users\Joshua.cameron\Desktop\PCHomesImportTestBlank\PCHomesServer\DATABASE\pchomes.dbc"))
  {
    OleDbCommand cmd = new OleDbCommand("ExecScript", importConnection);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("code", vfpCode);

    importConnection.Open();
    cmd.ExecuteNonQuery();
    importConnection.Close();
  }
}

PS:请注意,我假设您在 MS SQL.

上的字段名称为 title、firstName、lastName

我在这里添加另一个答案,因为您的另一个问题(很遗憾)已关闭(我不知道他们为什么这样做)。我将解释作为评论放在两者之间。请先关闭您现有的问题。

void Main()
{
  using (var exportConnection = new SqlConnection(connectionString: "Data Source=Localhost;"
                                                                   + "Trusted_Connection=yes;"
                                                                   + @"connection timeout=30;"
                                                                   + @"database=001-CARL_V4"))

  // your importConnection was wrong
  using (var importConnection = new OleDbConnection(connectionString: @"Provider=vfpoledb.1;"
                                                               + @"data source=C:\Users\Joshua.cameron\Desktop\PCHomesImportTestBlank\PCHomesServer\DATABASE\pchomes.dbc"))

  using (SqlCommand exportCommand = new SqlCommand(@"select * from dbo.CARL_Owners", exportConnection))

  using (OleDbCommand importCommand = new OleDbCommand(@"INSERT INTO CLIENT (itle,Fname,Sname) VALUES (?,?,?)",
        importConnection))
  {
    // you shouldn't use an array in between
    // because if the data is large you would be unnecessarily
    // wasting memory. Instead fill the rows in VFP database 
    // as you read data from SQL with the reader.
    // IOW do the process streaming. Read -> insert 
    // You are doing: Read into an array -> insert from array 
    // (but erroneously attempting to read from the reader again)


    importCommand.Parameters.AddWithValue("Title", "");
    importCommand.Parameters.AddWithValue("Fname", "");
    importCommand.Parameters.AddWithValue("Sname", "");

    // Open connections to both
    exportConnection.Open();
    importConnection.Open();

    Console.WriteLine("Visual Foxpro connection open");
    new OleDbCommand(@"DELETE FROM CLIENT", importConnection).ExecuteNonQuery();

    Console.WriteLine("Writing to table");
    Console.ReadKey();


    // Initiate the reader to SQL
    var exportReader = exportCommand.ExecuteReader();

    // Start reading
    while (exportReader.Read())
    {
      // as you read rows from SQL, set the parameter values
      // I would suggest using (string)row["sourceColumn"]
      // style but reader.GetValue, reader.GetString(index)
      // would work as well - although not safe (what happens
      // if someone modifies the structure of the SQL table a bit?)

      // anyway set the values
      importCommand.Parameters["Title"].Value = exportReader.GetString(0);
      importCommand.Parameters["Fname"].Value = exportReader.GetString(1);
      importCommand.Parameters["Sname"].Value = exportReader.GetString(2);

      // insert into VFP
      importCommand.ExecuteNonQuery();
    }

    // done
    exportConnection.Close();
    importConnection.Close();
  }
}