All infos - Check constraint на два столбца.

Check constraint на два столбца.

Задача: Создать check constraint на двастолбца так, чтобы нельзя было добавить совпадающее значение по одному столбцу, но различающееся по другому. При этом, если есть совадение по обоим столбцам, то добавление возможно и если нет совпадений в обоих столбцах, то добавление возможно.

USE master;
GO

IF DB_ID (N'Test') IS NULL
CREATE DATABASE Test;
GO

USE Test
GO
IF OBJECT_ID(N'dbo.User', N'U') IS NOT NULL  
   DROP TABLE [dbo].[User];  
GO

CREATE TABLE dbo.[User](
Id INT Null,
[Name] VARCHAR(50) Null
) 
GO

USE test
GO

IF object_id(N'dbo.CheckUserId', N'FN') IS NOT NULL
    DROP FUNCTION function_name
GO

CREATE FUNCTION dbo.CheckUserId (@id INT, @name VARCHAR(50))
RETURNS INT
AS 
BEGIN
  DECLARE @Amount INT, @IsValid BIT = 0
    SELECT @Amount = COUNT(*)
    FROM dbo.[User]    
	WHERE Id = @id and [Name] <> @name OR Id <> @id AND [Name] = @name
	IF( @Amount < 1)BEGIN SET @IsValid = 1 END ELSE SET @IsValid = 0
  RETURN @IsValid
END;
GO
-- drop function dbo.CheckUserId

ALTER TABLE dbo.[User] 
  ADD CONSTRAINT chkUser 
  CHECK(1 =  dbo.CheckUserId(Id, [Name]))
  
  --  alter table dbo.[User] drop constraint chkUser
GO

INSERT INTO dbo.[User](
Id,
[Name])
VALUES(
6,'z')
GO 

--это вставит т.к. значения обоих столбцов совпадают
INSERT INTO dbo.[User](
Id,
[Name])
VALUES(
6,'z')
GO

--это вставит т.к. значения обоих столбцов не совпадают
INSERT INTO dbo.[User](
Id,
[Name])
VALUES(
1,'ы')
GO
--здесь будет ошибка ограничения, т.к. есть совпадения по только одному столбцу
INSERT INTO dbo.[User](
Id,
[Name])
VALUES(
6,'y')
GO

--здесь будет ошибка ограничения, т.к. есть совпадения по только одному столбцу
INSERT INTO dbo.[User](
Id,
[Name])
VALUES(
6,'y')

Share this post

Оцените материал
(99 голосов)
Прочитано 2981 раз
Другие материалы в этой категории: « Определение недостающих индексов в SQL Server