以下存储过程有什么问题?

时间:2018-05-18 07:26:37

标签: sql-server stored-procedures

alter procedure product_sales 
@productid int,
@quantitysell int
as 
begin
    declare @productname varchar(20)
    declare @quantityavailable int 

    select @quantityavailable=quantityav from products_trycatch 
    select @productname=productname from products_trycatch where productid=@productid
    select @productid=productid from products_trycatch

    if(not exists(select @productid from products_trycatch)
        begin
            raiserror('Product does not exist',16,1)
        end 
    else
        begin
            if (@quantitysell>@quantityavailable)
                begin 
                    print 'Stock not available'
                end 
            else 
                begin 
-------------
                update products_trycatch set quantityav=quantityav-@quantitysell
                insert into product_log values(@productid,@productname,@quantitysell)
             end 

请告诉我错误的地方。我想做的是。一个表包含产品可用的库存,当我执行SP我提到哪个产品和销售数量时,sp从可用数量表中扣除该值并在新表中更新销售数量。

5 个答案:

答案 0 :(得分:1)

您正在考虑程序,逐步解决问题,但是从您的几个步骤中遗漏了部分内容。

不要编写几个查询来检索单个数据。整体考虑问题 1

alter procedure product_sales 
@productid int,
@quantitysell int
as 
begin
declare @rc int
update products_trycatch
set quantityav = quantityav - @quantitysell
where productid = @productid and quantityav > @quantitysell
set @rc = @@ROWCOUNT
if @rc = 1
begin
    insert into product_log
    select @productid,productname,@quantitysell
    from product_trycatch
    where productid = @productid
end
else
begin
  if not exists(select * from products_trycatch where productid = @productid)
  begin
    raiserror('Product does not exist',16,1)
  end
  else
  begin
    print 'Stock not available'
  end
end

不是我的所有查询都以product_trycatch列中的productid列为目标,而您的几个人不会这样做,这意味着他们将会分配非您的变量的确定性值,或更新product_trycatch中的所有行并扣除@quantitysell值。

1 对于奖励积分,我们可以写一个update caseoutput条款,无需执行任何重新查询产品名称或失败路径中的product_trycatch表,但这可能不值得增加复杂性。此查询显示了一般技术:

declare @products table (ID int not null, Quantity int not null, Name varchar(20) not null)
insert into @products (ID,Quantity,Name) values (1,15,'Fred')

declare @ID int
declare @Qty int
declare @RefData table (OldQuantity int not null, NewQuantity int not null,
                        Name varchar(20) not null)

select @ID = 1, @Qty = 20

update @products
set Quantity = CASE WHEN Quantity >= @Qty THEN Quantity - @Qty ELSE Quantity END
output deleted.Quantity,inserted.Quantity, inserted.Name into @RefData
where ID = @ID

select * from @RefData

您可以使用@ID@Qty值来查看@RefData当请求的数量高于可用数量或产品的数量时所反映的各种结果不存在。

答案 1 :(得分:0)

格式化您的代码并添加缺少的单词 -

alter procedure product_sales 
@productid int,
@quantitysell int
as 
begin
    declare @productname varchar(20)
    declare @quantityavailable int 
    select @quantityavailable=quantityav from products_trycatch 
    select @productname=productname from products_trycatch where productid=@productid
    select @productid=productid from products_trycatch
    if not exists(select @productid from products_trycatch)
    begin
        raiserror('Product does not exist',16,1)
    end 
    else if (@quantitysell>@quantityavailable)
    begin 
        print 'Stock not available'
    end
    else 
    begin 
        -------------
        update products_trycatch set quantityav=quantityav-@quantitysell
        insert into product_log values(@productid,@productname,@quantitysell)
    end
end 

答案 2 :(得分:0)

这是格式化代码

    alter procedure product_sales 
@productid int,
@quantitysell int
as 
begin
declare @productname varchar(20)
declare @quantityavailable int 
select @quantityavailable=quantityav from products_trycatch 
select @productname=productname from products_trycatch where productid=@productid
select @productid=productid from products_trycatch
if(not exists(select @productid from products_trycatch))
begin
raiserror('Product does not exist',16,1)
end 
else if (@quantitysell>@quantityavailable)
begin 
print 'Stock not available'
end 
else 
begin 
-------------
update products_trycatch set quantityav=quantityav-@quantitysell
insert into product_log values(@productid,@productname,@quantitysell)
end 
end

答案 3 :(得分:0)

刚刚修改了你的存储过程看看它

ALTER PROCEDURE Product_sales 
(@Productid    INT, 
 @Quantitysell INT
 ) 
AS 
  BEGIN TRY 
      DECLARE @Productname VARCHAR(20) 
      DECLARE @Quantityavailable INT 

      SELECT @Quantityavailable = Quantityav 
      FROM   Products_trycatch 

      SELECT @Productname = Productname 
      FROM   Products_trycatch 
      WHERE  Productid = @Productid 

      SELECT @Productid = Productid 
      FROM   Products_trycatch 

      IF( @Productid IS NULL ) 
        BEGIN 
            RAISERROR('Product does not exist',16,1) 
        END 
      ELSE IF ( @Quantitysell > @Quantityavailable ) 
        BEGIN 
            PRINT 'Stock not available' 
        END 
      ELSE 
        BEGIN 
            DECLARE @Is_transcount INT 

            BEGIN TRANSACTION 

            SET @Is_transcount=1 

            UPDATE Products_trycatch 
            SET    Quantityav = Quantityav - @Quantitysell; 

            INSERT INTO Product_log 
            VALUES     (@Productid, 
                        @Productname, 
                        @Quantitysell) 

            COMMIT TRANSACTION 

            SET @Is_transcount=0 
        END 
  END TRY 

  BEGIN CATCH 
      IF( @@Trancount > 0 ) 
        ROLLBACK TRANSACTION 

      DECLARE @Error_message   VARCHAR(Max), 
              @Error_number    INT, 
              @Error_procedure VARCHAR(100) 

      SELECT @Error_message = ERROR_MESSAGE(), 
             @Error_number = ERROR_NUMBER(), 
             @Error_procedure = ERROR_PROCEDURE() 
  END CATCH 

答案 4 :(得分:0)

SP对参数嗅探问题持开放态度。

您可以通过代码重新分配@productid的值。

从这一点开始,SQL将对使用什么计划做出更多假设,因为它不再知道实际价值。