2009-07-14 8 views

Antwort

42

Wenn Sie dies manuell tun möchten, können Sie Management Studio verwenden, um es zu finden (unter dem Knoten Constraints in der Tabelle).

, es zu tun mit SQL:

  • Wenn die Einschränkungen Standardeinschränkungen sind, können Sie sys.default_constraints es finden verwenden:

    SELECT OBJECT_NAME(parent_object_id) AS TableName, name AS ConstraintName 
    FROM sys.default_constraints ORDER BY TableName, ConstraintName 
    
  • Wenn Sie auch für andere Zwänge suchen (Scheck, eindeutige, Fremdschlüssel, Standard, Primärschlüssel), können Sie sysconstraints verwenden:

    SELECT OBJECT_NAME(id) AS TableName, OBJECT_NAME(constid) AS ConstraintName 
    FROM sysconstraints ORDER BY TableName, ConstraintName 
    

Sie sagen nicht, welche Version von SQL Server Sie verwenden. Die oben genannten Arbeiten sowohl auf SQL 2005 und SQL 2008

+1

+1 Vielen Dank. Dies funktioniert auch in SQL 2012. – gotqn

+0

Die erste Abfrage funktionierte toll in SQL 2008 R2, als ich die Objekt-ID der Tabelle zuerst mit 'DECLARE @ParentObjectId INT = (wählen Sie OBJECT_ID aus sys.objects wo Name = 'ParentTable' UND Typ = 'U')' und hinzugefügt 'WHERE parent_object_id = @ ParentObjectId' für die Abfrage. Andernfalls erhalten Sie alle Standardeinschränkungen in der Datenbank. – Torrents

+0

Das ist nett, aber es zeigt nicht das Schema, in dem die Tabellen sind. Es wäre nett, wenn Sie eine Verknüpfung zu sys.schemas hinzufügen würden. – AperioOculus

3

Sie können den Namen der Einschränkung aus sp_help [Tabellenname] finden und sie dann nach Name löschen.

Oder Sie können dies wahrscheinlich über Management Studio tun.

4

Oder Sie können es mit sys.check_constraints Katalogansicht finden.

57

Sie können diesen Code verwenden Sie es automatisch zu tun:

DECLARE @tableName VARCHAR(MAX) = '<MYTABLENAME>' 
DECLARE @columnName VARCHAR(MAX) = '<MYCOLUMNAME>' 
DECLARE @ConstraintName nvarchar(200) 
SELECT @ConstraintName = Name 
FROM SYS.DEFAULT_CONSTRAINTS 
WHERE PARENT_OBJECT_ID = OBJECT_ID(@tableName) 
AND PARENT_COLUMN_ID = (
    SELECT column_id FROM sys.columns 
    WHERE NAME = @columnName AND object_id = OBJECT_ID(@tableName)) 
IF @ConstraintName IS NOT NULL 
    EXEC('ALTER TABLE '[email protected]+' DROP CONSTRAINT ' + @ConstraintName) 

Ersetzen Sie einfach <MYTABLENAME> und <MYCOLUMNNAME> als angemessen.

+5

Für faule Menschen (und Microsoft SQL Server-Entwickler), als Hommage an diese Antwort, ersetzen Sie die oberen beiden Zeilen mit 'CREATE PROCEDURE dbo.DropColumnDefaultOrConstraint @ Tabellenname VARCHAR (MAX), @columnName VARCHAR (MAX) AS' dann wrap in' BEGIN' und 'END' und verwenden' EXEC DropColumnDefaultOrConstraint 'Tabellenname', 'Spaltenname'; ' – Chris

+7

Ich verstehe einfach nicht, warum MS SQL nicht automatisch Standardeinschränkungen fallen lässt. – Tim

+1

Dieses automatisierte Skript ist für jedes Roll-your-own-Datenbankschema-Update-Modul erforderlich. Ich frage mich, wie EF Migration Tool das tut? Der zugrunde liegende Fehler, dass SQL Server Namen für anonyme Standardwerte generiert und erfordert, dass Sie diesen Namen kennen/erhalten, um ihn zu ändern oder wieder zu löschen, ist ein Problem, das vor langer Zeit in der tsql-Syntax selbst behandelt werden sollte. aber es ist immer noch in sql2016. @Tim ja, oder zumindest eine Syntax, um den Tropfen zu erzwingen. – dlatikay

1

Für eine einzelne Tabelle und Spalte in einer einzigen Zeile verwenden Sie die folgende

declare @sql nvarchar(max); set @sql = ''; SELECT @sql+='ALTER TABLE [dbo].[YOURTABLENAME] DROP CONSTRAINT ' + ((SELECT OBJECT_NAME(constid) FROM sysconstraints WHERE OBJECT_NAME(id) = 'YOURTABLENAME'AND colid IN (SELECT ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS Where Table_Name = 'YOURTABLENAME' and COLUMN_NAME = 'YOURCOLUMNNAM'))) + ';'; EXEC sp_executesql @sql; 

Wenn Sie mehrere Einschränkungen für die Spalte haben, müssen Sie auf die Einschränkung sind Sie nach unterscheiden, aber wenn Sie nur eine haben Standard-Einschränkung wird dies den Trick machen.

Überprüfen Sie die anderen Spalten, die im information_schema verfügbar sind, damit Sie weiter unterscheiden können.

0

geht hier meine eigene Version, die alle abhängigen Einschränkungen fällt - Standardeinschränkung (falls vorhanden) und alle Check-Einschränkungen betroffen (wie SQL-Standard scheint darauf hinzudeuten und wie einige andere Datenbanken scheinen so)

declare @constraints varchar(4000); 
declare @sql varchar(4000); 
with table_id_column_position as (
    select object_id table_id, column_id column_position 
     from sys.columns where object_id is not null and object_id = object_id('TableName') and name = 'ColumnToBeDropped' 
) 
select @constraints = coalesce(@constraints, 'constraint ') + '[' + name + '], ' 
from sysobjects 
where (
    -- is CHECK constraint 
    type = 'C' 
    -- dependeds on the column 
    and id is not null 
    and id in (
     select object_id --, object_name(object_id) 
     from sys.sql_dependencies, table_id_column_position 
     where object_id is not null 
     and referenced_major_id = table_id_column_position.table_id 
     and referenced_minor_id = table_id_column_position.column_position 
    ) 
) OR (
    -- is DEFAULT constraint 
    type = 'D' 
    and id is not null 
    and id in (
    select object_id 
    from sys.default_constraints, table_id_column_position 
    where object_id is not null 
    and parent_object_id = table_id_column_position.table_id 
    and parent_column_id = table_id_column_position.column_position 
) 
); 
set @sql = 'alter table TableName drop ' + coalesce(@constraints, '') + ' column ColumnToBeDropped'; 
exec @sql 

(Vorsicht: beide TableName und ColumnToBeDropped erscheinen zweimal im Code oben)

Dies funktioniert, indem einzelne ALTER TABLE TableName DROP CONSTRAINT c1, ..., COLUMN ColumnToBeDropped und Ausführung der Konstruktion.

Verwandte Themen