2

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

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 EACH pig_id 循环中使用 f.pig_id 的必要性。我看过 CREATE TRIGGER 解决方案,但我希望有更简单的东西。我知道这是一个低效的查询,但该项目需要简单且易于非技术人员阅读的查询。

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

4

6 回答 6

2

我认为您正在寻找的是 CURSOR

这里是MSDN 示例的链接,底部有一个简单的链接。

于 2013-04-04T14:56:31.817 回答
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

或者

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
于 2013-04-04T15:40:08.463 回答
1

RBAR = 坏。

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/

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

请,请,请避免光标。

于 2013-04-04T14:59:24.970 回答
1

如果您需要对第一个查询中的值做一些复杂的事情,那么您可以使用 cursor。

一个例子:

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
于 2013-04-04T15:00:58.317 回答
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;
于 2013-04-04T15:01:10.740 回答
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
于 2013-04-04T15:24:41.670 回答