2017-02-24 40 views
6

寻找传递用户ID列表以返回列表名称。我有一个计划来处理输出的名字(用COALESCE的东西或其他),但试图找到传递用户ID列表的最佳方式。 我的存储过程的胆量将是这个样子:如何在存储过程中将列表作为参数传递?

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 

为@user_id_list传递的价值观是我这里主要关心的。

+5

我不会传入一个ID列表,我会创建一个用户定义的表类型,插入值,并将该变量传递给proc。然后,您可以对表格执行“JOIN”。 – Siyual

+1

试试看这里:http://stackoverflow.com/questions/7097079/c-sharp-sql-server-passing-a-list-to-a-stored-procedure –

+0

我同意表参数...其次我会使用一个字符串分离器和作为最后的手段...动态SQL。类似的问题刚刚发布[这里](http://stackoverflow.com/questions/42448333/using-a-string-which-comprises-of-values-in-a-query) – scsimon

回答

1

你可以试试这个:

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, ',')) 

这里是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 
+1

中使用'string_split',它们可能需要字符串分割功能..... – scsimon

+0

'dbo.SplitString'不是内部函数。 –

+1

这可能是您获得该类功能的速度最慢的。在这里查看一些其他选项:[以正确的方式分割字符串 - 或者下一个最好的方式 - 亚伦伯特兰](https://sqlperformance.com/2012/07/t-sql-queries/split-strings) – SqlZim

0

也许你可以使用:

select last_name+', '+first_name 
from user_mstr 
where ',' + @user_id_list + ',' like '%,' + convert(nvarchar, user_id) + ',%' 
14

的传球的首选方法SQL Server中存储过程的值数组是使用表值参数。

首先定义的类型是这样的:

CREATE TYPE UserList AS TABLE (UserID INT); 

然后使用该类型的存储过程:

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) 

所以你调用之前存储过程,你填一个表变量:

DECLARE @UL UserList; 
INSERT @UL VALUES (5),(44),(72),(81),(126) 

最后调用SP:

EXEC dbo.get_user_names @UL, @username OUTPUT; 
1

据我所知,有三个主要竞争者:表值参数,分隔列表字符串和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

,如果你有一个更结构化的数据集,以传递这可能是最好的可能是其架构显著变量。

TVPs似乎曾经是传递更多结构化参数的规范方式,如果您需要这种结构,显式和基本的值/类型检查,它们仍然很好。不过,它们在消费者方面可能会更麻烦一些。如果您没有2016+,这可能是默认/最佳选项。

我认为这是所有这些具体考虑之间的一种折衷,以及您偏好明确您的参数结构的含义,即使您拥有2016+,也可能更愿意明确指出类型/架构该参数而不是传递一个字符串并以某种方式解析它。

0

你可以使用这个简单的 '内联' 的方法来构造一个string_list_type参数(在SQL Server 2014工程):执行存储过程时

declare @p1 dbo.string_list_type 
insert into @p1 values(N'myFirstString') 
insert into @p1 values(N'mySecondString') 

使用例:

exec MyStoredProc @[email protected] 
0

我解决这个问题通过如下:

  1. 在C#中我建立了一个字符串变量。

string userId =“”;

  1. 我把列表中的项目放在这个变量中。我把','分开了。

例如:在C#

userId= "5,44,72,81,126"; 

和发送到SQL-服务器

SqlParameter param = cmd.Parameters.AddWithValue("@user_id_list",userId); 
  • 我创建SQL Server中的分隔函数用于转换我收到的L ist(它的类型是NVARCHAR(Max))。
  • 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 =项目FROM dbo.SplitInts(@user_id_list, '');

    相关问题