【问题标题】:ALTER TABLE with programmatically determined constant DEFAULT valueALTER TABLE 具有以编程方式确定的常量 DEFAULT 值
【发布时间】:2009-03-18 19:05:20
【问题描述】:

我正在尝试将列 (MSSQL 2005) 添加到具有另一个表 (Department) 的主键的默认约束的表 (Employee) 中。然后,我要将此列设为该表的 FK。本质上,如果没有提供 DepartmentID,这将根据部门名称将新员工分配到基础部门。
这不起作用:

DECLARE     @ErrorVar       INT
DECLARE     @DepartmentID       INT

SELECT      @DepartmentID = DepartmentID
FROM        Department
WHERE       RealName = 'RocketScience'

ALTER TABLE     [Employee]
ADD             [DepartmentID] INT NULL
CONSTRAINT      [DepartmentIDOfAssociate] DEFAULT (@DepartmentIDAssociate)
SELECT @ErrorVar = @@Error
IF (@ErrorVar <> 0)
BEGIN
    GOTO FATAL_EXIT
END

生产、测试​​和开发数据库已经不同步,DepartmentName = ‘RocketScience’ 的 DepartmentID 可能相同也可能不同,所以我不想只说 DEFAULT(某个数字)。无论我以哪种方式解决问题,我都会不断收到“ALTER TABLE 语句中不允许使用变量”。
正确的方法是什么?我也尝试过嵌套 select 语句,它得到“在这种情况下不允许子查询。只允许标量表达式。”

此外,我可以在一个语句中填充列值而不是执行

{ALTER null}
{更新值}
{ALTER not null}

步骤。我阅读了有关 WITH VALUES 命令的一些内容,但无法使其正常工作。 谢谢!!!

【问题讨论】:

    标签: sql-server tsql default alter-table


    【解决方案1】:

    接受的答案效果很好(感谢 marc_s),但在我考虑了一段时间后,我决定走另一条路。
    主要是因为服务器上必须有一个我认为最终会被调用的函数每次添加员工时。
    如果后来有人弄乱了该功能,那么没有人可以输入员工,原因也不会很明显。 (即使这不是真的,那么服务器上仍然有不需要的额外功能)

    我所做的是将命令动态组装到一个变量中,然后使用 EXECUTE 命令调用它。

    不仅如此,由于我使用了带 NOT NULL 的 DEFAULT 关键字,因此表被重新填充,我不必运行多个命令来完成它。我很幸运地找到了那个...

    DECLARE     @ErrorVar                   INT
    DECLARE     @DepartmentIDRocketScience          INT
    DECLARE     @ExecuteString                  NVARCHAR(MAX)
    
    SELECT          @DepartmentIDRocketScience = DepartmentID
    FROM            Department
    WHERE           RealName = 'RocketScience'
    
    SET @ExecuteString = ''
    SET @ExecuteString = @ExecuteString + 'ALTER TABLE      [Employee] '
    SET @ExecuteString = @ExecuteString + 'ADD              [DepartmentID] INT NOT NULL '
    SET @ExecuteString = @ExecuteString + 'CONSTRAINT       [DF_DepartmentID_RocketScienceDepartmentID] DEFAULT ' +CAST(@DepartmentIDAssociate AS NVARCHAR(MAX))
    EXECUTE (@ExecuteString)
    SELECT @ErrorVar = @@Error
    IF (@ErrorVar <> 0)
    BEGIN
        GOTO FATAL_EXIT
    END
    

    【讨论】:

    • 这是一个很好的答案。这解决了我的批量插入问题,每次执行函数都会超时。
    【解决方案2】:

    您可以将用于查找部门 ID 的代码包装到一个存储函数中,并在您的 DEFAULT 约束语句中使用它:

    CREATE FUNCTION dbo.GetDepartment()
    RETURNS INT
    AS
    BEGIN
      DECLARE         @DepartmentID           INT
    
      SELECT          @DepartmentID = DepartmentID
      FROM            Department
      WHERE           RealName = 'RocketScience'
    
      RETURN @DepartmentID
    END
    

    然后:

    ALTER TABLE     [Employee]
    ADD                     [DepartmentID] INT NULL
    CONSTRAINT      [DepartmentIDOfAssociate] DEFAULT (dbo.GetDepartment())
    

    这有帮助吗?

    马克

    【讨论】:

    • 试一试 - 我做到了 - 为我工作(在 SQL Server 2008 上,也就是说 - 但我怀疑这在 2005 年和 2008 年之间发生了变化)
    【解决方案3】:

    如果在添加列后应用外键约束,则在更改表时可以使用任何值作为默认值。然后您可以使用您的变量值运行更新语句。

    ALTER TABLE Employee 
    ADD DepartmentID INT NOT NULL
    Default -1;
    
    UPDATE Employee
    SET Employee.DepartmentID = @DepartmentID
    WHERE DepartmentID = -1;
    
    ALTER TABLE Employee 
    ADD CONSTRAINT fk_employee_to_department FOREIGN KEY (DepartmentID) 
    REFERENCES Department;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多