Wie finde ich mit INFORMATION_SCHEMA eine Standardeinschränkung?


116

Ich versuche zu testen, ob eine bestimmte Standardeinschränkung vorhanden ist. Ich möchte nicht die Tabelle sysobjects verwenden, sondern die standardmäßigere INFORMATION_SCHEMA.

Ich habe dies verwendet, um zuvor nach Tabellen und Primärschlüsseleinschränkungen zu suchen, aber ich sehe nirgendwo Standardeinschränkungen.

Sind sie nicht da (Ich verwende MS SQL Server 2000).

EDIT: Ich suche nach dem Namen der Einschränkung.

Antworten:


121

Soweit ich weiß, sind Standardwertbeschränkungen nicht Teil des ISO-Standards, daher werden sie nicht in INFORMATION_SCHEMA angezeigt. INFORMATION_SCHEMA scheint die beste Wahl für diese Art von Aufgabe zu sein, da sie plattformübergreifend ist. Wenn die Informationen jedoch nicht verfügbar sind, sollten Sie die Objektkatalogansichten (sys. *) Anstelle von Systemtabellenansichten verwenden, die in SQL Server veraltet sind 2005 und später.

Unten ist so ziemlich das Gleiche wie die Antwort von @ user186476. Es gibt den Namen der Standardwertbeschränkung für eine bestimmte Spalte zurück. (Für Nicht-SQL Server-Benutzer benötigen Sie den Namen des Standards, um ihn zu löschen. Wenn Sie die Standardeinschränkung nicht selbst benennen, erstellt SQL Server einen verrückten Namen wie "DF_TableN_Colum_95AFE4B5". Um das Ändern zu vereinfachen Ihr Schema in der Zukunft, benennen Sie Ihre Einschränkungen immer explizit!)

-- returns name of a column's default value constraint 
SELECT
    default_constraints.name
FROM 
    sys.all_columns

        INNER JOIN
    sys.tables
        ON all_columns.object_id = tables.object_id

        INNER JOIN 
    sys.schemas
        ON tables.schema_id = schemas.schema_id

        INNER JOIN
    sys.default_constraints
        ON all_columns.default_object_id = default_constraints.object_id

WHERE 
        schemas.name = 'dbo'
    AND tables.name = 'tablename'
    AND all_columns.name = 'columnname'

1
Hinweis: Es ist möglich, denselben Tabellennamen in verschiedenen Schemas zu verwenden. Sie sollten daher auch der Tabelle sys.schemas beitreten.
Daniel James Bryars

1
@DanielJamesBryars sys.schemas wurde jetzt zur Abfrage hinzugefügt.
Stephen Turner

Bitte lesen Sie meine Antwort, die kurz und bündig ist, in allen Versionen von SQL Server funktioniert, keine sysTabellen enthält und leicht zu merken ist.
ErikE

2
@ErikE Ihr Code setzt voraus, dass der Name der Standardeinschränkung bekannt ist. Das ist ein leicht zu lösendes Problem, wie Ihr Code zeigt. Gute Antwort, falsche Frage.
DarLom

Mein Code geht davon aus, dass der Fragesteller darum gebeten hat: "Ich möchte [ob 'eine bestimmte Standardeinschränkung existiert'] anhand des Namens der Einschränkung ermitteln." Ich habe meine Antwort bearbeitet, um ihre direkte Frage befriedigender Natur viel klarer zu machen. Hoffentlich hilft das.
ErikE

43

Sie können Folgendes verwenden, um die Ergebnisse noch weiter einzugrenzen, indem Sie den Tabellennamen und den Spaltennamen angeben, mit denen die Standardbeschränkung korreliert:

select * from sysobjects o 
inner join syscolumns c
on o.id = c.cdefault
inner join sysobjects t
on c.id = t.id
where o.xtype = 'D'
and c.name = 'Column_Name'
and t.name = 'Table_Name'

1
Ich suche seit ein paar Stunden nach dieser einfachen Abfrage. Thannnnnkkk youuuu!
Samuel

Es sollte o.xtype = 'D' geben, damit die Datenbank nicht zwischen Groß- und Kleinschreibung unterscheidet.
IvanH

37

Es scheint keine Standardbeschränkungsnamen in den Information_SchemaAnsichten zu geben.

Verwenden Sie SELECT * FROM sysobjects WHERE xtype = 'D' AND name = @name diese Option, um eine Standardeinschränkung nach Namen zu suchen


genau das, was ich brauchte. Danke
drdwilcox

Beantwortet Fragen direkt besser als spätere Alternativen (SQL 2000 & Abfrage nach Einschränkungsname).
Marc L.

Dies funktioniert nur, wenn Sie den Namen der Einschränkung kennen, aber wenn dies dem System zugewiesen ist ....
TS

12

Das folgende Skript listet alle Standardeinschränkungen und Standardwerte für die Benutzertabellen in der Datenbank auf, in der sie ausgeführt werden:

SELECT  
        b.name AS TABLE_NAME,
        d.name AS COLUMN_NAME,
        a.name AS CONSTRAINT_NAME,
        c.text AS DEFAULT_VALUE
FROM sys.sysobjects a INNER JOIN
        (SELECT name, id
         FROM sys.sysobjects 
         WHERE xtype = 'U') b on (a.parent_obj = b.id)
                      INNER JOIN sys.syscomments c ON (a.id = c.id)
                      INNER JOIN sys.syscolumns d ON (d.cdefault = a.id)                                          
 WHERE a.xtype = 'D'        
 ORDER BY b.name, a.name

5

Wenn Sie eine Einschränkung durch die Spalten- oder Tabellennamen erhalten möchten oder alle Einschränkungen in der Datenbank erhalten möchten, suchen Sie nach anderen Antworten. Wenn Sie jedoch nur genau das suchen, was die Frage verlangt, nämlich "zu testen, ob eine bestimmte Standardeinschränkung existiert ... anhand des Namens der Einschränkung". , gibt es einen viel einfacheren Weg.

Hier ist eine zukunftssichere Antwort, die die sysobjectsoder andere sysTabellen überhaupt nicht verwendet :

IF object_id('DF_CONSTRAINT_NAME', 'D') IS NOT NULL BEGIN
   -- constraint exists, work with it.
END

3
select c.name, col.name from sys.default_constraints c
    inner join sys.columns col on col.default_object_id = c.object_id
    inner join sys.objects o  on o.object_id = c.parent_object_id
    inner join sys.schemas s on s.schema_id = o.schema_id
where s.name = @SchemaName and o.name = @TableName and col.name = @ColumnName

1
Ein bisschen mehr Leerzeichen wäre schön, aber dies entspricht den Anforderungen des Originalplakats unter Verwendung der Objektkatalogansichten (sys. *), Die von Microsoft gegenüber den Tabellenansichten des Abwärtskompatibilitätssystems empfohlen werden.
Robert Calhoun

2

Ist die Spalte COLUMN_DEFAULT von INFORMATION_SCHEMA.COLUMNS das, wonach Sie suchen?


Ja und nein, es sagt mir, dass es eine Standardeinstellung gibt und was es ist, aber ich brauche auch den Namen der Einschränkung.
WildJoe

1
Beachten Sie außerdem, dass Sie möglicherweise nur NULL-Werte in der Spalte COLUMN_DEFAULT finden, wenn Ihre Laufzeit-SQL-Anmeldung das dbo-Schema nicht besitzt.
Glen Little

1
WHILE EXISTS( 
    SELECT * FROM  sys.all_columns 
    INNER JOIN sys.tables ST  ON all_columns.object_id = ST.object_id
    INNER JOIN sys.schemas ON ST.schema_id = schemas.schema_id
    INNER JOIN sys.default_constraints ON all_columns.default_object_id = default_constraints.object_id
    WHERE 
    schemas.name = 'dbo'
    AND ST.name = 'MyTable'
)
BEGIN 
DECLARE @SQL NVARCHAR(MAX) = N'';

SET @SQL = (  SELECT TOP 1
     'ALTER TABLE ['+  schemas.name + '].[' + ST.name + '] DROP CONSTRAINT ' + default_constraints.name + ';'
   FROM 
      sys.all_columns

         INNER JOIN
      sys.tables ST
         ON all_columns.object_id = ST.object_id

         INNER JOIN 
      sys.schemas
         ON ST.schema_id = schemas.schema_id

         INNER JOIN
      sys.default_constraints
         ON all_columns.default_object_id = default_constraints.object_id

   WHERE 
         schemas.name = 'dbo'
      AND ST.name = 'MyTable'
      )
   PRINT @SQL
   EXECUTE sp_executesql @SQL 

   --End if Error 
   IF @@ERROR <> 0 
   BREAK
END 

1

Nekromantie.
Wenn Sie nur überprüfen müssen, ob eine Standardeinschränkung vorhanden ist
(Standardeinschränkungen haben in schlecht verwalteten
DBs möglicherweise einen anderen Namen), verwenden Sie INFORMATION_SCHEMA.COLUMNS (column_default):

IF NOT EXISTS(
    SELECT * FROM INFORMATION_SCHEMA.COLUMNS
    WHERE (1=1) 
    AND TABLE_SCHEMA = 'dbo' 
    AND TABLE_NAME = 'T_VWS_PdfBibliothek' 
    AND COLUMN_NAME = 'PB_Text'
    AND COLUMN_DEFAULT IS NOT NULL  
)
BEGIN 
    EXECUTE('ALTER TABLE dbo.T_VWS_PdfBibliothek 
                ADD CONSTRAINT DF_T_VWS_PdfBibliothek_PB_Text DEFAULT (N''image'') FOR PB_Text; 
    '); 
END 

Wenn Sie nur anhand des Einschränkungsnamens überprüfen möchten:

-- Alternative way: 
IF OBJECT_ID('DF_CONSTRAINT_NAME', 'D') IS NOT NULL 
BEGIN
    -- constraint exists, deal with it.
END 

Und zu guter Letzt können Sie einfach eine Ansicht mit dem Namen
INFORMATION_SCHEMA.DEFAULT_CONSTRAINTS erstellen :

CREATE VIEW INFORMATION_SCHEMA.DEFAULT_CONSTRAINTS 
AS 
SELECT 
     DB_NAME() AS CONSTRAINT_CATALOG 
    ,csch.name AS CONSTRAINT_SCHEMA
    ,dc.name AS CONSTRAINT_NAME 
    ,DB_NAME() AS TABLE_CATALOG 
    ,sch.name AS TABLE_SCHEMA 
    ,syst.name AS TABLE_NAME 
    ,sysc.name AS COLUMN_NAME 
    ,COLUMNPROPERTY(sysc.object_id, sysc.name, 'ordinal') AS ORDINAL_POSITION 
    ,dc.type_desc AS CONSTRAINT_TYPE 
    ,dc.definition AS COLUMN_DEFAULT 

    -- ,dc.create_date 
    -- ,dc.modify_date 
FROM sys.columns AS sysc -- 46918 / 3892 with inner joins + where 
-- FROM sys.all_columns AS sysc -- 55429 / 3892 with inner joins + where 

INNER JOIN sys.tables AS syst 
    ON syst.object_id = sysc.object_id 

INNER JOIN sys.schemas AS sch
    ON sch.schema_id = syst.schema_id 

INNER JOIN sys.default_constraints AS dc 
    ON sysc.default_object_id = dc.object_id

INNER JOIN sys.schemas AS csch
    ON csch.schema_id = dc.schema_id 

WHERE (1=1) 
AND dc.is_ms_shipped = 0 

/*
WHERE (1=1) 
AND sch.name = 'dbo'
AND syst.name = 'tablename'
AND sysc.name = 'columnname'
*/

0

Ich glaube nicht, dass es in INFORMATION_SCHEMA enthalten ist - Sie müssen wahrscheinlich Sysobjects oder verwandte veraltete Tabellen / Ansichten verwenden.

Sie würden denken, dass es in INFORMATION_SCHEMA.TABLE_CONSTRAINTS einen Typ dafür geben würde, aber ich sehe keinen.


0

Wahrscheinlich, weil in einigen anderen SQL-DBMS die "Standardeinschränkung" nicht wirklich eine Einschränkung ist, finden Sie ihren Namen nicht in "INFORMATION_SCHEMA.TABLE_CONSTRAINTS". Ihre beste Wahl ist also "INFORMATION_SCHEMA.COLUMNS", wie andere bereits erwähnt haben.

(SQLServer-ignoramus hier)

Der einzige Grund, an den ich denken kann, wenn Sie den Namen der "Standardeinschränkung" kennen müssen, ist, wenn SQLServer keinen "ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT..."Befehl unterstützt. Aber dann befinden Sie sich bereits in einer nicht standardmäßigen Zone und müssen die produktspezifischen Methoden verwenden, um das zu erhalten, was Sie benötigen.


0

Wie wäre es mit einer Kombination aus CHECK_CONSTRAINTS und CONSTRAINT_COLUMN_USAGE:

    select columns.table_name,columns.column_name,columns.column_default,checks.constraint_name
          from information_schema.columns columns
             inner join information_schema.constraint_column_usage usage on 
                  columns.column_name = usage.column_name and columns.table_name = usage.table_name
             inner join information_schema.check_constraints checks on usage.constraint_name = checks.constraint_name
    where columns.column_default is not null

CONSTRAINT_COLUMN_USAGE enthält keine Informationen zu Standardeinschränkungen.
Stephen Turner

0

Ich verwende das folgende Skript, um alle Standardeinstellungen (sp_binddefaults) und alle Standardeinschränkungen mit folgenden Skripten abzurufen:

SELECT 
    t.name AS TableName, c.name AS ColumnName, SC.COLUMN_DEFAULT AS DefaultValue, dc.name AS DefaultConstraintName
FROM  
    sys.all_columns c
    JOIN sys.tables t ON c.object_id = t.object_id
    JOIN sys.schemas s ON t.schema_id = s.schema_id
    LEFT JOIN sys.default_constraints dc ON c.default_object_id = dc.object_id
    LEFT JOIN INFORMATION_SCHEMA.COLUMNS SC ON (SC.TABLE_NAME = t.name AND SC.COLUMN_NAME = c.name)
WHERE 
    SC.COLUMN_DEFAULT IS NOT NULL
    --WHERE t.name = '' and c.name = ''

0

Objektkatalog anzeigen : sys.default_constraints

Die Informationsschemaansichten INFORMATION_SCHEMAsind ANSI-kompatibel, aber die Standardeinschränkungen sind nicht Teil des ISO-Standards. Microsoft SQL Server bietet Systemkatalogansichten zum Abrufen von Informationen zu SQL Server-Objektmetadaten.

sys.default_constraints Systemkatalogansicht zum Abrufen von Informationen zu Standardeinschränkungen.

SELECT so.object_id TableName,
       ss.name AS TableSchema,
       cc.name AS Name,
       cc.object_id AS ObjectID,              
       sc.name AS ColumnName,
       cc.parent_column_id AS ColumnID,
       cc.definition AS Defination,
       CONVERT(BIT,
               CASE cc.is_system_named
                   WHEN 1
                   THEN 1
                   ELSE 0
               END) AS IsSystemNamed,
       cc.create_date AS CreationDate,
       cc.modify_date AS LastModifiednDate
FROM sys.default_constraints cc WITH (NOLOCK)
     INNER JOIN sys.objects so WITH (NOLOCK) ON so.object_id = cc.parent_object_id
     LEFT JOIN sys.schemas ss WITH (NOLOCK) ON ss.schema_id = so.schema_id
     LEFT JOIN sys.columns sc WITH (NOLOCK) ON sc.column_id = cc.parent_column_id
                                               AND sc.object_id = cc.parent_object_id
ORDER BY so.name,
         cc.name;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.