【问题标题】:Update TableType variable in dynamic SQL query更新动态 SQL 查询中的 TableType 变量
【发布时间】:2014-01-29 07:26:44
【问题描述】:

我在我的数据库中创建了用户定义的表类型。之后,我在我的过程中声明了该表类型的变量。我已经返回了其余的逻辑。最后,我尝试使用动态 SQL 更新该表类型变量。

但是我得到了一个错误:

消息 10700,第 16 级,状态 1,第 1 行
表值参数“@ttbl_TagList”是只读的,不能修改。

我该如何解决这个错误?

用户定义的表类型:

CREATE TYPE [dbo].[tt_TagList] AS TABLE(
    [tagListId] [tinyint] IDENTITY(1,1) NOT NULL,
    [tagId] [tinyint] NOT NULL DEFAULT ((0)),
    [tagName] [varchar](100) NOT NULL DEFAULT (''),
    [tagValue] [nvarchar](max) NOT NULL DEFAULT ('')
)
GO

程序:

CREATE PROCEDURE [dbo].[P_ReplaceTemplateTag]   
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @ttbl_TagList dbo.tt_TagList, @V_TagId INT, @V_Counter TINYINT = 1, 
            @V_FinalQuery NVARCHAR(MAX) = '', @V_TagValue NVARCHAR(MAX); 

    INSERT INTO @ttbl_TagList (tagId, tagName, tagValue) 
    SELECT DISTINCT T.tagId, T.tagName, '' AS tagValue 
    FROM dbo.tbl_Tag T;

    WHILE (1 = 1)
    BEGIN
        SET @V_TagValue = '';
        SELECT @V_TagId = tagId FROM @ttbl_TagList WHERE tagListId = @V_Counter;

        IF (@@ROWCOUNT = 0) 
        BEGIN 
            BREAK;
        END

        IF (@V_TagId = 1) 
        BEGIN 
            /* Logic for getting tag value */
            SET @V_TagValue = 'Tag Value 1';
        END
        ELSE IF (@V_TagId = 2) 
        BEGIN 
            /* Logic for getting tag value */
            SET @V_TagValue = 'Tag Value 2';
        END
        ELSE IF (@V_TagId = 3) 
        BEGIN 
            /* Logic for getting tag value */
            SET @V_TagValue = 'Tag Value 3';
        END
        ELSE IF (@V_TagId = 4) 
        BEGIN 
            /* Logic for getting tag value */
            SET @V_TagValue = 'Tag Value 4';
        END

        IF (@V_TagValue != '')
        BEGIN 
            SET @V_FinalQuery = @V_FinalQuery + ' WHEN ' + CONVERT(NVARCHAR(10), @V_Counter) + ' THEN ''' + @V_TagValue + '''';
        END
        SET @V_Counter = @V_Counter + 1;
    END

    IF (@V_FinalQuery != '')
    BEGIN
        SET @V_FinalQuery = N'UPDATE @ttbl_TagList SET tagValue = (CASE tagListId' + @V_FinalQuery + ' END)';
        EXECUTE sp_executesql @V_FinalQuery, N'@ttbl_TagList dbo.tt_TagList readonly', @ttbl_TagList;
    END

    SELECT * FROM @ttbl_TagList;
END 

【问题讨论】:

    标签: sql sql-server sql-update dynamic-sql user-defined-types


    【解决方案1】:

    TVP 不能直接更新。所以试试这个 -

    CREATE PROCEDURE [dbo].[P_ReplaceTemplateTag]   
    AS
    BEGIN
        SET NOCOUNT ON;
    
        IF OBJECT_ID('tempdb.dbo.#t1') IS NOT NULL
            DROP TABLE #t1
    
        DECLARE 
              @ttbl_TagList dbo.tt_TagList
            , @V_Counter TINYINT = 1
            , @V_FinalQuery NVARCHAR(MAX) = ''
            , @V_TagValue NVARCHAR(MAX); 
    
        INSERT INTO @ttbl_TagList (tagId, tagName, tagValue) 
        SELECT DISTINCT tagId, tagName, ''
        FROM dbo.tbl_Tag;
    
        WHILE (1 = 1) BEGIN
    
            SELECT @V_TagValue = 
                CASE 
                    WHEN tagId = 1 THEN 'Tag Value 1'
                    WHEN tagId = 2 THEN 'Tag Value 2'
                    WHEN tagId = 3 THEN 'Tag Value 3'
                    WHEN tagId = 4 THEN 'Tag Value 4'
                    ELSE ''
                END
            FROM @ttbl_TagList 
            WHERE tagListId = @V_Counter;
    
            IF (@@ROWCOUNT = 0) BREAK;
    
            IF (@V_TagValue != '')
            BEGIN 
                SET @V_FinalQuery = @V_FinalQuery + ' WHEN ' + CONVERT(NVARCHAR(10), @V_Counter) + ' THEN ''' + @V_TagValue + '''';
            END
    
            SET @V_Counter = @V_Counter + 1;
        END
    
        IF (@V_FinalQuery != '')
        BEGIN
    
            CREATE TABLE #t1
            (
                  tagId TINYINT
                , tagName VARCHAR(100)
                , tagValue NVARCHAR(MAX)
            )
    
            SET @V_FinalQuery = N'
                INSERT INTO #t1
                SELECT tagId, tagName, (CASE tagListId' + @V_FinalQuery + ' END)
                FROM @ttbl_TagList';
    
            EXEC sys.sp_executesql 
                  @V_FinalQuery
                , N'@ttbl_TagList dbo.tt_TagList readonly'
                , @ttbl_TagList;
    
        END
    
        SELECT * FROM #t1;
    
    END 
    

    【讨论】:

      猜你喜欢
      • 2018-06-14
      • 2015-11-15
      • 1970-01-01
      • 2017-04-04
      • 1970-01-01
      • 2017-12-12
      • 2014-09-21
      • 2014-10-20
      相关资源
      最近更新 更多