2009-09-16 12 views
163

In Microsoft SQL Server, ich weiß, die Abfrage Einschränkung, wenn ein Standardwert für eine Spalte vorhanden zu überprüfen und eine Standardeinschränkung fallen ist:Wie SQL-Standardeinschränkung zu löschen, ohne seinen Namen zu kennen?

IF EXISTS(SELECT * FROM sysconstraints 
    WHERE id=OBJECT_ID('SomeTable') 
    AND COL_NAME(id,colid)='ColName' 
    AND OBJECTPROPERTY(constid, 'IsDefaultCnst')=1)  
ALTER TABLE SomeTable DROP CONSTRAINT DF_SomeTable_ColName 

Aber wegen in früheren Versionen der Datenbank Typo, der Name des Constraint könnte DF_SomeTable_ColName oder DF_SmoeTable_ColName sein.

Wie kann ich die Standardbedingung ohne SQL-Fehler löschen? Standard-Constraint-Namen werden nicht in der Tabelle INFORMATION_SCHEMA angezeigt, was die Sache ein wenig komplizierter macht.

So etwas wie 'löschen Sie die Standardbedingung in dieser Tabelle/Spalte' oder 'löschen DF_SmoeTable_ColName', aber keine Fehler geben, wenn es nicht finden kann.

+1

Ich bin nicht kompetent mit SQL Server können Sie eine Einschränkung umbenennen, nachdem Sie seine herausgefunden Name? "Ändern Sie die Tabelle in einigen Fällen in xy in yyy umbenennen". –

Antwort

232

Aufbauend auf Mitch Wheat den Code, wird das folgende Skript generieren, den Befehl Löschen Sie die Abhängigkeit und führen Sie sie dynamisch aus.

declare @schema_name nvarchar(256) 
declare @table_name nvarchar(256) 
declare @col_name nvarchar(256) 
declare @Command nvarchar(1000) 

set @schema_name = N'MySchema' 
set @table_name = N'Department' 
set @col_name = N'ModifiedDate' 

select @Command = 'ALTER TABLE ' + @schema_name + '.' + @table_name + ' drop constraint ' + d.name 
from sys.tables t 
    join sys.default_constraints d 
    on d.parent_object_id = t.object_id 
    join sys.columns c 
    on c.object_id = t.object_id 
    and c.column_id = d.parent_column_id 
where t.name = @table_name 
    and t.schema_id = schema_id(@schema_name) 
    and c.name = @col_name 

--print @Command 

execute (@Command) 
+0

Überprüfen Sie http://Stackoverflow.com/a/15786313/2049986, um eine Version zu sehen, alle Einschränkungen für eine Tabelle zu löschen –

+0

Ich verwende *** sys.check_constraints ***, nicht *** sys .default_constraints *** – Kiquenet

+0

*** Nicht gültig *** wenn einige Spalten, die *** mehrere *** _default-Einschränkungen oder Check-Constraints_ hatten, erstellt wurden, nur für *** last constraints *** in Abfrage ausgeführt. – Kiquenet

229

Rob Farley Blog-Post von Hilfe sein könnten:

Etwas wie:

declare @table_name nvarchar(256) 
declare @col_name nvarchar(256) 
set @table_name = N'Department' 
set @col_name = N'ModifiedDate' 

select t.name, c.name, d.name, d.definition 
from 
    sys.tables t 
    join sys.default_constraints d on d.parent_object_id = t.object_id 
    join sys.columns c on c.object_id = t.object_id 
          and c.column_id = d.parent_column_id 
where 
    t.name = @table_name 
    and c.name = @col_name 
+1

Beste Antwort auf diese Frage – gdmanandamohon

10

Um Einschränkung für mehrere Spalten fallen:

declare @table_name nvarchar(256) 

declare @Command nvarchar(max) = '' 

set @table_name = N'ATableName' 

select @Command = @Command + 'ALTER TABLE ' + @table_name + ' drop constraint ' + d.name + CHAR(10)+ CHAR(13) 
from sys.tables t 
join sys.default_constraints d 
on d.parent_object_id = t.object_id 
join sys.columns c 
on c.object_id = t.object_id 
and c.column_id = d.parent_column_id 
where t.name = @table_name 
and c.name in ('column1', 
'column2', 
'column3' 
) 

--print @Command 

execute (@Command) 
3

Tropfen alle Standard contstraints in einer Datenbank - sicher für nvarchar (max) Grenzwert.

/* WARNING: THE SAMPLE BELOW; DROPS ALL THE DEFAULT CONSTRAINTS IN A DATABASE */ 
/* MAY 03, 2013 - BY WISEROOT */ 
declare @table_name nvarchar(128) 
declare @column_name nvarchar(128) 
declare @df_name nvarchar(128) 
declare @cmd nvarchar(128) 

declare table_names cursor for 
SELECT t.name TableName, c.name ColumnName 
FROM sys.columns c INNER JOIN 
    sys.tables t ON c.object_id = t.object_id INNER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id 
    ORDER BY T.name, c.name 

    open table_names 
fetch next from table_names into @table_name , @column_name 
while @@fetch_status = 0 
BEGIN 

if exists (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name) 
BEGIN 
    SET @df_name = (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = @table_name and c.name = @column_name) 
    select @cmd = 'ALTER TABLE [' + @table_name + '] DROP CONSTRAINT [' + @df_name + ']' 
    print @cmd 
    EXEC sp_executeSQL @cmd; 
END 

    fetch next from table_names into @table_name , @column_name 
END 

close table_names 
deallocate table_names 
+0

*** Nicht gültig *** wenn einige Spalten, die *** mehrere *** _default-Einschränkungen oder Check-Constraints_ hatten, erstellt wurden, nur für *** Top 1-Bedingungen *** in Abfrage ausgeführt. – Kiquenet

79

fand ich, dass das funktioniert und verwendet keine Verknüpfungen:

DECLARE @ObjectName NVARCHAR(100) 
SELECT @ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS 
WHERE [object_id] = OBJECT_ID('[tableSchema].[tableName]') AND [name] = 'columnName'; 
EXEC('ALTER TABLE [tableSchema].[tableName] DROP CONSTRAINT ' + @ObjectName) 

So stellen Sie sicher, dass column nicht über Klammern um sie, da die Abfrage nach einer exakten Übereinstimmung sucht und nichts, wenn sie zurückkehren ist [SpaltenName].

+0

Und diese Antwort funktioniert mit anderen Schemata als dem Standard [dbo], im Gegensatz zu den anderen Antworten. – Contango

+0

Ich habe es nicht getestet, aber Sie können versuchen, und fügen Sie ein WHILE (@ObjectName IS NOT NULL) darum, setzen Sie TOP 1 vor SELECT (at) ObjectName = OBJECT_Name ([Standard ... und führen Sie nur die EXEC (' ALTER TA ... if (at) ObjectName ist NICHT NULL – ScubaSteve

+5

Um dieses Skript idempotent zu machen, fügen Sie 'IF @ObjectName IS NOT NULL' vor dem EXEC-Befehl hinzu – Seven

4

Expanded-Lösung (nimmt Tabellenschema berücksichtigt):

-- Drop default contstraint for SchemaName.TableName.ColumnName 
DECLARE @schema_name NVARCHAR(256) 
DECLARE @table_name NVARCHAR(256) 
DECLARE @col_name NVARCHAR(256) 
DECLARE @Command NVARCHAR(1000) 

set @schema_name = N'SchemaName' 
set @table_name = N'TableName' 
set @col_name = N'ColumnName' 

SELECT @Command = 'ALTER TABLE [' + @schema_name + '].[' + @table_name + '] DROP CONSTRAINT ' + d.name 
FROM sys.tables t 
    JOIN sys.default_constraints d  
    ON d.parent_object_id = t.object_id 
    JOIN sys.schemas s 
     ON s.schema_id = t.schema_id 
    JOIN sys.columns c  
    ON c.object_id = t.object_id  
    AND c.column_id = d.parent_column_id 
WHERE t.name = @table_name 
    AND s.name = @schema_name 
    AND c.name = @col_name 

EXECUTE (@Command) 
0

Ich hatte einige Spalten, die mehrere Standardeinschränkungen erstellt hatte, so schaffe ich die folgende gespeicherte Prozedur:

CREATE PROCEDURE [dbo].[RemoveDefaultConstraints] @table_name nvarchar(256), @column_name nvarchar(256) 
AS 
BEGIN 

    DECLARE @ObjectName NVARCHAR(100) 

    START: --Start of loop 
    SELECT 
     @ObjectName = OBJECT_NAME([default_object_id]) 
    FROM 
     SYS.COLUMNS 
    WHERE 
     [object_id] = OBJECT_ID(@table_name) 
     AND [name] = @column_name; 

    -- Don't drop the constraint unless it exists 
    IF @ObjectName IS NOT NULL 
    BEGIN 
     EXEC ('ALTER TABLE '[email protected]_name+' DROP CONSTRAINT ' + @ObjectName) 
     GOTO START; --Used to loop in case of multiple default constraints 
    END 
END 
GO 

-- How to run the stored proc. This removes the default constraint(s) for the enabled column on the User table. 
EXEC [dbo].[RemoveDefaultConstraints] N'[dbo].[User]', N'enabled' 
GO 

-- If you hate the proc, just get rid of it 
DROP PROCEDURE [dbo].[RemoveDefaultConstraints] 
GO 
1

Führen Sie diesen Befehl Um alle Einschränkungen zu durchsuchen:

exec sp_helpconstraint 'mytable' --and look under constraint_name. 

Es wird etwas wie t aussehen sein: DF__Mytable__Column__[ABC123]. Dann können Sie die Einschränkung einfach fallen lassen.

+0

Funktioniert nicht für mich: 'exec sp_helpconstraint 'Rollen2016.UsersCRM'' – Kiquenet

+0

@Kiquenet Sollte nur der Tabellenname sein: exec sp_helpconstraint' Roles2016 ' –

+0

Es zeigt nur Fremdschlüssel Constaints. nicht Standardwert constaint – Ronnie

0

nützlich für einige Spalten, die mehrdefault constraints or check constraints erstellt hatten:

Modified https://stackoverflow.com/a/16359095/206730 Skript

Hinweis: Dieses Skript ist für sys.check_constraints

declare @table_name nvarchar(128) 
declare @column_name nvarchar(128) 
declare @constraint_name nvarchar(128) 
declare @constraint_definition nvarchar(512) 

declare @df_name nvarchar(128) 
declare @cmd nvarchar(128) 

PRINT 'DROP CONSTRAINT [Roles2016.UsersCRM].Estado' 

declare constraints cursor for 
select t.name TableName, c.name ColumnName, d.name ConstraintName, d.definition ConstraintDefinition 
from sys.tables t 
join sys.check_constraints d on d.parent_object_id = t.object_id 
join sys.columns c on c.object_id = t.object_id  
and c.column_id = d.parent_column_id 
where t.name = N'Roles2016.UsersCRM' and c.name = N'Estado' 

open constraints 
fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition 
while @@fetch_status = 0 
BEGIN 
    print 'CONSTRAINT: ' + @constraint_name 
    select @cmd = 'ALTER TABLE [' + @table_name + '] DROP CONSTRAINT [' + @constraint_name + ']' 
    print @cmd 
    EXEC sp_executeSQL @cmd; 

    fetch next from constraints into @table_name , @column_name, @constraint_name, @constraint_definition 
END 

close constraints 
deallocate constraints 
0

I hoffe das s könnte hilfreich sein für wen hat ähnliches Problem. Wählen Sie im Fenster Ihre Datenbank => Tabellen, => Ihre Tabelle => Einschränkungen. Wenn der Kunde in der create column time definiert ist, können Sie den Standardnamen der Einschränkung einschließlich des Spaltennamens sehen. dann verwenden:

ALTER TABLE yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295; 

(der Constraint-Name ist nur ein Beispiel)

0

immer Skript und Überprüfung erzeugen, bevor Sie laufen. Unter dem Skript

select 'Alter table dbo.' + t.name + ' drop constraint '+ d.name from sys.tables t 
    join sys.default_constraints d 
    on d.parent_object_id = t.object_id 
    join sys.columns c 
    on c.object_id = t.object_id 
    and c.column_id = d.parent_column_id 
where c.name in ('VersionEffectiveDate', 'VersionEndDate', 'VersionReasonDesc') 
order by t.name 
0
 declare @ery nvarchar(max) 
     declare @tab nvarchar(max) = 'myTable' 
     declare @qu nvarchar(max) = 'alter table '[email protected]+' drop constraint ' 

     select @ery = (select bj.name from sys.tables as tb 
     inner join sys.objects as bj 
     on tb.object_id = bj.parent_object_id 
     where tb.name = @tab and bj.type = 'PK') 

     exec(@[email protected]) 

     **Take a look** 
+1

Auch wenn Ihr Code eine Lösung bringt, ist es am besten, dass Sie ein paar Erklärungen dazu liefern, warum er die Frage löst. – Fabien

0

Nach Lösung wird aus der Tabelle zu spezifischen Standardeinschränkung einer Spalte fallen

Declare @Const 

SET @Const = (
       SELECT TOP 1 'ALTER TABLE' + YOUR TABLE NAME +' DROP CONSTRAINT '+name 
       FROM Sys.default_constraints A 
       JOIN sysconstrints B on A.parent_object_id = B.id 
       WHERE id = OBJECT_ID('YOUR TABLE NAME') 
       AND COL_NAME(id, colid)='COLUMN NAME' 
       AND OBJECTPROPERTY(constid,'IsDefaultCnst')=1 
      ) 
EXEC (@Const) 
Verwandte Themen