使用存储过程添加记录不太有效

时间:2015-03-21 20:25:44

标签: mysql sql-server stored-procedures access-vba

我在使用访问表单在ms sql server数据库中添加记录时遇到了一些问题。我在访问表单中输入数据,然后执行存储过程,该存储过程应将数据添加到2个不同的表中。

这里的问题是,数据正在提交给一个表,而不是另一个表。这是我的存储过程:

ALTER PROCEDURE [dbo].[spAddArticle]
( 
   @description VARCHAR(128),
   @stock integer,
   @price decimal(8,2),
   @startdate varchar(30),
   @enddate varchar(30),
   @supplier varchar(128)
) 
AS 
BEGIN 
IF (
   SELECT COUNT(*) 
   FROM article  
   WHERE description = @description
   ) = 0 
   begin try
    BEGIN TRANSACTION
        DECLARE @articlenr INT
        SELECT @articlenr = MAX(articlenr) + 1 FROM article

        INSERT INTO article (articlenr, description, catcode, supplier, stock) 
         VALUES (@articlenr, @description, NULL, @supplier, @stock)

        INSERT INTO articleprice (articlenr, price, startdate, enddate) 
        VALUES (@articlenr, @price, @startdate, @enddate)
    commit
    Raiserror('The article has been added!', 16, 1)

  end try

   begin catch
       if @@TRANCOUNT > 0
       begin
                  ROLLBACK
       end
       Raiserror('An article with description %s already exists!', 16,1,@description)

   end catch
END

数据正在添加到表格文章中,但不会添加到文章价格中,我似乎无法弄清楚为什么......任何想法?

希望你们能在这里帮助我..

1 个答案:

答案 0 :(得分:1)

此存储过程存在许多问题。我无法解释为什么第二个插入失败但错误处理会混淆错误。 "成功"由于严重性16错误,raiseerror将触发catch块。更严重的问题是代码容易受到竞争条件的影响(EXISTS检查和SELECT MAX)。为了这个proc,我添加了一个UPDLOCK提示来序列化。以下版本需要SQL 2012或更高版本。如果您使用的是早期版本,请将CATCH块处理更改为使用RAISERROR而不是THROW

ALTER PROCEDURE [dbo].[spAddArticle]
( 
   @description VARCHAR(128),
   @stock integer,
   @price decimal(8,2),
   @startdate varchar(30),
   @enddate varchar(30),
   @supplier varchar(128)
) 
AS 

SET NOCOUNT ON; --rowcount messages can confuse some applications, especially ADO classic API

BEGIN TRY

    BEGIN TRANSACTION;

    IF NOT EXISTS(
       SELECT *
       FROM article  WITH(UPDLOCK, HOLDLOCK) --serialize access for this proc
       WHERE description = 'a'
       )
    BEGIN

        DECLARE @articlenr INT;

        SELECT @articlenr = MAX(articlenr) + 1 FROM article;

        INSERT INTO article (articlenr, description, catcode, supplier, stock) SELECT @articlenr, @description, NULL, @supplier, @stock);

        INSERT INTO articleprice (articlenr, price, startdate, enddate) VALUES (@articlenr, @price, @startdate, @enddate);

        COMMIT;

        RAISERROR('The article has been added!', 0, 0); --informational message for debugging

    END
    ELSE
    BEGIN

        RAISERROR('An article with description %s already exists!', 16,1,@description);

    END;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
    BEGIN
        ROLLBACK;
    END;
    THROW;
END CATCH
GO