导致此语法错误的原因是什么? oledb INSERT语句

时间:2016-03-09 14:27:52

标签: c# syntax-error visual-foxpro

我发布了一个我之前遇到过的另一个问题,并通过一些帮助解决了这个问题。

我现在收到以下代码为中心的语法错误:

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

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

这是输出:

Output Text

使用断点我已确定导出阅读器调用正在接收数据。我已将其缩小到以下问题:

"VALUES ({0},{1},{2})",
  exportReader.GetValue(0), exportReader.GetValue(1), exportReader.GetValue(2))))

我已确认可以通过执行以下操作插入数据:

using (OleDbCommand importCommand =
    new OleDbCommand(string.Format(
       "INSERT INTO CLIENT (Title,Fname,Sname)" + "VALUES (Mr,Joshua,Cameron-Mackintosh)",
           importConnection)))

这没有问题,所以我知道问题不在于底层连接或命令。

4 个答案:

答案 0 :(得分:3)

其他正确评论SQL注入,但VFP对SQL注入的影响较小,它可以是相同的。主要原因,VFP并不真正使用多个查询,就像其他sql引擎允许的那样“;”识别语句之间的中断。但是,如果引号不匹配,则CAN和WILL会破坏实际运行的sql语句。

话虽如此,VFP OleDb提供程序确实允许参数化,但没有“命名”参数。它用“?”做到了作为.net框架将插入值的占位符,只要它具有相同的预期格式(例如:字符串,数字,日期),就不必转换数据类型

将OleDbCommand更改为

"INSERT INTO CLIENT (Title, Fname, Sname ) values ( ?, ?, ? )"

然后,通过

设置参数
importCommand.Parameters.Add( "parmForTitle", exportReader.GetValue(0));
importCommand.Parameters.Add( "parmForFName", exportReader.GetValue(1));
importCommand.Parameters.Add( "parmForSName", exportReader.GetValue(2));

此外,必须以与查询中显示的顺序完全相同的顺序添加参数。所以,我用“parmFor”作为前缀,表示它是插入(或更新,或用于select,insert或delete)的相应字段的参数位置。命令对象对所有命令的工作方式相同。即使你编写了一个select语句,并且在WHERE,JOIN或其他任何位置都有值。

那么,ExecuteNonQuery()

答案 1 :(得分:1)

  1. 那里有“foxpro连接字符串”。如果完成了 一个VFP数据库,然后“截断表客户端”将不起作用 第一名。 VFP中不存在该命令。相反,你可以 尝试使用“从客户端删除”,标记要删除的记录。 或者你可以使用与execSript相对应的“zap”命令 “truncate table”但是连接需要使用该表 独占。
  2. 您应该引用字符串值。更好的是,对于任何SQL操作,您都应该使用参数。使用参数时,应该以正确的方式为您使用的连接执行此操作。在这里你使用的是OLEDB连接,那么你应该使用?作为参数占位符。
  3. 您的代码的修订版将是:

    importConnection.Open();
    Console.WriteLine("Foxpro connection open");
    OleDbCommand deleteOleDbCommand = new OleDbCommand(@"Delete from CLIENT",
                                importConnection);
    
    Console.WriteLine("writing to table");
    Console.ReadKey();
    using (OleDbCommand importCommand = new OleDbCommand(
        @"INSERT INTO CLIENT (Title,Fname,Sname) VALUES (?,?,?)",
        importConnection))
    {
      importCommand.Parameters.AddWithValue("title","");
      importCommand.Parameters.AddWithValue("fname","");
      importCommand.Parameters.AddWithValue("sname","");
    
      // maybe in a loop here
      importCommand.Parameters["title"].Value = exportReader.GetValue(0);
      importCommand.Parameters["fname"].Value = exportReader.GetValue(1);
      importCommand.Parameters["sname"].Value = exportReader.GetValue(2);
    
      importCommand.ExecuteNonQuery();
      // ...
    }
    

    PS:你可以直接输入Parameters.AddWithValue上的值,而不是创建一个单独的.Parameters [“...”]。值= ...但是你只能在单个插入时这样做(不是与VFP相关的东西,就是OleDb或Sql或其他什么东西)。

答案 2 :(得分:0)

您不需要ExecuteReader来插入声明。只需使用ExecuteNonQuery

在您的情况下,如果您的列是字符类型,则需要使用单引号;例如

VALUES ('{0}', '{1}', '{2}')

VALUES部分之前也使用空白区域(不必,但作为良好做法)。

"INSERT INTO CLIENT (Title,Fname,Sname)" + " VALUES (Mr,Joshua,Cameron-Mackintosh)",
                                       //  ^^^ here

但更重要的是;

您应始终使用parameterized queries。例如,Prepared语句自动处理转义字符,并且这种字符串连接对SQL Injection攻击是开放的。

答案 3 :(得分:0)

您必须为连接的字符串留出空间。

"INSERT INTO CLIENT (Title,Fname,Sname)" + "[space here]VALUES (Mr,Joshua,Cameron-Mackintosh)"
然而,它应该是这样的:

"INSERT INTO CLIENT (Title,Fname,Sname) VALUES (?,?,?)"

始终使用参数化查询。请参阅: http://blogs.technet.com/b/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx