【问题标题】:Syntax error (missing operator) in query expression in C# script task in SSISSSIS 中 C# 脚本任务中的查询表达式中的语法错误(缺少运算符)
【发布时间】:2022-02-21 09:19:23
【问题描述】:

我收到此错误:

System.Data.OleDb.OleDbException (0x80040E14):查询表达式 ''O'Brien','O'Brien'' 中的语法错误(缺少运算符)。

在 System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
在 System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
在 System.Data.OleDb.OleDbCommand.ExecuteCommandText(对象和执行结果)
在 System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior 行为,对象和执行结果)
在 System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior 行为,字符串方法)
在 System.Data.OleDb.OleDbCommand.ExecuteNonQuery()
在 ST_fc2b814c7d4843308992fd44a2168035.ScriptMain.Main()

这是我在 C# 脚本中使用此查询的代码:

string queryString = "SELECT * FROM " + SchemaName + "." + TableName + " with(nolock) WHERE mfid IN " + "('"+ MFID + "')" +" AND activeflag = 'Y' AND ga_id NOT IN ('DPN') ORDER BY EmpID, ga_id";

C# 脚本:

try
{
    // Declare Variables
    string MFID = Dts.Variables["User::MFID"].Value.ToString();
    string ExcelPROD =MFID + Dts.Variables["User::ExcelPROD"].Value.ToString();
    string FolderPath = Dts.Variables["User::FolderPath"].Value.ToString()+MFID+"\\";

    OleDbConnection Excel_OLE_Con = new OleDbConnection();
    OleDbCommand Excel_OLE_Cmd = new OleDbCommand();

    //Construct ConnectionString for Excel
    string connstring = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + FolderPath + ExcelPROD
                    + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"";

    // Drop Excel file if exists
    File.Delete(FolderPath + "\\" + ExcelPROD + ".xlsx");

    // Use ADO.NET Connection from SSIS Package to get data from table
    SqlConnection myADONETConnection = new SqlConnection();
    myADONETConnection = (SqlConnection)(Dts.Connections["PROD"].AcquireConnection(Dts.Transaction) as SqlConnection);

    string SchemaName = "dbo";
    string TableName = "MASTER_DATA_EMPLOYEE";

    // Load Data into DataTable from SQL ServerTable
    // Assumes that connection is a valid SqlConnection object.
    string queryString = "SELECT * FROM " + SchemaName + "." + TableName + " with(nolock) WHERE mfid IN ('" + MFID + "')" + " AND activeflag = 'Y' AND ga_id NOT IN ('DPN') ORDER BY EmpID,ga_id";

    SqlDataAdapter adapter = new SqlDataAdapter(queryString, myADONETConnection);

    DataSet ds = new DataSet();
    adapter.Fill(ds);

    //Get Header Columns
    string TableColumns = "";

    // Get the Column List from Data Table so can create Excel Sheet with Header
    foreach (DataTable table in ds.Tables)
    {
        foreach (DataColumn column in table.Columns)
        {
            TableColumns += column + "],[";
        }
    }

    // Replace most right comma from Columnlist
    TableColumns = ("[" + TableColumns.Replace(",", " Text,").TrimEnd(','));
    TableColumns = TableColumns.Remove(TableColumns.Length - 2);
    //MessageBox.Show(TableColumns);

    //Use OLE DB Connection and Create Excel Sheet
    Excel_OLE_Con.ConnectionString = connstring;
    Excel_OLE_Con.Open();
    Excel_OLE_Cmd.Connection = Excel_OLE_Con;
    Excel_OLE_Cmd.CommandText = "Create table [" + SchemaName + "_" + TableName + "] (" + TableColumns + ")";
    Excel_OLE_Cmd.ExecuteNonQuery();

    //Write Data to Excel Sheet from DataTable dynamically
    foreach (DataTable table in ds.Tables)
    {
        String sqlCommandInsert = "";
        String sqlCommandValue = "";

        foreach (DataColumn dataColumn in table.Columns)
        {
            sqlCommandValue += dataColumn + "],[";
        }

        sqlCommandValue = "[" + sqlCommandValue.TrimEnd(',');
        sqlCommandValue = sqlCommandValue.Remove(sqlCommandValue.Length - 2);
        sqlCommandInsert = "INSERT into [" + SchemaName + "_" + TableName + "] (" + sqlCommandValue + ") VALUES(";

        int columnCount = table.Columns.Count;

        foreach (DataRow row in table.Rows)
        {
            string columnvalues = "";

            for (int i = 0; i < columnCount; i++)
            {
                int index = table.Rows.IndexOf(row);
                columnvalues += "'" + table.Rows[index].ItemArray[i] + "',";
            }

            columnvalues = columnvalues.TrimEnd(',');

            var command = sqlCommandInsert + columnvalues + ")";
            Excel_OLE_Cmd.CommandText = command;
            Excel_OLE_Cmd.ExecuteNonQuery();
        }
    }

    Excel_OLE_Con.Close();
                
    Dts.TaskResult = (int)ScriptResults.Success;
}     

【问题讨论】:

  • 这就是为什么你应该总是使用参数的第一个原因;你能发现语法错误吗:SELECT * FROM Person WHERE Name = 'O'Brien'(如果不能,请将其粘贴到 SQL 语法高亮的地方,并仔细查看颜色)
  • This 是第二个原因。请访问bobby-tables.com,获取有关如何编写不受当今采用的最简单黑客方法之一影响的查询的建议
  • 停止使用nolock 溅出你的代码

标签: c# sql-server ssis sqlcommand script-task


【解决方案1】:

主要问题是在构建查询时使用的 MFID 变量包含一个引号,该引号用于 SQL Server 中的字符串文字。

System.Data.OleDb.OleDbException (0x80040E14):查询表达式 ''O'Brien','O'Brien'' 中的语法错误(缺少运算符)。

您可以通过参数化 SQL 命令来解决此问题。网上有很多教程和分步指南。举个例子:

由于您在IN () 子句中使用了MFID 变量,您可以参考以下答案来解决此问题:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 2018-09-02
    • 2018-01-29
    • 2012-11-14
    相关资源
    最近更新 更多