我正在尝试创建用户定义的游标,但是我收到以下错误,
Msg 102,Level 15,State 1,Line 25 &#39 ;;'附近的语法不正确。
我正在使用AdventureWorks2008r2
这是我的代码;
USE AdventureWorks2008r2
GO
DECLARE
-- LOCAL VARIABLEs
@OrderId INT,
@status TINYINT
--declare the cursor
DECLARE mynamelist CURSOR STATIC
FOR
SELECT Sales.SalesOrderHeader.SalesOrderID, Sales.SalesOrderHeader.STATUS
FROM Sales.SalesOrderHeader;
OPEN mynamelist;
FETCH NEXT
FROM mynamelist
INTO @status,
@OrderId
WHILE @@FETCH_STATUS = 0
IF @status = 1
BEGIN
FETCH NEXT
FROM mynamelist
INTO @status,@OrderId
PRINT 'Order Number:' + CAST(@OrderId AS VARCHAR(10)) + 'Status:Approved';
END;
ELSE IF @status = 3
PRINT 'Order Number:' + CAST(@OrderId AS VARCHAR(10)) + 'Status:Backordered';
ELSE IF @status = 4
PRINT 'Order Number:' + CAST(@OrderId AS VARCHAR(10)) + 'Status:Rejected';
ELSE IF @status = 5
PRINT 'Order Number:' + CAST(@OrderId AS VARCHAR(10)) + 'Status:Shipped';
ELSE
PRINT 'Order Number:' + CAST(@OrderId AS VARCHAR(10)) + 'Status:Cancelled';
END;
CLOSE nynamelist;
DEALLOCATE mynamelist;
如何解决此错误
答案 0 :(得分:1)
所以你有一些语法问题,然后是你的代码编写方式的一些逻辑问题。您将FETCH NEXT
嵌套在IF
语句中,因此WHILE
块实际上不会选择下一条记录,除非@status = 1
....
使用缩进和空格组织代码将有助于您大大了解步骤的逻辑和优先级。你错过了游标循环的BEGIN
。
另请注意,对于sql-server的分号并不总是必要的,除非在THROW和Common Table Expressions的情况下,之前的语句必须以分号结束,这就是为什么你经常看到它们被写为;WITH cte
as和;THROW 51000,
...我确信还有其他一些例子我只是给了一些。
无论如何,转储所有的If如果使用case expression
这个类型的操作更适合构建你的字符串然后打印它。
另请注意,如果结果中出现语法错误,您可以双击它,它会引发您遇到的语法错误。
DECLARE
-- LOCAL VARIABLEs
@OrderId INT , @status TINYINT
--declare the cursor
DECLARE mynamelist CURSOR STATIC FOR
SELECT
h.SalesOrderID,
h.Status
FROM
Sales.SalesOrderHeader h
open mynamelist;
FETCH NEXT FROM mynamelist INTO @status, @OrderId
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @Message NVARCHAR(1000)
SET @Message = 'Order Number:' + CAST(@OrderId as VARCHAR(10)) + 'Status:'
SET @Message = @Message + CASE
WHEN @status = 1 THEN 'Approved'
WHEN @status = 3 THEN 'Backordered'
WHEN @status = 4 THEN 'Rejected'
WHEN @status = 5 THEN 'Shipped'
ELSE 'Cancelled'
END
PRINT @Message;
FETCH NEXT FROM mynamelist INTO @status, @OrderId
END
CLOSE nynamelist;
DEALLOCATE mynamelist;