2013-04-04 58 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