简体   繁体   中英

INSERT statement conflicted with the CHECK constraint (check with UDF)

I'm working on inventory management system where I have to relate sale line items to purchase line items in order to calculate profit. in order to keep track of available item by purchase line, I wrote a function and used it in a CHECK constraint but insert query is conflicting despite of less quantity than available quantity.

I have tried changing [Qty] , half or less of available quantity inserts successfully however equal amount or one less does not work.

Here is my table

CREATE TABLE [dbo].[tSaleLineItem]
(
    [Id] [INT] IDENTITY(1,1) NOT NULL,
    [InvoiceId] [INT] NOT NULL,
    [proId] [INT] NOT NULL,
    [Qty] [INT] NOT NULL,
    [Price] [FLOAT] NOT NULL,
    [PurchaseId] [INT] NOT NULL,
    [IsActive] [BIT] NOT NULL
)

My check constraint condition

[dbo].[fnGetStockByPurchase]([PurchaseId]) >= [Qty]

and my function is defined as

RETURN 
    (ISNULL((SELECT Qty FROM tPurchaseLineItem 
             WHERE Id = @PurchaseId AND IsActive = 1), 0)
    - ISNULL((SELECT SUM(Qty) FROM tSaleLineItem 
              WHERE PurchaseId = @PurchaseId AND IsActive = 1), 0))

This is what I am trying

SELECT * 
FROM tPurchaseLineItem

SELECT dbo.fnGetStockByPurchase(4)

INSERT INTO tSaleLineItem(InvoiceId, proId,Qty,Price, PurchaseId) 
VALUES (2, 1, 10, 100, 4)

Messages tab shows

(3 rows affected)

(1 row affected)

Msg 547, Level 16, State 0, Line 7
The INSERT statement conflicted with the CHECK constraint "CK_tSaleLineItem_Qty". The conflict occurred in database "testDb", table "dbo.tSaleLineItem".

Result tab shows

Id  InvoiceId   proId   Qty Price   IsActive
--------------------------------------------
4   2           1       10  100     1
5   2           1       10  100     1
6   2           1       10  100     1

(No column name)
10

I want my current INSERT query to insert data as [Qty] is equal to available quantity.

Shouldn't it be:

RETURN 
(ISNULL((SELECT SUM(Qty) FROM tSaleLineItem 
         WHERE Id = @PurchaseId AND IsActive = 1), 0)
- ISNULL((SELECT Qty FROM tPurchaseLineItem 
          WHERE PurchaseId = @PurchaseId AND IsActive = 1), 0))

Because if you have two Purchases function returns negative value and hence constraint violation

I debugged the function body by converting into following block

DECLARE @PurchaseId INT;
DECLARE @Qty INT;
DECLARE @QtyP INT;
DECLARE @QtyS INT;
SET @PurchaseId=4;
SET @Qty =10;

SELECT @QtyS =  ISNULL(SUM(Qty),0) FROM tSaleLineItem 
         WHERE PurchaseId = @PurchaseId AND IsActive = 1;
SELECT @QtyP =  ISNULL(SUM(Qty),0) FROM tPurchaseLineItem 
         WHERE Id = @PurchaseId AND IsActive = 1;
PRINT 'QtyP';
PRINT @QtyP;
PRINT 'QtyS';
PRINT @QtyS;
PRINT 'QtyP-QtyS';
PRINT @QtyP - @QtyS

IF((@QtyP-@QtyS)>=@Qty)
          PRINT 'True';
ELSE
          PRINT 'False';

what i found is order of SUM() and ISNULL() . In my question I have written it as ISNULL(SUM)) which resulted in null while SUM(ISNULL()) resulted in zero although in both cases there is no row in tSaleLineItem . The Above block resulted in

 QtyP 10 QtyS 0 QtyP-QtyS 10 True 

although I am still wondering why it inserted half or less quantity, though it is not the headache now.

The summary is still blowing my mind. I cannot understand this too.

DECLARE @QtyS INT;

SELECT @QtyS =  SUM(ISNULL(Qty,0)) FROM tSaleLineItem 
PRINT 'QtyS';
PRINT @QtyS;

SELECT @QtyS =  ISNULL(SUM(Qty),0) FROM tSaleLineItem 
PRINT 'QtyS';
PRINT @QtyS;

the output is

 QtyS QtyS 0 

However, Thank you all for your valuable comments and help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM