我正在尝试使用CHECK + UDF应用自定义验证,尽管如此,在我的情况下它不能正常工作,而且在搜索之后有一种观点认为这种方法可能会影响性能并且它不健壮。
在T-SQL中有一些现有工具可以解决我的问题吗?
这是我的sql:
DROP TABLE IF EXISTS dbo.test_name_uniq;
CREATE TABLE dbo.test_name_uniq (
name VARCHAR(255),
state VARCHAR(255)
)
ALTER TABLE dbo.test_name_uniq DROP CONSTRAINT IF EXISTS test_name_uniq_constraint;
DROP FUNCTION IF EXISTS dbo.validate_test_name_uniq;
GO
CREATE FUNCTION dbo.validate_test_name_uniq(@name VARCHAR(255))
RETURNS BIT
AS
BEGIN
DECLARE @unique_name BIT = 0;
SELECT @unique_name = CASE
WHEN COUNT(*) > 0
THEN 0
ELSE 1
END
FROM dbo.test_name_uniq i
WHERE i.name = @name AND i.state <> 'Removed';
RETURN @unique_name;
END;
GO
ALTER TABLE dbo.test_name_uniq
WITH NOCHECK ADD CONSTRAINT test_name_uniq_constraint CHECK (dbo.validate_test_name_uniq(name) = 1 );
GO
DELETE FROM dbo.test_name_uniq;
GO
INSERT INTO dbo.test_name_uniq (name, state) VALUES
('Test application', 'Active');
每当我尝试插入一行时,都会收到错误:
The INSERT statement conflicted with the CHECK constraint "test_name_uniq_constraint". The conflict occurred in database "data_local_test", table "dbo.test_name_uniq", column 'name'.
提前致谢!
答案 0 :(得分:4)
您可以使用name
栏state<>'Removed'
上的UNIQUE FILTERED INDEX进行尝试:
CREATE UNIQUE INDEX uix_name
ON dbo.test_name_uniq (name)
WHERE where state<> 'Removed';
希望它有所帮助。