【问题标题】:Invalid object using WITH common table expression使用 WITH 公用表表达式的对象无效
【发布时间】:2014-05-28 04:11:56
【问题描述】:

我正在尝试在存储过程中使用 With

    USE [BusOprtn]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER  PROCEDURE [dbo].[AddRepairedStock]

     @RepairedItems [dbo].[RepairedItems] readonly


    AS
    BEGIN 

    declare @productNo bigint,@productManufacturer bigint

      SET NOCOUNT ON;

      begin try
      begin transaction
      UPDATE [BusOprtn].[dbo].[RepairItem] SET [ReturnedQuantity] = rdi.ReturnedQuantity,[AmountPaid] = rdi.AmountPaid,[ReturnDate] = rdi.ReturnDate from [BusOprtn].[dbo].[RepairItem] as ri inner join @RepairedItems as rdi on ri.id=rdi.id;

     ;with y as (
     select [PartUsedId],rdi.[ReturnedQuantity] from [BusOprtn].[dbo].[RepairItem] as ri inner join @RepairedItems as rdi on ri.Id=rdi.id 
     ), x as (
     SELECT  [PartNo] ,[ManufacturerId],[ReturnedQuantity] FROM [BusOprtn].[dbo].[PartUsed] as p inner join y 
     on p.id = y.PartUsedId
     )


      UPDATE [BusOprtn].[dbo].[ProductMaster] SET   [RepairedStock] =( [RepairedStock]+x.[ReturnedQuantity]) from [BusOprtn].[dbo].[ProductMaster] as pm inner join x on x.[PartNo]=pm.Id;
      UPDATE [BusOprtn].[dbo].[ProductStockManufacturer] SET  [RepairedCurrentStock] = ([RepairedCurrentStock]+x.[ReturnedQuantity]) from [BusOprtn].[dbo].[ProductStockManufacturer] as pm inner join x on x.[PartNo]=pm.[ProductNo] and x.[ManufacturerId]= pm.[ManufacturerId];

      commit transaction
        end try
        BEGIN CATCH
        declare @ErrorMessage nvarchar(max), @ErrorSeverity 

int, @ErrorState int;
    select @ErrorMessage = ERROR_MESSAGE() + ' Line ' + cast

(ERROR_LINE() as nvarchar(5)), @ErrorSeverity = ERROR_SEVERITY(), 

@ErrorState = ERROR_STATE();
    rollback transaction;
    raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState);
        END CATCH
END

当我执行上面的命令时,它执行成功。但是当我尝试在运行时调用存储过程时,它给出了错误

`Invalid object name 'x'.

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.`

早期的问题是子查询,因为它不允许使用“WITH”,因此尝试使用另一个临时表y,但错误仍在继续。我为 WITH 中允许的项目推荐了 Allowed Items

【问题讨论】:

    标签: c# sql stored-procedures try-catch


    【解决方案1】:

    错误来自您使用 CTE x 的第二个更新语句

    CTE 的范围是一个语句,因此 x 仅在第一次更新时可见。

    要解决此问题,您可以在第二次更新之前复制 CTE 的代码,或者您可以使用临时表(或表变量)来捕获来自 x 的输出,并在两个更新语句中使用临时表的 CTE。

    使用不同格式的代码很容易看到。

    第一次更新声明:

    with y as 
    (
      select [PartUsedId],
             rdi.[ReturnedQuantity] 
      from [BusOprtn].[dbo].[RepairItem] as ri 
        inner join @RepairedItems as rdi 
          on ri.Id=rdi.id 
    ), x as
    (
      SELECT [PartNo],
             [ManufacturerId],
             [ReturnedQuantity] 
      FROM [BusOprtn].[dbo].[PartUsed] as p 
        inner join y 
          on p.id = y.PartUsedId
    )
    UPDATE [BusOprtn].[dbo].[ProductMaster] 
    SET [RepairedStock] = ([RepairedStock]+x.[ReturnedQuantity]) 
    from [BusOprtn].[dbo].[ProductMaster] as pm 
      inner join x 
        on x.[PartNo]=pm.Id;
    

    第二次更新声明:

    UPDATE [BusOprtn].[dbo].[ProductStockManufacturer] 
    SET  [RepairedCurrentStock] = ([RepairedCurrentStock]+x.[ReturnedQuantity]) 
    from [BusOprtn].[dbo].[ProductStockManufacturer] as pm 
      inner join x 
        on x.[PartNo]=pm.[ProductNo] and x.[ManufacturerId]= pm.[ManufacturerId];
    

    【讨论】:

      【解决方案2】:

      您可以尝试使用 SQL Server Profiler(MSSMS 中的Service 菜单)。在那里您可以找到确切收到的查询。也许有些不同。

      希望它会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-09
        相关资源
        最近更新 更多