存储过程中 EXISTS 子句的参数
本文关键字:参数 子句 EXISTS 存储过程 过程中 存储 | 更新日期: 2023-09-27 18:35:11
我有一个表格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# 代码中,创建一个数据表,用 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;
...
}
您还可以使用拆分功能。许多存在,如果你能保证输入是安全的(没有<,>等),这就是我喜欢的:
CREATE FUNCTION dbo.SplitInts_XML
(
@List VARCHAR(MAX),
@Delimiter CHAR(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT Item = y.i.value('(./text())[1]', 'int')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>') + '</i>').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