[英]SQL - Is there a better way of passing a list of keys, for use in a where clause, into a Stored Procedure?
這是場景; 我有一個與OrderIds相關的CustomerIds (1,2,3) 列表 。 我有一個存儲過程Delete_OrdersByCustomerIds
,它刪除與指定的CustomerIds相關的所有訂單。
目前,我這樣做的方法是將CustomerIds連接成一個字符串,即“1,2,3”。 然后我將此字符串傳遞給我的存儲過程並使用以下函數創建一個我可以加入的Int表:
CREATE FUNCTION [dbo].[iter$simple_intlist_to_tbl] (@list nvarchar(MAX))
RETURNS @tbl TABLE (number int NOT NULL) AS
BEGIN
DECLARE @pos int,
@nextpos int,
@valuelen int
SELECT @pos = 0, @nextpos = 1
WHILE @nextpos > 0
BEGIN
SELECT @nextpos = charindex(',', @list, @pos + 1)
SELECT @valuelen = CASE WHEN @nextpos > 0
THEN @nextpos
ELSE len(@list) + 1
END - @pos - 1
INSERT @tbl (number)
VALUES (convert(int, substring(@list, @pos + 1, @valuelen)))
SELECT @pos = @nextpos
END
RETURN
END
然后,我只是執行DELETE FROM Orders WHERE CustomerId IN iter$simple_intlist_to_tbl(@CustomerIds).number
。 (語法可能不在這里,我在大聲思考。)
我不禁覺得這很糟糕 。 是否有更好的方法來實現同樣的目標? 我不想自己構建SQL語句,我目前正在使用標准的.Net ADO包裝器。
綜觀其他問題,即這一個 ,看來我的方法是可以接受的,所以這是做在SQL 2005的唯一途徑?
使用XML將數組傳遞給STP。 例:
CREATE PROC myProc
(
@list AS XML
)
AS
(
SELECT items.item.value('.', 'VARCHAR(MAX)') AS Item
FROM @list.nodes('list/item') items(item)
)
打電話給STP:
myProc '<list><item>a</item><item>b</item></list>'
@Tom:可以在這里找到性能評估
主要的教訓是,除非您願意使用CLR代碼,否則XML是最快的方法:
在我的測試中,XML的執行時間比CLR高40-60%,但它的速度是迭代方法的兩倍。 事實上,XML是最快的方法,不需要在服務器中做任何准備
如果您使用SQL 2008,您可以通過在表中作為參數傳遞給存儲過程,如解釋在這里
在早期版本的SQL中,常見的方法是您已經擁有的,或者傳遞一個CSV字符串以在LIKE子句中使用(我不會證明,因為我不會特別推薦這種方法)。
我使用XML列表。
我使用這種存儲過程:
CREATE PROCEDURE [dbo].[GetUsersInList]
@UserList nvarchar(MAX)
AS
BEGIN
DECLARE @DocHandle int
DECLARE @UsersListTable table (
[UserID] bigint
)
EXEC sp_xml_preparedocument @DocHandle OUTPUT, @UserList
INSERT INTO
@UsersListTable ([UserID])
SELECT
doc.Value [UserID]
FROM
OPENXML(@DocHandle, '/List/Item', 1) WITH ([Value] int) doc
EXEC sp_xml_removedocument @DocHandle
SELECT
*,
IsNull(cast(TechID as varchar) + ' - ' + DisplayName, DisplayName) [FriendlyName]
FROM
dbo.[Users]
WHERE
[ID] IN (SELECT [UserID] FROM @UsersListTable)
END
要創建此類列表:
var list =
new XElement("List",
users.Select(user =>
new XElement("Item", new XAttribute("Value", user.Id))
)
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.