对于每个样式的SQL查询

时间:2013-04-04 14:51:06

标签: sql sql-server loops

基本上我想在伪代码中做的是:

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语句演示了在农场TABLE中循环FOR FOR EACH pig_id中使用f.pig_id的必要性。我看过CREATE TRIGGER解决方案,但我希望能有更简单的东西。我知道这是一个效率低下的查询,但该项目需要简单,并且非技术人员可以轻松地进行人工阅读。

编辑: 它被用在一个小数据集上,因此人类可读性优先于效率。

6 个答案:

答案 0 :(得分:2)

我认为你要找的是CURSOR

这里是link to MSDN examples,在底部有一个简单的。

答案 1 :(得分: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

答案 2 :(得分:1)

RBAR = BAD。

https://www.simple-talk.com/sql/t-sql-programming/rbar--row-by-agonizing-row/

基于集合的好!

.............................

我在这里创建了一个ANTI示例:

http://granadacoder.wordpress.com/2008/07/24/cursors-setbased-and-scalar-udf/

Anti示例是我向您展示如何使用游标,但后来我向您展示了如何不使用游标来解决同样的问题。

请,请避免使用游标。

答案 3 :(得分: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

答案 4 :(得分: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;

答案 5 :(得分: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