0
ALTER PROCEDURE [dbo].[InsertNewProduct]
    @ProductCode VARCHAR(200) ,
    @OMCode VARCHAR(200) ,
    @ProductName VARCHAR(200) ,
    @Category VARCHAR(200) ,
    @Balance INT ,
    @ReOrder INT ,
    @Unit VARCHAR(20) ,
    @location VARCHAR(500) ,
    @expiry DATE
AS 
    SET NOCOUNT ON

    DECLARE @existingProduct INT

    SET @existingProduct = ( SELECT COUNT(*)
                             FROM   dbo.Products
                             WHERE  OMCode = @OMCode
                           )

    IF @existingProduct > 0 
        BEGIN

            RAISERROR(' Already Exists--',11,1)

        END

    IF @existingProduct <= 0 
        BEGIN
            INSERT  INTO dbo.Products
            VALUES  ( @ProductCode, @OMCode, @ProductName, @Category, @Balance,
                      @ReOrder, @Unit, @location, @expiry )

        END 


GO

现在的问题是仍然插入了具有现有 OMCODE 的产品。似乎无法理解为什么....而且我不想在 OMCode 列上放置一个唯一约束。

4

3 回答 3

1

这可能与并发有关吗?我看到你没有对你的 SP 进行任何形式的锁定。如果 SP “同时”执行两次,则两次执行都可能输入相同的 IF existingProduct <= 0,您是否尝试锁定?

在这里快速介绍,如果它有任何用处:http ://www.sqlteam.com/article/introduction-to-locking-in-sql-server

于 2013-07-30T18:47:18.640 回答
0

您可以尝试一次访问数据库,例如:

ALTER PROCEDURE [dbo].[InsertNewProduct]
    @ProductCode VARCHAR(200) ,
    @OMCode VARCHAR(200) ,
    @ProductName VARCHAR(200) ,
    @Category VARCHAR(200) ,
    @Balance INT ,
    @ReOrder INT ,
    @Unit VARCHAR(20) ,
    @location VARCHAR(500) ,
    @expiry DATE
AS 
    SET NOCOUNT ON
    DECLARE @Output TABLE (OMCode VARCHAR(200)) 
    INSERT INTO dbo.Products
    OUTPUT INSERTED.OMCode INTO @Output
    SELECT @ProductCode, @OMCode, @ProductName, @Category, @Balance, @ReOrder, @Unit, @location, @expiry 
    FROM (SELECT @OMCode AS OMCode) Tester
    LEFT JOIN Products ON Tester.OMCode = Products.OMCode
    WHERE Products.OMCode IS NULL

    IF(EXISTS(SELECT * FROM [@Output]))
    BEGIN
         RAISERROR(' Already Exists--',11,1)
    END

我个人喜欢明确命名子句中的所有列INSERT,它可以减少错位的机会

    ...
    INSERT INTO dbo.Products (ProductCode,  OMCode,  ProductName,  Category,  Balance,  ReOrder,  Unit,  location,  expiry)
    OUTPUT INSERTED.OMCode INTO @Output
    SELECT                    @ProductCode, @OMCode, @ProductName, @Category, @Balance, @ReOrder, @Unit, @location, @expiry 
    ...
于 2013-07-31T04:37:21.653 回答
0

由于您正在修剪输入上的@OMCode,因此您可能想试试这个:

SET @existingProduct = ( SELECT COUNT(*)
                         FROM   dbo.Products
                         WHERE  rtrim(ltrim(OMCode)) = @OMCode
                       )
于 2013-07-30T19:41:23.257 回答