2012-06-30 40 views
3

我有一個SQL Server 2008中的表自定義default值。阿爾特「默認」在SQL Server

這個

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

類似現在我想更改該默認值。

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

在我可以編輯現有的之前,我需要刪除第一個並重新創建它。

DROP DEFAULT [dbo].[Default_Timestamp] 

它給出以下錯誤。

消息3716,級別16,狀態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管理Studio窗口該列,並在新的查詢窗口中執行它實際上是「解除綁定」所有這些列默認

4)現在定義新的默認

但是:這些日子裏,我可能會定義一個新的DEFAULT本身 - 你就不能設置默認的直接問題列約束?

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

似乎更容易與未來的工作!當明確指定約束時,如果需要,還可以輕鬆找到並再次刪除該約束。

1

我從來沒見過CREATE DEFAULT或DROP DEFAULT作爲獨立的命令,但只知道約束子句來添加或刪除默認約束。

SSMS 2008生成以下代碼(右鍵單擊表設計器 「生成更改腳本...」):

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的未來版本中刪除。請勿在新開發工作中使用此功能,並儘快修改當前使用此功能的應用程序。我們 建議您使用ALTER TABLE的DEFAULT 關鍵字創建默認定義或CREATE TABLE語句來代替。

當然,這也適用於sp_unbindefault

1

你可以發現,通過看default_object_idsys.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