使用IN子句构建SSIS T-SQL表达式

时间:2014-10-31 15:15:52

标签: sql-server tsql ssis expression

想知道是否有人可以在这里提供帮助。我正在尝试构建一个动态T-SQL,以便在数据流任务中构建如下所示的内容

Select * 
from Table A 
where RecordID NOT IN (@objectvariable)

我创建了一个名为@objectvariable的变量作为对象,用于保存RecordID列表并设置SQL任务,并将结果集选项设置为"完整结果集"并映射结果集变量。

SQL任务成功执行并填充列表。

当我在数据流任务中使用此变量并构造T-SQL脚本时,我收到错误

  

变量的数据类型" User :: ProcessedData"表达式不支持。
  读取变量" User :: ProcessedData"失败,错误代码为0xC00470D0。

简而言之,我想构建像

这样的T-SQL
Select * 
from Table A 
where RecordID NOT IN (100,102,103) 

在数据流ado源任务中,通过使用变量来引入' IN'值。这可能吗?

非常感谢

1 个答案:

答案 0 :(得分:1)

最简单的解决方案是在原始数据源中生成逗号分隔的字符串值(使用您可以在StackOverflow和其他站点上找到的每个RDBMS供应商的许多值并置方法之一)。然后将其粘贴到String变量中并构建动态查询。

话虽如此,您还可以使用脚本任务将Recordset对象转换为逗号分隔的字符串。这是一个C#脚本,为您执行此操作(请参阅下面的使用说明代码):

#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Linq;

#endregion

namespace ST_75a10d235ce24be89bab80890dca9be9
{
    /// <summary>
    /// ScriptMain is the entry point class of the script.  Do not change the name, attributes,
    /// or parent of this class.
    /// </summary>
    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {
        public void Main()
        {

            OleDbDataAdapter da = new OleDbDataAdapter();
            DataTable dt = new DataTable();
            da.Fill(dt, Dts.Variables["User::ContractSet"].Value);
            Dts.Variables["User::ContractValues"].Value = String.Join(",", dt.AsEnumerable().Select(r => r.Field<string>("contract")).ToArray());

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

        #region ScriptResults declaration
        /// <summary>
        /// This enum provides a convenient shorthand within the scope of this class for setting the
        /// result of the script.
        /// 
        /// This code was generated automatically.
        /// </summary>
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

    }
}
  • 在包中创建两个变量,一个Object(示例中为User :: ContractSet)和一个String(User :: ContractValues)。
  • 在脚本任务中将User :: ContractSet设置为ReadVariable,将User :: ContractValues设置为ReadWriteVariable。
  • 请注意,您必须在LINQ选择查询中设置您从Recordset连接的字段名(在示例中为“合同”。)
  • 此脚本需要对System.Data.DataSetExtensions和System.Linq程序集的引用。

在数据流填充User :: ContractSet之后放置此任务,然后User :: ContractValues将有一个逗号分隔列表,您可以使用它来构建动态查询。