在同一个存储过程中使用 3 个更新? "Small Error"

Using 3 updates in the same Store Procedure? "Small Error"

我有以下 SP,其中有 3 个更新语句。我每次执行此 SP 都会收到错误消息“消息 208,级别 16,状态 1,过程 sp_Rating_Comments,第 41 行 对象名称无效 'RatingLines'."。此错误位于第二个更新语句中。当我隐藏第二个和第三个更新语句时,我的代码工作正常。知道如何将这 3 个更新语句一起使用。

Alter PROCEDURE [HRSDB].[sp_Rating_Comments] 
-- @BookingNr varchar(25)
-- ,@Company varchar(30)
AS
BEGIN
  SET NOCOUNT ON;
     ;WITH RatingLines AS   -- Get the important columns from both HRSDB tables
    (
   Select   RDA.[CTS]    AS [CTS]
     ,RDA.[B_KEY]    AS [B_KEY]
     ,RDA.[H_KEY]    AS [H_KEY]
     ,RDA.[RT_ID]    AS [RT_ID]
     ,RDA.[RT_AVGRATING] AS [RT_AVGRATING]
        ,RDDA.[RTD_COMMENT] AS [RTD_COMMENT]
                      
  From  [DynNavHRS].[HRSDB].[HTL_RATING_ALL_DA]        RDA
  Join  [DynNavHRS].[HRSDB].[HTL_RATING_DETAIL_ALL_DA] RDDA
  ON    RDA.RT_ID =RDDA.RT_ID
     AND   RDDA.[RTD_COMMENT] <> ''
     AND   RDA.[B_KEY]='19214642'  -- Just to test with one rec 
    )
    
-- First Table:  
  UPDATE     [DynNavHRS].[dbo].[HRS$Agency Header]
  SET        [Booking Rating] = '1'
  FROM       [DynNavHRS].[dbo].[HRS$Agency Header] AH
  INNER JOIN RatingLines   RL1
  ON         RL1.[B_KEY] = AH.[Reservation No_]
  WHERE      RL1.[RTD_COMMENT] <> ''   -- If the Booking have a comment in DB2
  AND        [Booking Rating] = '0' ;  -- in order to avoide scanning all line
 
-- Second Table: 
  UPDATE     [DynNavHRS].[dbo].[HRS$Correction Agency Header] 
  SET        [Booking Rating] = '1'
  FROM       [DynNavHRS].[dbo].[HRS$Correction Agency Header] CL
  INNER JOIN RatingLines   RL2
  ON         RL2.[B_KEY] = CL.[Reservation No_]
  WHERE      RL2.[RTD_COMMENT] <> ''   -- If the Booking have a comment in DB2
  AND        [Booking Rating] = '0'  ; -- in order to avoide scanning all line

-- Third Table:  
  UPDATE     [DynNavHRS].[dbo].[HRS$Agency Display Line] 
  SET        [Booking Rating] = '1'
  FROM       [DynNavHRS].[dbo].[HRS$Agency Display Line] DL
  INNER JOIN RatingLines   RL3
  ON         RL3.[B_KEY] = DL.[Reservation No_]
  WHERE      RL3.[RTD_COMMENT] <> ''   -- If the Booking have a comment in DB2
  AND        [Booking Rating] = '0'   ;-- in order to avoide scanning all line

COMMIT
END

您使用 ;WITH RatingLines ... 启动 SP,它连接到第一个 UPDATE 语句,而不是其他语句。此构造创建一个 CTE,该 CTE 仅对其后的第一条语句可见。更多解释可以在 WITH common_table_expression (Transact-SQL) 的 TN 中找到。备注中的这段摘录特别强调了这一点:

A CTE must be followed by a single SELECT, INSERT, UPDATE, MERGE, or DELETE statement that references some or all the CTE columns.

要让此 table 为您的 SP 中的所有语句所知,请创建一个 table 变量或为 RatingLines 创建一个临时 table。

使用临时 table 的大纲如下:

Select   RDA.[CTS]        AS [CTS]
              ,RDA.[B_KEY]        AS [B_KEY]
              ,RDA.[H_KEY]        AS [H_KEY]
              ,RDA.[RT_ID]        AS [RT_ID]
              ,RDA.[RT_AVGRATING] AS [RT_AVGRATING]
              ,RDDA.[RTD_COMMENT] AS [RTD_COMMENT]
INTO #RatingLines -- Create #RatingLines as temporary table
From  [DynNavHRS].[HRSDB].[HTL_RATING_ALL_DA]        RDA
Join  [DynNavHRS].[HRSDB].[HTL_RATING_DETAIL_ALL_DA] RDDA
ON    RDA.RT_ID =RDDA.RT_ID
AND   RDDA.[RTD_COMMENT] <> ''
AND   RDA.[B_KEY]='19214642';

-- Throughout the rest of the SP, use #RatingLines as your ratings table; eg:
...
INNER JOIN #RatingLines   RL1
...

-- At the end of the SP, drop the temporary table
DROP TABLE #RatingLines;