Álv*_*lez 5 sql-server-2008 sql-server ssms t-sql
我有一个表,我错误地在列中允许 NULL 值:
CREATE TABLE EXAMPLE (
EXAMPLE_ID INT IDENTITY(1, 1) NOT NULL,
FOO_ID INT,
CREATED_ON DATETIME DEFAULT CURRENT_TIMESTAMP, -- Oops!
CODE VARCHAR(50),
QUOTE DECIMAL(18,2),
BAR_ID TINYINT NOT NULL DEFAULT 1,
CONSTRAINT EXAMPLE_PK PRIMARY KEY (EXAMPLE_ID),
CONSTRAINT EXAMPLE_FK1 FOREIGN KEY (FOO_ID)
REFERENCES FOO (FOO_ID)
ON DELETE CASCADE,
CONSTRAINT EXAMPLE_FK2 FOREIGN KEY (BAR_ID)
REFERENCES BAR (BAR_ID)
);
CREATE INDEX EXAMPLE_IDX1 ON EXAMPLE (FOO_ID);
CREATE INDEX EXAMPLE_IDX2 ON EXAMPLE (BAR_ID);
Run Code Online (Sandbox Code Playgroud)
这是一个相当不重要的列(没有索引,没有外键,没有在触发器中使用......),这是我通常修复它的方式:
ALTER TABLE EXAMPLE
ALTER COLUMN CREATED_ON DATETIME NOT NULL;
-- Runs in 1 second
Run Code Online (Sandbox Code Playgroud)
但是,我决定使用 GUI 工具(SQL Server Management Studio,但我尝试过的所有其他工具都做类似的事情),发现整个过程大约需要 20 分钟。原因?自动生成的更改代码是一个 3351 行的脚本,它显然试图编辑数据库中具有指向EXAMPLE.EXAMPLE_ID
!
ALTER TABLE dbo.SOME_OTHER_TABLE
DROP CONSTRAINT SOME_OTHER_TABLE_FK
GO
BEGIN TRANSACTION
GO
ALTER TABLE dbo.SOME_OTHER_TABLE ADD CONSTRAINT
SOME_OTHER_TABLE_FK FOREIGN KEY
(
EXAMPLE_ID
) REFERENCES dbo.EXAMPLE
(
EXAMPLE_ID
) ON UPDATE NO ACTION
ON DELETE CASCADE
GO
ALTER TABLE dbo.SOME_OTHER_TABLE SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
Run Code Online (Sandbox Code Playgroud)
进一步挖掘表明,该脚本Tmp_EXAMPLE
使用最终定义创建了一个新表,并将所有数据从EXAMPLE
.
这个复杂的过程有必要吗?plain 的确切问题是ALTER TABLE
什么?
NULL
只需将当前值更新为默认值即可。
然后做你的ALTER TABLE
UPDATE [MyTable]
SET [MyColumn] = 0
WHERE [MyColumn] IS NULL;
ALTER TABLE [MyTable] ALTER COLUMN [MyColumn] INTEGER NOT NULL;
Run Code Online (Sandbox Code Playgroud)
UPDATE [MyTable]
SET [MyColumn] = ''
WHERE [MyColumn] IS NULL;
ALTER TABLE [MyTable] ALTER COLUMN [MyColumn] VARCHAR(max) NOT NULL;
Run Code Online (Sandbox Code Playgroud)
在此之前,请确保备份数据库,以防万一搞砸了
SSMS 制作的整个复杂场景是没有必要的,做一个简单的场景是没有问题的ALTER TABLE