将逗号分隔值转换为子查询

时间:2016-10-03 13:40:17

标签: sql sql-server-2008-r2

我有以下查询:

Set @OrderStatuses = 'Cancelled,Complete'  

Select * 
From TableName  
Where Status in (@OrderStatuses)

Status是我在外部收到的,它无法获取任何结果,因为我们实际需要处理的是:

Select * 
From TableName  
Where Status in ('Cancelled', 'Complete');

@OrderStatuses可以包含任意数量的以逗号分隔的值。

3 个答案:

答案 0 :(得分:2)

一种方法是动态SQL:

declare @sql nvarchar(max);

set @sql = 'Select * from TableName Where Status in (@list)';

set @sql = replace(@sql, '@list', '@OrderStatuses');

exec sp_executesql @sql;

注意:您不能将列表作为参数传递。

您还可以使用like

Select *
from TableName
Where ',' + @OrderStatuses + ',' like '%,' + Status + ',%';

但是,这不能使用索引进行比较。

答案 1 :(得分:1)

您需要使用split string function并处理其余的事情..

;with cte
as
(
select * from split_strings(@orderstatus,',')
)
select * from table where status in (select item from cte)

答案 2 :(得分:1)

您必须将列表添加为Table-Valued Parameter

以下是我用来将任何IEnumerable项目列表(在本例中为整数)转换为表值参数的两种方法。您必须为数据库中的结果表创建/定义用户定义类型(UDT)。在下面的示例中,UDT名为dbo.keyIds,并使用此SQL创建(一次):

CREATE TYPE [dbo].[KeyIds] 
AS TABLE(pkId int NOT NULL, PRIMARY KEY CLUSTERED 
   ( [pkId] ASC) WITH (IGNORE_DUP_KEY = OFF)
 )

c#代码是:

public class DbParamList : List<IDbDataParameter>
{ 
    public void AddSQLTableParm<T>(
                string parmName, IEnumerable<T> values)
    {
        var parm = new SqlParameter(parmName, CreateDataTable(values))
        {
            SqlDbType = SqlDbType.Structured,
            TypeName = "dbo.keyIds"
        };
        Add(parm);
    }
    internal static DataTable CreateDataTable<T>(IEnumerable<T> values)
    {
        var dt = new DataTable();
        var props = typeof (T).GetProperties();
        if (props.Length > 0)
        {
            foreach (var col in props)
                dt.Columns.Add(col.Name, col.PropertyType);
            foreach (var id in values)
            {
                var newRow = dt.NewRow();
                foreach (var prop in id.GetType().GetProperties())
                    newRow[prop.Name] = prop.GetValue(id, null);
                dt.Rows.Add(newRow);
            }
        }
        else
        {
            dt.Columns.Add("ids");
            foreach (var id in values) dt.Rows.Add(id);
        }
        return dt;
    }
}