2017-06-16 71 views
2

我有一些SQL通过盲目需求/请求转换为存储过程。在我看到的应用程序中有一点SQL使用动态IN(set)语句构建where子句。我已经搜索了动态存储过程,但没有接近我正在寻找的东西对我来说。这里是WHERE子句的示例:如何使用动态创建的IN集创建存储过程

WHERE Var.A = @Param AND Var.Id IN 

从这里SQL是使用字符串生成器手动构建的,然后执行。不知道如何将它转换为存储过程,因为我对它们相当陌生。

我们正在使用C#和SQL Server

+2

如何将用户定义的表格类型从C#发送到proc? – hardkoded

+0

这听起来不错。但我不知道这意味着什么。我会研究这个角度。谢谢大声笑 – Matt1776

+0

@ Matt1776:根据各种因素,IN子句可以是从良性到病态的不良表现。由于IN子句的目的是过滤返回的行,INNER JOIN子句也是这样做的(除了引入额外的列之外),执行INNER JOIN而不是IN会比较好,而且往往会更好。 (回想一下,INNER JOIN只返回两个表中匹配连接字段的行。) –

回答

3

您可以使用用户定义的数据类型。

在C#方面,它应该是这样的:

//Setup a DataTable with the same structure as the SQL Type 
var data = new DataTable(); 
data.Columns.Add("value", typeof(string)); 

//Populate the table 
data.Rows.Add("oneID"); 
data.Rows.Add("anotherID"); 

//You create your sql command 
cmd.Parameters.Add("@listArgument", data); 
//Command execution 

SQL一边,你可以有一种这样的

CREATE TYPE [dbo].[NVarCharTable] AS TABLE (
    [value] NVARCHAR(MAX) NOT NULL); 

然后存储过程:

CREATE PROCEDURE [dbo].[MyProc] 
    @listArgument NVarCharTable READONLY 
AS 
BEGIN 

    SELECT * 
    FROM FOO 
    WHERE Var.Id IN (Select [value] FROM @listArgument) 

END 

参考:https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/table-valued-parameters

+0

这是......很美。这看起来类似于创建临时视图,但这被称为用户定义的表类型?我会看看这是否有效! – Matt1776

+1

我已经添加了一个引用链接来阅读,我使用DataTables,但有很多方法使用它从C# – hardkoded

+0

我有一个时间让这个工作老实说 - 这绝对是由于我缺乏经验用这种方法。当我在SQL Server中执行存储过程时,如何设置[NVarCharTable]的值?它只给我一个窗口界面,我不能写SQL – Matt1776

1

如果您使用的是SQl SERVER 2016或更高版本,则可以使用string_split函数将csv参数转换为表格,然后将其用于您的IN列表中。

SELECT * FROM TBL WHERE Var.A = @Param AND Var.Id IN (SELECT value FROM STRING_SPLIT(@inlist, ',')) 

希望这有助于

+0

唉,我们被锁定到SQLServer 2012,但是这看起来像一个有效的,更简单的选项,因为split会返回一个表。尝试一下会很好。 – Matt1776

+0

有那么多的函数需要一个值列表并分解到一个表中。只是Google它 - sql server central至少有3个版本。所以这种方法在其他版本中也是可行的,只需要添加1个函数。 – Jesse

+0

@Jesse经过一些粗略的研究我只找到一种方法来创建一个调用dll的函数 - 你有什么具体的想法吗?仔细阅读SQLServer文档后,我没有看到任何可以使用的东西,这不会太繁重。 – Matt1776