我的第一个表值函数和游标

Mig*_*Mas 0 t-sql sql-server function cursor while-loop

我有这样的疑问:

\n\n
SELECT name, lastname\nFROM contestant \nWHERE  name= 'John'  AND lastname = 'Smith'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我从上面的查询中得到了几个结果,我需要将它们用于以下查询:

\n\n
SELECT  name, lastname,prize, city \nFROM draw\nWHERE  name= name from table contestant  AND lastname= name from table contestant  \n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我\xe2\x80\x99m 使用游标和WHILE 构建一个表值函数,这样我就可以得到一个包含结果的表。

\n\n

Here\xe2\x80\x99s是我的尝试,你能帮我完成吗?这对我理解TSQL这一章非常有帮助。谢谢!

\n\n
CREATE FUNCTION [dbo].[myFunction]\n(\n    @name varchar (44),\n    @lastname varchar (44) \n)\nRETURNS \n@tmpTable TABLE \n(   \n    name char(44),\n    lastname char(44),\n    prize varchar(44),\n    city char(44)\n\n)\nAS\nBEGIN\n\n    DECLARE \n/* what do I have to input here */\n\n    DECLARE myCursor CURSOR FOR\n\nSELECT name, lastname\nFROM contestant \nWHERE  name= @name  AND lastname = @lastname\n\n    OPEN myCursor\n\n    FETCH NEXT FROM myCursor INTO  /* what goes here?*/\n\n\n\n    WHILE (@@FETCH_STATUS = 0) \n    BEGIN\n\n -- and here? \n\n        FETCH NEXT FROM myCursor INTO /* what goes here?*/\n\n\n    END /*WHILE*/\n\n    CLOSE myCursor\n    DEALLOCATE myCursor\n\n\n    INSERT INTO @tmpTable (name, lastname,prize, city)\n    SELECT name, lastname,prize, city \n        FROM prize\n        WHERE name = @name AND lastname = @lastname\n\n    RETURN\nEND\n
Run Code Online (Sandbox Code Playgroud)\n

Nic*_*aid 5

好吧,只要你明白:

  1. 表格设计不正确 - 您应该在两个表格中都有参赛者密钥。
  2. 连接是解决此问题的方法,而不是游标
  3. 我在这里提供的是解决这个问题的最糟糕的方法,你需要从中学到的是,你永远不应该用它来解决这个问题!

但为了回答您的问题“我如何使用光标”,这里有一些未经测试的代码,希望能为您提供这个概念。

CREATE FUNCTION [dbo].[myFunction]
(
@name varchar (44),
@lastname varchar (44) 
)
RETURNS 
@tmpTable TABLE 
(   
name char(44),
lastname char(44),
prize varchar(44),
city char(44)
)
AS
BEGIN

DECLARE @c_name varchar (44)
DECLARE @c_lastname varchar (44) 


DECLARE myCursor CURSOR FOR

SELECT name, lastname
FROM contestant 
WHERE  name= @name  AND lastname = @lastname

OPEN myCursor

FETCH NEXT FROM myCursor INTO  @c_name, @c_lastname

WHILE (@@FETCH_STATUS = 0) 
BEGIN

    -- we've found a row. Name look for the matching row in prize
    INSERT INTO @tmpTable (name, lastname,prize, city)
    SELECT name, lastname,prize, city 
    FROM prize
    WHERE name = @c_name AND lastname = @c_lastname

    FETCH NEXT FROM myCursor INTO @c_name, @c_lastname

END /*WHILE*/

CLOSE myCursor
DEALLOCATE myCursor

RETURN
END
Run Code Online (Sandbox Code Playgroud)

作为比较,这是正确的解决方案:

SELECT draw.name, draw.lastname, draw.prize, draw.city
FROM 
draw
INNER JOIN
contestant 
ON draw.name = contestant.name
AND draw.lastname = contestant.lastname
WHERE  contestant.name= 'John'  
AND contestant.lastname = 'Smith'
Run Code Online (Sandbox Code Playgroud)

它更小、更简单、更快。