T-SQL存储过程:在while循环中,只在游标中插入第一行

时间:2018-02-11 17:59:07

标签: sql-server stored-procedures

我的存储过程有问题。

我的应用程序中的参数定义良好,但在此过程中,当我尝试在表Image中插入一行时,它只插入@xmlImages的第一行,并发送了两个值。我感谢任何帮助!

CREATE PROCEDURE sp_AddExplanationAndImage
    @Text NVARCHAR(MAX) = NULL,
    @ID INT = 0
    @ListOfImages NVARCHAR(MAX) = NULL
AS
BEGIN
    INSERT INTO dbo.Explanation (ID, Text)
    VALUES (@ID, @Text)

    DECLARE @xmlImages xml

    SET @xmlImages = CAST(@ListOfImages AS xml)

    DECLARE @ImageExtension NVARCHAR(MAX)
    DECLARE @Name NVARCHAR(MAX)
    DECLARE @Content VARBINARY(MAX)

    IF (@ListOfImages IS NOT NULL)
    BEGIN
        DECLARE cursor cursor for--local fast_forward for
            SELECT
                s.x.value('(Image/Extension)[1]', 'nvarchar(max)'),
                s.x.value('(Image/Name)[1]', 'nvarchar(max)'),
                s.x.value('(Image/Content)[1]', 'varbinary(max)')
            FROM 
                @xmlImages.nodes('Images') AS s(x)

        OPEN CURSOR

        FETCH NEXT FROM cursor INTO @ImageExtension, @Name, @Content 

        WHILE @@FETCH_STATUS = 0
        BEGIN
            IF @@fetch_status <> 0 
               BREAK

            INSERT INTO dbo.Image (Extension, Name, Content)
                SELECT @ImageExtension, @Name, @Content

            FETCH NEXT FROM cursorSlike INTO @ImageExtension, @Name, @Content 
        END

        CLOSE cursor
        DEALLOCATE cursor
    END

2 个答案:

答案 0 :(得分:2)

fetch next from块中的WHILE不会引用您循环的光标。您将光标命名为cursor(我建议使用更具描述性的名称BTW),但您要从cursorSlike获取下一个。

但我不确定你是否首先需要循环(通常,除非没有其他方法可以完成任务,否则你应该避免SQL Server中的循环)。我在SQL Server中没有做过很多XML,但你试过这个吗?

INSERT INTO dbo.Image(Extension,Name,Content)
 SELECT
            s.x.value('(Image/Extension)[1]','nvarchar(max)'),
            s.x.value('(Image/Name)[1]','nvarchar(max)'),
            s.x.value('(Image/Content)[1]','varbinary(max)')
        FROM @xmlImages.nodes('Images')AS s(x)

答案 1 :(得分:1)

根据您的样本数据。你需要获得Images/Image个节点。而你不需要使用光标。

    INSERT INTO dbo.Image(Extension,Name,Content)
    SELECT
        s.x.value('(Extension)[1]','nvarchar(max)'),
        s.x.value('(Name)[1]','nvarchar(max)'),
        s.x.value('(Content)[1]','nvarchar(max)')
    FROM @xmlImages.nodes('Images/Image')AS s(x)