2017-02-24 67 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, '');

    相關問題