插入/更新时如何验证字段的最佳方法

时间:2018-03-01 11:04:00

标签: sql-server validation tsql user-defined-functions

我正在尝试使用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'.

提前致谢!

1 个答案:

答案 0 :(得分:4)

您可以使用namestate<>'Removed'上的UNIQUE FILTERED INDEX进行尝试:

CREATE UNIQUE INDEX uix_name
ON dbo.test_name_uniq (name)
WHERE where state<> 'Removed';

希望它有所帮助。