使用WITH公用表表达式的对象无效

时间:2014-05-28 04:11:57

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

我正在尝试在存储过程中使用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但是错误仍在继续。我在{。}}中审阅了Allowed Items允许的项目。

2 个答案:

答案 0 :(得分:2)

错误来自您使用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];

答案 1 :(得分:0)

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

希望它会有所帮助。