SQL Server 2012 check constraint error on udf - sql

Just trying to make a simple function in SQL Server 2012 to be used as a check constraint. Cant get past this error. Thanks for any help!
The error I receive:
Msg 547, Level 16, State 0, Line 1 The ALTER TABLE statement
conflicted with the CHECK constraint "CheckBatchQuantity". The
conflict occurred in database "Ians23_SnackManufacturer", table
"dbo.Batch", column 'BatchQuantity'.
Code:
CREATE FUNCTION udfBatchNumber2
(#BatchQuantity int)
RETURNS int
AS
BEGIN
DECLARE #Return int
IF #BatchQuantity >10
SET #Return = 0
ELSE
SET #Return = 1
RETURN #Return
END
ALTER TABLE Batch
ADD CONSTRAINT CheckBatchQuantity
check ((dbo.[udfBatchNumber](BatchQuantity)) <= 0)

The error is due to existing records in Batch table whose BatchQuantity is greater than zero.
First update/remove the records whose BatchQuantity > 0 then create the check constraint
update Batch
set BatchQuantity = NULL
Where BatchQuantity > 0
ALTER TABLE Batch
ADD CONSTRAINT CheckBatchQuantity
check ((dbo.[udfBatchNumber](BatchQuantity)) <= 0)
or you can create the constraint with NOCHECK which will not check the existing data
ALTER TABLE Batch WITH NOCHECK
ADD CONSTRAINT CheckBatchQuantity
check ((dbo.[udfBatchNumber](BatchQuantity)) <= 0)

Related

Constraint on column to set limit of possible values

I need to put a constraint on a column so that it can only contain the following range of values
Allowed values: between 1 and 10
Column Data Type: tinyint
DBMS or Docker Image: Microsoft SQL Server - mcr.microsoft.com/mssql/server:2019-latest
I believe it should be something close to this
ALTER TABLE [dbo].[Projects]
ADD CONSTRAINT chk_val_limit CHECK (Priority in (between 1 and 10))
GO
You can try this one!
ALTER TABLE [dbo].[Projects]
ADD CONSTRAINT chk_val_limit CHECK (ColumnName > 1 AND ColumnName < 10)
GO

Invalid Identifier in ALTER TABLE ADD COLUMN

I'm getting the error "Invalid Identifier" whilst running this ALTER TABLE statement:
ALTER TABLE TRUCK ADD COLUMN WEIGHT INTEGER NOT NULL;
The syntax is like this, so I don't understand the error:
ALTER TABLE table_name ADD COLUMN column_name data_type[NOT NULL][UNIQUE]
The attribute WEIGHT doesn't need unique.
How do I include the "not greater than 1000" for the Integer data type into the Alter statement?
SQL Server:
ALTER TABLE TRUCK
ADD WEIGHT INT NOT NULL
This query will be helpful.
alter table truck
add column weight int not null default 0 check (weight < 1000)

How to add a new column and a constraint in one go?

I want to add a new column to an existing table.
I need it to emulate the enum type (in the way possible in SQL Server; with value constraints, that is).
The following doesn't work:
ALTER TABLE orders ADD [sent_to_panel] NVARCHAR(16) NULL;
ALTER TABLE orders WITH CHECK ADD CONSTRAINT [CK_orders] CHECK (([sent_to_panel]='invalidated' OR [sent_to_panel]='not_sent' OR [sent_to_panel]='sent'));
ALTER TABLE orders ADD CONSTRAINT [DF_orders_sent_to_panel] DEFAULT (N'not_sent') FOR [sent_to_panel];
ALTER TABLE orders CHECK CONSTRAINT [CK_orders];
I'm getting an error:
Msg 207, Level 16, State 1, Line 2
Invalid column name 'sent_to_panel'.
If I execute the first command on its own, though:
ALTER TABLE orders ADD [sent_to_panel] NVARCHAR(16) NULL;
The rest goes through.
So I suppose the problem is that the column isn't actually added yet (and thus not recognized by ADD CONSTRAINT) when trying to get it all done in one go.
The question is: how to make the script work properly?
CREATE TABLE a (
b int
);
ALTER TABLE a
ADD c nvarchar(16) NULL
, CONSTRAINT check_this CHECK (c IN ('invalidated', 'not_sent', 'sent'))
, CONSTRAINT defaultify DEFAULT ('not_sent') FOR c
;
ALTER TABLE a
CHECK CONSTRAINT check_this
;
DROP TABLE a;

Using a function in a SQL CHECK constraint

I am trying to replace simple CHECK constraint with an embedded function within a CHECK constraint however it doesn't seem to restrict the data I can enter. The constraint is to prevent product amount of less than 0.25 and more than 5,000. The original check worked fine, however the function doesn't seem to do anything at all.
The original constraint:
ALTER TABLE Prices
ADD CONSTRAINT CheckPrices CHECK ((Amount > 0.25) AND (Amount <= 5000.00))
The function:
ALTER FUNCTION dbo.CheckProductPrices
(
#productSKU int,
#priceDate smalldatetime
)
RETURNS bit
AS
BEGIN
DECLARE #retVal bit = 0
SELECT #retVal = CASE WHEN Amount > 0.25 AND Amount <= 5000.00 THEN 1 ELSE 0 END
FROM Prices
WHERE productSKU = #productSKU
AND priceDate = #priceDate
RETURN #retVal
END
The new CHECK constraint:
ALTER TABLE Prices
ADD CONSTRAINT CheckPrices CHECK (dbo.CheckProductPrices([productItem], [priceValidDate]) = 1)
I don't understand why the new constraint isn't stopping invalid prices the way the original constraint did.

Check constraint in SQL Server

I have three tables a,b and c and need to add a constraint like below for checking the data integrity
The below is wrong but I need help in enforcing the below condition.
ALTER TABLE [a]
ADD CONSTRAINT UOMGROUPIG CHECK UNITOFMEASURID IN (SELECT UnitOfMeasureId FROM b WHERE UOMGroupId=1 )
ALTER TABLE [c]
ADD CONSTRAINT UOMGROUPIG CHECK UNITOFMEASURID IN (SELECT UnitOfMeasureId FROM b WHERE UOMGroupId=2 )
Thanks
A scalar valued function like this works for your example, you can easily modify it and create your second constraint:
CREATE FUNCTION your_schema_name.udf_Check1(
#UNITOFMEASURID INT
)
RETURNS BIT
AS
BEGIN
DECLARE #returnValue BIT = 0
SELECT #returnValue = CASE WHEN COUNT(UnitOfMeasureId) > 0 THEN 1 ELSE 0 END
FROM your_schema_name.b
WHERE UOMGroupId=1
AND #UNITOFMEASURID = UnitOfMeasureId
RETURN #returnValue
END
GO
ALTER TABLE [a]
ADD CONSTRAINT UOMGROUPIG
CHECK (your_schema_name.udf_Check1(UNITOFMEASURID) = 1)
GO
Here is the example: SQL Fiddle
You cannot write query within Check constraint. Instead you can call user defined function.
You can use same function in both constraints by passing #UOMGroupId value along with UNITOFMEASURID.
CREATE FUNCTION CheckFnctn(#UNITOFMEASURID int, #UOMGroupId int)
RETURNS int
AS
BEGIN
if exists(SELECT UnitOfMeasureId FROM b WHERE UOMGroupId=#UOMGroupId
and UnitOfMeasureId = #UNITOFMEASURID)
BEGIN
RETURN 1;
END
RETURN 0; --missed this line
END;
ALTER TABLE [a]
ADD CONSTRAINT UOMGROUPIG CHECK (dbo.CheckFnctn(UNITOFMEASURID, 1)=1);
ALTER TABLE [c]
ADD CONSTRAINT UOMGROUPIG CHECK (dbo.CheckFnctn(UNITOFMEASURID, 2)=1);