存储过程中EXISTS子句的参数

我有一个表DEPT ,它包含2列 – ID, NAME

将使用DEPT表中的ID显示搜索表单,用户可以选择任意数量的ID并提交表单,以获取相关的NAMEs

澄清/输入:

  • 我不想构建动态查询 – 它不可管理。
  • 我更喜欢使用表值参数的存储过程

还有其他解决办法吗?

注意:
这个例子很简单,只有1个表 – 在现实生活中,我必须处理超过6个表!

谢谢你的任何建议

 CREATE TYPE dbo.DeptList AS TABLE ( ID INT ); GO CREATE PROCEDURE dbo.RetrieveDepartments @dept_list AS dbo.DeptList READONLY AS BEGIN SET NOCOUNT ON; SELECT Name FROM dbo.table1 WHERE ID IN (SELECT ID FROM @dept) UNION ALL SELECT Name FROM dbo.table2 WHERE ID IN (SELECT ID FROM @dept) -- ... END GO 

现在在您的C#代码中,创建一个DataTable,用ID填充它,并将其传递给存储过程。 假设您已经有一个名为tempList的列表,并且ID存储在id中:

 DataTable tvp = new DataTable(); tvp.Columns.Add(new DataColumn("ID")); foreach(var item in tempList) { tvp.Rows.Add(item.id); } using (connObject) { SqlCommand cmd = new SqlCommand("StoredProcedure", connObject); cmd.CommandType = CommandType.StoredProcedure; SqlParameter tvparam = cmd.Parameters.AddWithValue("@dept_list", tvp); tvparam.SqlDbType = SqlDbType.Structured; ... } 

您还可以使用拆分function。 许多存在,如果你能保证输入是安全的(没有<,>,等等),这就是我喜欢的:

 CREATE FUNCTION dbo.SplitInts_XML ( @List VARCHAR(MAX), @Delimiter CHAR(1) ) RETURNS TABLE AS RETURN ( SELECT Item = yivalue('(./text())[1]', 'int') FROM ( SELECT x = CONVERT(XML, '' + REPLACE(@List, @Delimiter, '') + '').query('.') ) AS a CROSS APPLY x.nodes('i') AS y(i) ); GO 

现在你的程序可以是:

 CREATE PROCEDURE dbo.RetrieveDepartments @dept_list VARCHAR(MAX) AS BEGIN SET NOCOUNT ON; ;WITH d AS (SELECT ID = Item FROM dbo.SplitInts(@dept_list, ',')) SELECT Name FROM dbo.table1 WHERE ID IN (SELECT ID FROM d) UNION ALL SELECT Name FROM dbo.table2 WHERE ID IN (SELECT ID FROM d) -- ... END GO