SQL Server 2014存储过程修改:支持接收多个Int类型ID参数
嘿,针对你在SQL Server 2014里要让存储过程接收多个ID的需求,我给你几个实用的方案——毕竟2014还没自带STRING_SPLIT函数,得换点合适的路子:
方案1:表值参数(TVP)——最推荐的类型安全方案
这是SQL Server里处理多值参数最规范的方式,类型安全还能保证性能,尤其适合传递大量ID的场景。
首先你得先创建一个表类型,用来承载多个ID:
CREATE TYPE dbo.IntList AS TABLE (Id INT); GO
然后修改你的存储过程,让它接收这个表类型参数:
ALTER PROCEDURE [dbo].[GetProductsById] @ids dbo.IntList READONLY -- 表值参数必须标记为READONLY AS BEGIN SET NOCOUNT ON; -- 两种查询方式任选,JOIN的性能通常更优 SELECT p.* FROM Products p JOIN @ids i ON p.ProductId = i.Id; -- 或者用IN子句: -- SELECT * -- FROM Products -- WHERE ProductId IN (SELECT Id FROM @ids); END GO
调用的时候,你只需要先把ID插入到表变量里,再传给存储过程:
DECLARE @idList dbo.IntList; INSERT INTO @idList VALUES (1), (3), (5), (7); -- 可以随便加多少个ID EXEC dbo.GetProductsById @ids = @idList;
方案2:XML参数——无需额外创建对象的灵活方案
如果不想预先创建表类型,用XML来传递多值也是个不错的选择,不用额外维护对象。
修改后的存储过程如下:
ALTER PROCEDURE [dbo].[GetProductsById] @idsXml XML AS BEGIN SET NOCOUNT ON; SELECT * FROM Products WHERE ProductId IN ( -- 解析XML里的每个ID节点 SELECT x.value('.', 'INT') FROM @idsXml.nodes('/Ids/Id') AS T(x) ); END GO
调用的时候直接传XML格式的字符串就行:
EXEC dbo.GetProductsById @idsXml = '<Ids><Id>2</Id><Id>4</Id><Id>6</Id></Ids>';
方案3:自定义字符串拆分函数——适合简单场景的轻量方案
如果习惯用逗号分隔的字符串传参数,你可以写一个自定义的拆分函数,把字符串拆成单个ID的表,再用于查询。
先创建这个表值拆分函数:
CREATE FUNCTION dbo.SplitInts(@List VARCHAR(MAX)) RETURNS TABLE AS RETURN ( WITH Numbers AS ( -- 生成足够多的数字,用来拆分字符串 SELECT TOP (LEN(@List) - LEN(REPLACE(@List, ',', '')) + 1) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N FROM sys.all_columns -- 用系统表生成数字,不用自己建表 ) SELECT -- 截取每个逗号分隔的部分并转成INT CONVERT(INT, SUBSTRING(@List, N, CHARINDEX(',', @List + ',', N) - N)) AS Id FROM Numbers ); GO
然后修改存储过程接收字符串参数:
ALTER PROCEDURE [dbo].[GetProductsById] @ids VARCHAR(MAX) -- 比如"1,3,5,7"这样的逗号分隔字符串 AS BEGIN SET NOCOUNT ON; SELECT * FROM Products WHERE ProductId IN (SELECT Id FROM dbo.SplitInts(@ids)); END GO
调用的时候直接传逗号分隔的ID字符串:
EXEC dbo.GetProductsById @ids = '1,3,5,7';
各方案优缺点对比
- 表值参数:类型安全、性能最优,适合大量ID传递,完全避免SQL注入风险,但需要预先创建表类型,稍显麻烦。
- XML参数:无需额外创建对象,格式灵活,适合临时需求,但XML解析的性能略逊于表值参数。
- 自定义拆分函数:调用简单直观,不用改太多代码,但要注意输入字符串的格式正确性,若参数来自不可信来源,存在SQL注入风险,ID数量多的时候性能不如前两者。
内容的提问来源于stack exchange,提问作者Chatra
相关产品推荐
相关产品推荐

