2009-02-25 42 views
6

OK,我知道這是可以做到的,我這樣做很多時候,但爲什麼這麼難做到在T-SQL的循環?我可以想到很多我想通過查詢結果集解析的原因,並且做一些無法在沒有循環的情況下完成的任務,但是設置和執行我的循環的代碼大於20行。爲什麼會這樣很難做一個循環,T-SQL

我相信其他人也有類似的看法,爲什麼是我們仍然沒有進行一個循環的簡單方法?

旁白:我們終於在SQL2008有一個UPSERT(又名合併),所以也許所有的希望都不會丟失。

回答

22

SQL是一組爲基礎的,declarative language;不是程序性的或imperative language。 T-SQL試圖跨越這兩者,但它仍建立在基於集合的基礎範式之上。

+0

你有這些正確的方法嗎? – AnthonyWJones 2009-02-25 21:51:59

+0

哎呀!你是對的,我粘貼我的鏈接在錯誤的順序:)謝謝 – 2009-02-25 21:52:46

1

因爲SQL是基於集合的語言。 sql的強大功能是根據特定的特性在更大的數據組中找到一個較小的組。爲了處理這個任務,循環是很不必要的。顯然,它是爲了方便處理某些情況而添加的,但是該語言的預期用途使此功能無關緊要。

2

T-SQL的設計不是命令式語言。其設計是聲明性的。它的聲明性特性允許optomizer分割各種任務並平行運行它們,並以其他方式按照最有效的順序執行操作。

-2

我不是數據庫的專家,但我相信數據庫事務的原子性將使得難以實現循環,因爲該交易是完全的或不應該出現在所有。保持狀態可以討厭!

Wikipedia Article on Atomicity

0

SQL是一種基於SET系統,而不是程序(循環)之一。通常,它被認爲是在SQL中使用循環的不好的做法,因爲它們與基於集合的等價物相比性能不佳。

WHILE是最常見的循環結構,光標也可以使用,但有自己的問題(忘記解除分配/關閉)

... WHILE的例子(你可能不需要它,但其他人可能)

DECLARE @iterator INT 
SET @iterator = 0 

WHILE @iterator < 20 
BEGIN 
    SELECT * FROM table WHERE rowKey = @iterator 
/*do stuff*/ 
    @iterator = @iterator + 1 
END 

真正的問題是「它是什麼,你正在嘗試做的,根本無法在一套基於這樣做呢?」

10

我能想到一噸的原因,我會想解析直通設置查詢結果,並做一些事情,根本就沒有一個循環

而且絕大多數來完成的那些我可以告訴你如何在基於集合的操作中完成它,或者解釋爲什麼它應該在客戶端代碼而不是數據庫中完成。需要在sql中進行循環的情況非常罕見。

+1

我同意他們應該在客戶端代碼完成;然而,當我們處理數百萬條記錄時,即使數據庫中沒有合適的「位置」,也可以在數據庫中完成100倍(1000倍?)的處理。 – 2009-02-26 15:29:32

1

幾乎一切都可以根據設定來完成,請嘗試使用數字表

爲何20行?這就是你需要的全部

select *,identity(int, 1,1) as Someid into #temp 
from sysobjects 

declare @id int, @MaxId int 
select @id = 1,@MaxId = max(Someid) from #temp 

while @id < @MaxId 
begin 
-- do your stuff here 
print @id 
set @id [email protected] + 1 
end 
1

它取決於你想在循環中做什麼。使用while循環並不難:

declare @i int 
set @i = 20 
while @i>0 begin 
... do some stuff 
set @i = @i-1 
end 

它只是在使用遊標時變得很麻煩,這應該避免反正。

1

您可以嘗試使用用戶定義的函數來完成大部分工作,而不是採用基於循環的方法。這將保留基於設置的SQL語言的意圖。