2012-06-30 4 views
3

У меня есть значение default в таблице SQL Server 2008.Alter «По умолчанию» в SQL Server

Подобно этому

CREATE DEFAULT [dbo].[Default_Timestamp] 
AS 
    GetDate() 

Теперь я хочу, чтобы изменить значение в этом умолчанию.

CREATE DEFAULT [dbo].[Default_Timestamp] 
AS 
    GETUTCDATE() 

Прежде чем я смогу отредактировать существующий, мне нужно отбросить первый и заново создать его.

DROP DEFAULT [dbo].[Default_Timestamp] 

дает следующую ошибку.

Msg 3716, Level 16, State 3, 4 линия
по умолчанию 'dbo.Default_Timestamp' не может быть удален, потому что он связан с одним или несколькими колонкой.

Поскольку по умолчанию уже используется несколько таблиц, я не могу сбросить и воссоздать новый.

Я знаю, что мне нужно отвязать все таблицы от этого значения по умолчанию, прежде чем я смогу его воссоздать.

Может ли кто-нибудь предоставить скрипт для отображения всех таблиц и столбцов, связанных с этим значением по умолчанию?

ответ

4

Это многоэтапный процесс:

1) Найдите object_id для по умолчанию:

DECLARE @DefaultObjectID INT 
SELECT @DefaultObjectID = OBJECT_ID('Default_Timestamp') 

2) Найти все столбцы, которые ссылаются, что по умолчанию:

SELECT 
    ColumnName = c.Name, 
    TableName = t.Name, 
    UnbindCmd = 'EXEC sp_unbindefault ''' + t.Name + '.' + c.name + '''' 
FROM sys.columns c 
INNER JOIN sys.tables t ON c.object_id = t.object_id 
WHERE default_object_id = @DefaultObjectID 

Это создаст список команд UnbindCmd, чтобы фактически удалить DEFAULT из этих столбцов.

3) Теперь скопируйте этот столбец из окна SQL Server Mgmt студии, и выполнить его в новом окне запроса на самом деле «отвязать» по умолчанию от всех этих столбцов

4) Теперь определите новое значение по умолчанию

Однако: в эти дни, я бы, вероятно, не определить новый DEFAULT сами по себе - вы не можете просто установить ограничение по умолчанию на столбцах вопрос напрямую?

ALTER TABLE dbo.YourTable 
ADD CONSTRAINT DF_YourTable_TimeStamp 
DEFAULT GETUTCDATE() FOR YourColumnName 

Кажется, что легче работать с входом в будущее! Когда вы явно укажете свое ограничение, вы также можете легко найти и удалить это ограничение, если потребуется.

1

Я никогда не видел CREATE DEFAULT или DROP DEFAULT как автономные команды, но знаю только условие CONSTRAINT, чтобы добавить или удалить ограничение по умолчанию.

SSMS 2008 генерирует следующий код (щелкните правой кнопкой мыши в конструкторе таблиц, "Сформировать Change Script ..."):

ALTER TABLE dbo.T ADD CONSTRAINT 
    DF_T_DateTimeColumn DEFAULT getdate() FOR DateTimeColumn 
GO 

ALTER TABLE dbo.T 
    DROP CONSTRAINT DF_T_DateTimeColumn 
GO 
ALTER TABLE dbo.T ADD CONSTRAINT 
    DF_T_DateTimeColumn DEFAULT getutcdate() FOR DateTimeColumn 
GO 

обновление:

Я признаю это, я никогда не использовал EXEC sp_bindefault, но я думаю, что его использование не рекомендуется, так как MSDN говорит:

Эта функция будет удалена в будущей версии Microsoft SQL Server. Не используйте эту функцию в новых разработках и не изменяйте приложения , которые в настоящее время используют эту функцию как можно скорее. We рекомендуем создавать определения по умолчанию, используя вместо этого ключевое слово DEFAULT инструкций ALTER TABLE или CREATE TABLE.

Это относится к sp_unbindefault, конечно.

1

Вы можете найти столбцы, которые используют объект по умолчанию, глядя на default_object_id в sys.columns:

ID объекта по умолчанию, независимо от того, является ли это автономный объект sys.sp_bindefault, или встроенное ограничение по умолчанию DEFAULT .

Зная это тривиально, чтобы построить сценарий, который развязывает все столбцы из объекта по умолчанию и заменяет по умолчанию со значением по умолчанию ограничения на основе:

use master; 
go 

if db_id('test') is not null 
    drop database test; 
go 

create database test; 
go 

use test; 
go 

create default foo as 1; 
go 

create table t1 (a int); 
create table t2 (b int); 
go 

exec sp_bindefault 'foo', 't1.a'; 
exec sp_bindefault 'foo', 't2.b'; 
go 

drop default foo; 
-- Msg 3716, Level 16, State 3, Line 2 
-- The default 'foo' cannot be dropped because it is bound to one or more column. 
go 

declare crs cursor static forward_only read_only for 
select object_schema_name(object_id) as schema_name, 
     object_name(object_id) as object_name, 
     name as column_name 
    from sys.columns where default_object_id = object_id('foo'); 
open crs; 

declare @schema_name sysname, @object_name sysname, @column_name sysname, @sql nvarchar(max); 

fetch next from crs into @schema_name, @object_name, @column_name; 
while @@fetch_status = 0 
begin 
    set @sql = N'exec sp_unbindefault ' + quotename(
     quotename(@schema_name) + N'.'+ 
     quotename(@object_name) + N'.'+ 
     quotename(@column_name), ''''); 
    print @sql; 
    exec sp_executesql @sql; 
    set @sql = N'alter table ' + 
     quotename(@schema_name) + N'.' + 
     quotename(@object_name) + N' add constraint ' + 
     quotename(N'default_' + @column_name) + N' default 2 for ' + 
     quotename(@column_name); 
    print @sql; 
    exec sp_executesql @sql; 
    fetch next from crs into @schema_name, @object_name, @column_name; 
end 

close crs; 
deallocate crs; 
go 

drop default foo; 
-- it now succeeds 
go 
Смежные вопросы