sha*_*011 31 sql sql-server stored-procedures
希望传递用户ID列表以返回列表名称.我有计划处理输出的名称(使用COALESCE或其他东西),但试图找到传递用户ID列表的最佳方法.我的sproc的内容看起来像这样:
create procedure [dbo].[get_user_names]
@user_id_list, --which would equal a list of incoming ID numbers like (5,44,72,81,126)
@username varchar (30) output
as
select last_name+', '+first_name
from user_mstr
where user_id in @user_id_list
Run Code Online (Sandbox Code Playgroud)
传递@user_id_list的值是我的主要关注点.
Mat*_*tum 38
将值数组传递给SQL Server中的存储过程的首选方法是使用表值参数.
首先,您定义这样的类型:
CREATE TYPE UserList AS TABLE ( UserID INT );
Run Code Online (Sandbox Code Playgroud)
然后在存储过程中使用该类型:
create procedure [dbo].[get_user_names]
@user_id_list UserList READONLY,
@username varchar (30) output
as
select last_name+', '+first_name
from user_mstr
where user_id in (SELECT UserID FROM @user_id_list)
Run Code Online (Sandbox Code Playgroud)
因此,在调用该存储过程之前,请填充表变量:
DECLARE @UL UserList;
INSERT @UL VALUES (5),(44),(72),(81),(126)
Run Code Online (Sandbox Code Playgroud)
最后打电话给SP:
EXEC dbo.get_user_names @UL, @username OUTPUT;
Run Code Online (Sandbox Code Playgroud)
Amb*_*tle 13
据我所知,有三个主要的竞争者:表值参数,分隔列表字符串和JSON字符串.
自2016年起,如果您想要分隔的路线,可以使用内置的STRING_SPLIT:https://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql
这可能是最简单/最简单/最简单的方法.
此外,自2016年起,JSON可以作为nvarchar传递并与OPENJSON一起使用:https://docs.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql
如果你有一个更结构化的数据集可以在其模式中显着变化,那么这可能是最好的.
TVP似乎曾经是传递更多结构化参数的规范方法,如果您需要结构,显式性和基本值/类型检查,它们仍然很好.不过,它们在消费者方面可能会稍微麻烦一些.如果您没有2016+,这可能是默认/最佳选择.
我认为这是在任何这些具体考虑因素之间的权衡,以及您对明确的params结构的偏好,这意味着即使您有2016+,您可能更愿意明确说明参数的类型/模式而不是传递一个字符串并以某种方式解析它.
从 Azure DB、Azure Data WH 和 SQL Server 2016 开始,您可以使用 STRING_SPLIT 来实现与 @sparrow 所描述的类似的结果。
从@sparrow 回收代码
WHERE user_id IN (SELECT value FROM STRING_SPLIT( @user_id_list, ',')
Run Code Online (Sandbox Code Playgroud)
将值列表接受到存储过程中的简单有效的方法
我通过以下方法解决了这个问题:
字符串userId =“”;
例如:在C#中
Run Code Online (Sandbox Code Playgroud)userId= "5,44,72,81,126";
并发送到SQL-Server
Run Code Online (Sandbox Code Playgroud)SqlParameter param = cmd.Parameters.AddWithValue("@user_id_list",userId);
NVARCHAR(Max))转换为表。Run Code Online (Sandbox Code Playgroud)CREATE FUNCTION dbo.SplitInts ( @List VARCHAR(MAX), @Delimiter VARCHAR(255) ) RETURNS TABLE AS RETURN ( SELECT Item = CONVERT(INT, Item) FROM ( SELECT Item = x.i.value('(./text())[1]', 'varchar(max)') FROM ( SELECT [XML] = CONVERT(XML, '<i>' + REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.') ) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y WHERE Item IS NOT NULL );
SELECT user_id =来自dbo.SplitInts(@user_id_list,',');的项目
你可以试试这个:
create procedure [dbo].[get_user_names]
@user_id_list varchar(2000), -- You can use any max length
@username varchar (30) output
as
select last_name+', '+first_name
from user_mstr
where user_id in (Select ID from dbo.SplitString( @user_id_list, ',') )
Run Code Online (Sandbox Code Playgroud)
这是 SplitString 的用户定义函数:
Create FUNCTION [dbo].[SplitString]
(
@Input NVARCHAR(MAX),
@Character CHAR(1)
)
RETURNS @Output TABLE (
Item NVARCHAR(1000)
)
AS
BEGIN
DECLARE @StartIndex INT, @EndIndex INT
SET @StartIndex = 1
IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
BEGIN
SET @Input = @Input + @Character
END
WHILE CHARINDEX(@Character, @Input) > 0
BEGIN
SET @EndIndex = CHARINDEX(@Character, @Input)
INSERT INTO @Output(Item)
SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)
SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
END
RETURN
END
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
68602 次 |
| 最近记录: |