添加带条件的 SQL Server 约束

huangapple go评论91阅读模式
英文:

Add constraint to SQL Server with condition

问题

我想添加一个约束,要求每个员工的employee_year都小于其经理的employee_year,并且我们知道每个经理本身也是一名员工。因此,我编写了以下代码:

  1. ALTER TABLE employee
  2. ADD CONSTRAINT CK_EmployeeYearLessThanManager
  3. CHECK (employee_year <= (SELECT m.employee_year
  4. FROM employee m
  5. WHERE m.employee_number = manager_employee_number ));

我遇到了以下错误:

不允许在此上下文中使用子查询。只允许使用标量表达式。

是否有可能以某种方式编写这样的约束?

英文:

Consider this table

  1. CREATE TABLE employee
  2. (
  3. employee_number INT PRIMARY KEY,
  4. employee_name NVARCHAR(100),
  5. employee_year INT,
  6. manager_employee_number INT,
  7. salary INT,
  8. FOREIGN KEY(manager_employee_number)
  9. REFERENCES employee(employee_number)
  10. );

I want to add a constraint which every employee's employee_year is less than his manager's and we know every manager is an employee himself. So I wrote this:

  1. ALTER TABLE employee
  2. ADD CONSTRAINT CK_EmployeeYearLessThanManager
  3. CHECK (employee_year &lt;= (SELECT m.employee_year
  4. FROM employee
  5. WHERE m.employee_number = manager_employee_number ));

I get this error:

> Subqueries are not allowed in this context. Only scalar expressions are allowed

Is there any possible way to write such a constraint?

答案1

得分: 1

根据错误信息可以看出,你不能将它实现为子查询,但作为一种解决方法,你可以创建一个标量值的用户定义函数,并从检查约束中调用它。这里有一个示例:

  1. CREATE TABLE employee
  2. (
  3. employee_number INT PRIMARY KEY,
  4. employee_name NVARCHAR(100),
  5. employee_year INT,
  6. manager_employee_number INT,
  7. salary INT,
  8. FOREIGN KEY(manager_employee_number)
  9. REFERENCES employee(employee_number)
  10. );
  11. GO
  12. CREATE FUNCTION dbo.get_manager_hire_year(@manager_employee_number INT)
  13. RETURNS INT
  14. AS
  15. BEGIN
  16. DECLARE @e_year int;
  17. SELECT @e_year = employee_year
  18. FROM employee
  19. WHERE employee_number = @manager_employee_number;
  20. RETURN @e_year
  21. END
  22. GO
  23. ALTER TABLE employee
  24. ADD CONSTRAINT CK_EmployeeYearLessThanManager
  25. CHECK (employee_year <= dbo.get_manager_hire_year(manager_employee_number))
英文:

As it can be seen from the error message, you cannot implement it as a subquery, but as a work around you can create a scalar-valued user defined function and call it from the check constraint. Here is an example:

  1. CREATE TABLE employee
  2. (
  3. employee_number INT PRIMARY KEY,
  4. employee_name NVARCHAR(100),
  5. employee_year INT,
  6. manager_employee_number INT,
  7. salary INT,
  8. FOREIGN KEY(manager_employee_number)
  9. REFERENCES employee(employee_number)
  10. );
  11. GO
  12. CREATE FUNCTION dbo.get_manager_hire_year(@manager_employee_number INT)
  13. RETURNS INT
  14. AS
  15. BEGIN
  16. DECLARE @e_year int;
  17. SELECT @e_year = employee_year
  18. FROM employee
  19. WHERE employee_number = @manager_employee_number;
  20. RETURN @e_year
  21. END
  22. GO
  23. ALTER TABLE employee
  24. ADD CONSTRAINT CK_EmployeeYearLessThanManager
  25. CHECK (employee_year &lt;= dbo.get_manager_hire_year(manager_employee_number))

huangapple
  • 本文由 发表于 2023年2月7日 01:38:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75364730.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定