2013-04-04 57 views
2

基本上我想要的僞做的是:每個樣式SQL查詢

FOR EACH pig_id IN (SELECT pig_id FROM farm AS f) 
BEGIN 
-- Do something funky with the f.pig_id, for example 
    SELECT bacon, ham, pork, (face + guts + brains + testicles) AS 'sausage' 
    FROM farm 
    WHERE pig_id = f.pig_id 
END 

循環的實際內部是比較複雜的,但這個簡單的SELECT語句表明,有必要在循環中使用f.pig_id對於農場表中的每個pig_id。我看過CREATE TRIGGER解決方案,但我希望更簡單一些。我知道這是一個效率低下的查詢,但該項目需要非技術人員的簡單性和易讀性。

編輯: 它被用於一個小的數據集,所以人的可讀性是一個優先於效率。

+2

您正在嘗試做一些效率低下。將行插入臨時表中,根據需要進行更新,然後查詢臨時表可能會更好。 – 2013-04-04 14:54:52

+2

這有時被稱爲「RBAR」行通過Agonizing Row。這不是你如何開始編碼TSQL。 – granadaCoder 2013-04-04 14:55:22

+1

我不確定爲什麼JOIN(或JOINS)不夠用 - 當你看到這樣的代碼時,它通常源於對SQL和設置的誤解! – Jamie 2013-04-04 14:59:09

回答

2

如果pig_id唯一的列(如。數據類型爲int),你可以使用循環不CURSOR

DECLARE @id int = (SELECT MIN(pig_id) FROM farm) 
WHILE (@id IS NOT NULL) 
BEGIN 
    SELECT bacon, ham, pork, (face + guts + brains + testicles) AS 'sausage' 
    FROM farm 
    WHERE pig_id = @id 

    SELECT @id = MIN(pig_id) FROM farm WHERE pig_id > @Id 
END 

OR

DECLARE @id int = 0 
WHILE 1 = 1 
BEGIN 
    SELECT @id = (select min(pig_id) from farm where pig_id > @id)  

    IF @id IS NULL 
    BREAK 
    ELSE 

    SELECT bacon, ham, pork, (face + guts + brains + testicles) AS 'sausage' 
    FROM farm 
    WHERE pig_id = @id 
    CONTINUE 
END 
+0

乾杯隊友,這似乎是最優雅的解決方案。謝謝你的幫助。 – Gregology 2013-04-04 16:33:38

+0

不客氣。 – 2013-04-04 16:36:50

2

我想你在找什麼是CURSOR

這裏link to MSDN examples,有簡單的bottome其中一路。

+1

遊標是邪惡的,只能用在最後,最後,最後,最後的手段。 – granadaCoder 2013-04-04 14:58:31

+2

@granadaCoder我不會不同意,但有時是必要的邪惡,不知道應用的具體細節,可能沒有其他的方式... – Borik 2013-04-04 15:01:09

+1

也許這是唯一的方法。但是在我發佈「無光標」法令(在我的小組中)的過去10年中,我只有一種情況,即set-baed代碼無法寫入。你沒有警告過他。你剛給他的dyn @ mite去釣魚。也就是說,可以用dyn @ mite去釣魚,但我不推薦它。 – granadaCoder 2013-04-04 15:04:24

1

如果您需要對第一個查詢中的值進行復雜處理,則可以使用遊標。

一個例子:

DECLARE @pig int 
DECLARE db_cursor CURSOR FOR 
SELECT pig_id FROM farm AS f 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @pig 

WHILE @@FETCH_STATUS = 0 
BEGIN 
     --Do your thing here.... 

     FETCH NEXT FROM db_cursor INTO @pig 
END 

CLOSE db_cursor 
DEALLOCATE db_cursor 
1

如前所述,光標應該做你想要的這裏是一個簡單的例子:

DECLARE @valueHolder INT 

DECLARE myCursor CURSOR FOR SELECT ID FROM MyTable 
OPEN myCursor 

FETCH NEXT FROM myCursor INTO @valueHolder 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    PRINT @valueHolder 

    FETCH NEXT FROM myCursor INTO @valueHolder 
END 

CLOSE myCursor; 
DEALLOCATE myCursor; 
1

不使用光標,你可以只使用一個計數器和一個WHILE循環:

模式:

CREATE TABLE #Pig 
(
PigId INT 
) 
INSERT INTO #Pig VALUES 
(1), 
(3), 
(6), 
(10) 

CREATE TABLE #Farm 
(
PigId INT, 
Name VARCHAR(20) 
) 
INSERT INTO #Farm VALUES 
(1,'michaeljackson'), 
(1,'jim'), 
(3,'jill'), 
(3,'j') 

腳本:

SELECT PigId, 
     rn = ROW_NUMBER() OVER (ORDER BY PigId) 
INTO #PigRows 
FROM #Pig 


DECLARE @max INT = (SELECT MAX(rn) FROM #PigRows) 

DECLARE @counter INT = 1 
WHILE @counter <= @max 
BEGIN 

    SELECT Name 
    FROM #Farm 
    WHERE PigId = @counter 

    SET @counter = @counter + 1 
END