How can I validate data before insert/update with

2019-03-01 06:19发布

问题:

I have a table defined like this

CREATE TABLE [dbo].[ObjectRelationClauses]
(
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [RelationId] INT NOT NULL, 
    [OperatorType] NVARCHAR(3) NOT NULL, 
    [LocalPropertyId] INT NOT NULL, 
    [ForeignPropertyId] INT NULL, 
    [ForeignValue] VARCHAR(255) NULL, 
    [ParentClauseId] INT NULL
)

I need to be able to raise an error if the value of both ForeignPropertyId and ForeignValue columns both null, otherwise I want to perform the operation.

Here is what I tried

CREATE TRIGGER [dbo].[Trigger_ObjectRelationClauses]
    ON [dbo].[ObjectRelationClauses]
    FOR INSERT, UPDATE
    AS
    BEGIN
        SET NoCount ON
        IF(ForeignPropertyId IS NULL AND ForeignValue IS NULL)
        BEGIN
           RAISERROR('Either ForeignPropertyId or ForeignValue must be provided to perform this action!')
        END

    END

but this gives me a syntax error. Perhaps, the way I am using RAISERROR is wrong.

How can I correctly add a trigger to validate the data on INSERT and UPDATE?

回答1:

This looks like a job for a check constraint, not a trigger:

ALTER TABLE [dbo].[ObjectRelationClauses]
ADD CONSTRAINT foreign_chk CHECK 
([ForeignPropertyId] IS NOT NULL OR [ForeignValue] IS NOT NULL);


回答2:

You can add a constraint. However, if you are inserting multiple rows, then the constraint will prevent any rows from being inserted. To get around this, you can use an instead of trigger.

But, it might be easier simply to do:

insert into ObjectRelationClauses(. . .)
    select . . .
    from . . .
    where ForeignPropertyId is not null or ForeignValue is not null;

If you insert one row at a time, then the constraint is the way to go.



回答3:

Because the SQL server dont know which record you are referring as per ForeignPropertyId and ForeignValue.

1) You should have taken use of the MAGIC TABLE. inserted.ForeignPropertyId is NULL AND inserted.ForeignValue is NULL.

2) You can use Instead Of trigger, not the For/After trigger.

If you are not that comfortable with trigger, my advice is not to use them too much. It will give you headache in the future.



回答4:

RAISERROR Required Levels of Severity & State . Please use this query

CREATE TRIGGER [dbo].[Trigger_ObjectRelationClauses]
ON [dbo].[ObjectRelationClauses]
FOR INSERT, UPDATE
AS
BEGIN
    SET NoCount ON;
    DECLARE @ForeignPropertyId INT ,@ForeignValue varchar(255)
     Select @ForeignPropertyId=  i.ForeignPropertyId, @ForeignValue = i.ForeignValue from Inserted i
    IF(@ForeignPropertyId IS NULL AND @ForeignValue IS NULL)
    BEGIN
       RAISERROR ('Either ForeignPropertyId or ForeignValue must be provided to perform this action!',16,1)
    END

END


回答5:

Why can't you USE SQL NOT NULL Constraint ?

The NOT NULL constraint enforces a column to NOT accept NULL values.

You can alter your existing column by referring below snippet.

ALTER TABLE [Table] ALTER COLUMN [Column] INTEGER NOT NULL;