存储过程中的临时视图仅在第一次更新时有效

时间:2016-11-22 08:44:50

标签: sql sql-server stored-procedures

我正在编写一个存储过程,用于创建临时视图,然后根据此临时视图执行多个更新。 问题是在第一个UPDATE命令(错误是“无效的对象名称”)之后,此临时视图无效。

USE [MyDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_MySP]
    @passedParam VARCHAR(32)
AS
BEGIN
    WITH MyTempView AS
    (
        SELECT [myTable1].[Id]
        FROM [dbo].[myTable1] LEFT JOIN [dbo].[myTable2] ON [myTable1].Id = [myTable2].[DeviceId]
        WHERE 
        --all kind of conditions    
    )

    --The temp view is valid here
    UPDATE [dbo].[myTable1]
    SET [myTable1].[Ready] = 0, [myTable1].[Reason] = NULL
    WHERE
    [myTable1].[Id] IN (SELECT [Id] FROM MyTempView)

    --The temp view is NO LONGER VALID from this point
    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 1.')
    WHERE
    --all kind of conditions

    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 2.')
    WHERE
    --all kind of conditions

    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 3.')
    WHERE
    --all kind of conditions

    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 4.')
    WHERE
    --all kind of conditions

END

怎么能解决? 提前谢谢。

2 个答案:

答案 0 :(得分:1)

是临时视图无效,因为cte的范围仅限于第一个更新语句。所以你将结果插入临时表。并在任何你想要的程序中使用它。

 USE [MyDB]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[SP_MySP]
        @passedParam VARCHAR(32)
    AS
    BEGIN
       if object_id('tempdb..#t1') is not null
        drop table #t1
            SELECT [myTable1].[Id] into #t1
            FROM [dbo].[myTable1] LEFT JOIN [dbo].[myTable2] ON [myTable1].Id = [myTable2].[DeviceId]
            WHERE 


    --The temp view is valid here
    UPDATE [dbo].[myTable1]
    SET [myTable1].[Ready] = 0, [myTable1].[Reason] = NULL
    WHERE
    [myTable1].[Id] IN (SELECT [Id] FROM #t1)

    --The temp view is NO LONGER VALID from this point
    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 1.')
    WHERE
    --all kind of conditions

    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 2.')
    WHERE
    --all kind of conditions

    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 3.')
    WHERE
    --all kind of conditions

    UPDATE [dbo].[myTable1]
    SET [myTable1].[Reason] = CONCAT([myTable1].[Reason],'Reason 4.')
    WHERE
    --all kind of conditions

    END

答案 1 :(得分:0)

使用WITH name创建的 common table expression (CTE)位于其所属的一个命令之前:

with name
  ... implement CTE
update ... 

它与批次中的任何其他命令无关。

我认为你的命名令你感到困惑:

  1. MyTempView不是视图
  2. MyTempView不是临时的(名称上会有#前缀)
  3. 表和视图定义(临时或非临时)未使用with定义。
  4. 目前尚不清楚您在CTE中想要实现的目标,因此不容易建议什么是更好的方法。