我想不使用光標像這樣的東西在一個集中的每一行執行存儲過程:
SELECT EXEC dbo.Sproc @Param1 = Table1.id
FROM Table1
我使用T-SQL在SQL Server 2005,我認爲這可能是可能使用的功能,但我想盡可能使用存儲過程(公司標準)是否可以在不使用遊標的情況下對集合執行存儲過程?
回答
9的10倍,你可以做你想要的,沒有光標或一個while循環。但是,如果你必須使用一個,我發現雖然循環往往更快。
此外,如果你不想刪除或更新表,你可以使用這樣的事情:
DECLARE @id [type]
SELECT @id = MIN([id]) FROM [table]
WHILE @id IS NOT NULL
BEGIN
EXEC [sproc] @id
SELECT @id = MIN([id]) FROM [table] WHERE [id] > @id
END
是的。如果你有一列可以在表中使用,以紀念那些處理後,您可以使用,而存在:
DECLARE @Id int
WHILE EXISTS(SELECT * FROM Table1 WHERE Processed='N')
BEGIN
SELECT Top 1 @Id = id from Table1 WHERE Procesed='N'
EXEC dbo.Sproc @Id
UPDATE Table1 SET Processed = 'Y' WHERE Id = @Id
END
或者,傾倒的ID到一個臨時表或表變量並刪除完成後:
DECLARE @HoldTable table (Id int PRIMARY KEY)
DECLARE @Id int
INSERT INTO @HoldTable SELECT Id FROM Table1
WHILE EXISTS(SELECT * FROM @HoldTable)
BEGIN
SELECT @Id = id from @HoldTable
EXEC dbo.Sproc @Id
DELETE FROM @HoldTable where Id = @Id
END
編輯你的第二個答案。您選擇的是@Id而不是@HoldTable,並且您有where子句,其中'processed ='N'`但是@HoldTable沒有這樣的列。第二個選項現在應該可以工作。我希望我能正確理解你的意圖。 – kralco626 2015-02-24 19:51:49
坦率地說,如果我需要執行一個存儲過程的一組數據,而不是當一個記錄它是寫的,我會寫基於集合的代碼,而不是使用存儲的過程。如果要針對大型數據集運行,這是執行此操作的唯一有效方法。您可以從幾個小時開始執行存儲過程所執行的插入,即秒或甚至毫秒。當您需要處理一組數據時,尤其不要使用基於記錄的處理,尤其是不要重複使用代碼等愚蠢的原因。性能勝過代碼的重用。
如果可能,我會寫一個從臨時表中讀取的存儲過程的第二個版本。
如果這不可能比你可能運氣不好。
如果您只使用SQL Server 2005或更新版本,不關心向後兼容性,並且可以將您的代碼轉換爲用戶定義函數(而不是存儲過程),那麼您可以使用新的「 CROSS APPLY「運算符,它使用的語法非常類似於你想要的。我發現here短的介紹(當然,你也可以閱讀波士和MSDN)
假設你的SP返回名爲out_int一個值,你的例子可以寫成:
SELECT T.id, UDF.out_int
FROM
Table1 T
CROSS APPLY
dbo.fn_My_UDF(T.id) AS UDF
這將從Table1中檢索每個「id」並使用它來調用fn_My_UDF,其結果將顯示在除原始參數之外的最終結果集中。
「CROSS APPLY」的變體是「OUTER APPLY」。它們是「INNER JOIN」和「LEFT JOIN」的等價物,但是加入表和UDF(並同時調用第二個)。
如果你必須(按照尖頭髮老闆的明確命令)使用SP insead,好運氣!你必須保留光標,或嘗試作弊:將代碼改爲UDF,並創建包裝SP:D。
這個循環有效,但對我的SP來說很慢。我認爲HLGEM的正確答案是,您最好的辦法是編寫一個更好的批量查詢。
DECLARE @id INT
SET @id = 0
DECLARE @max INT
SELECT TOP 1 @max = TableID
FROM dbo.Table
ORDER BY TableID desc
-- loop until BREAK
-- this is how you can perform a DO-WHILE loop in TSQL
WHILE (1 = 1)
BEGIN
SELECT
TOP 1 @id = TableID
FROM dbo.Table
WHERE TableID > @id
IF @id IS NOT NULL
BEGIN
-- call you SP here
PRINT @id
END
-- break out of the loop once the max id has been reached
IF @id = @max BREAK
END
- 1. Redis:是否可以在不使用集合的情況下獲取值?
- 2. 是否可以在不使用存儲過程或函數的情況下生成X行?
- 3. 是否可以使用存儲過程執行sql注入?
- 4. 是否可以在不使用pick方法的情況下存儲文件?
- 5. 是否可以在不使用POJO的情況下從MyBatis調用MySQL存儲過程?
- 6. 是否可以在不使用debugfs的情況下使用ftrace?
- 7. 是否可以在不使用Rails的情況下使用FactoryGirl?
- 8. 如何在不使用遊標的情況下調用表中每行的參數化存儲過程
- 9. 用遊標存儲過程以奇怪的方式執行
- 10. 是否可以在不拖放的情況下使用Linq-SQL?
- 11. 是否可以在不使用isNaN的情況下檢測NaN?
- 12. 是否可以在不渲染HTML的情況下使用React?
- 13. 執行現有存儲過程以在不使用openrowset的情況下填充SQL Server 2008 R2中的新表
- 14. 是否可以將表名傳遞給存儲過程並在沒有Exec函數的情況下使用它?
- 15. 是否可以在不打開excel的情況下運行datanitro
- 16. 是否可以執行Insert Into存儲過程?
- 17. 如何使用遊標從表中執行存儲過程?
- 18. 在下列情況下,我可以使用存儲過程而不是觸發器嗎?
- 19. 是否可以在不發佈的情況下執行Web.config轉換?
- 20. 是否可以調用存儲過程?
- 21. 是否可以在沒有遊標的情況下檢查sqlite值? - Android
- 22. 我可以在不使用遊標的情況下在SQL函數中執行此操作嗎?
- 23. 是否可以在不使用數據結構的情況下存儲和訪問對象實例?
- 24. 在Sql Server中審計存儲過程的執行情況
- 25. 針對存儲過程的情況?
- 26. 是否可以在不使用OnGUI的情況下創建文本標籤?
- 27. 制式的情況下,不可儲存
- 28. 是否可以在不禁用JavaScript的情況下禁用AJAX?
- 29. 是否可以在不使用CSS3的情況下旋轉HTML對象?
- 30. 批處理文件執行是否可以在不完成java進程的情況下逐步執行?
這完全正確嗎?你可以通過id命令而不指定group by子句嗎? – 2010-06-25 16:12:43
它不適用。閱讀最大ID後它不會停止。 – 2011-03-31 22:42:10
-1不起作用。正如理查德科萊特所說,選擇語法被破壞。如果你修正了這個語法,那麼就像Tony_Henrich指出的那樣,它陷入了一個無限循環中)。我添加了一個有工作循環的答案,但是我的經驗很慢。 – 2012-04-17 17:31:43