ฉันจะค้นหาข้อ จำกัด เริ่มต้นโดยใช้ INFORMATION_SCHEMA ได้อย่างไร


116

ฉันกำลังพยายามทดสอบว่ามีข้อ จำกัด เริ่มต้นหรือไม่ ฉันไม่ต้องการใช้ตาราง sysobjects แต่เป็น INFORMATION_SCHEMA มาตรฐานมากกว่า

ฉันเคยใช้สิ่งนี้เพื่อตรวจสอบตารางและข้อ จำกัด ของคีย์หลักมาก่อน แต่ฉันไม่เห็นข้อ จำกัด เริ่มต้นเลย

พวกเขาไม่อยู่ที่นั่น? (ฉันใช้ MS SQL Server 2000)

แก้ไข: ฉันกำลังมองหาชื่อของข้อ จำกัด

คำตอบ:


121

ตามที่ฉันเข้าใจข้อ จำกัด ของค่าเริ่มต้นไม่ได้เป็นส่วนหนึ่งของมาตรฐาน ISO ดังนั้นจึงไม่ปรากฏใน INFORMATION_SCHEMA INFORMATION_SCHEMA ดูเหมือนจะเป็นตัวเลือกที่ดีที่สุดสำหรับงานประเภทนี้เนื่องจากเป็นแบบข้ามแพลตฟอร์ม แต่หากไม่มีข้อมูลก็ควรใช้มุมมองแค็ตตาล็อกอ็อบเจ็กต์ (sys. *) แทนมุมมองตารางระบบซึ่งเลิกใช้แล้วใน SQL Server 2005 และใหม่กว่า

ด้านล่างนี้ค่อนข้างเหมือนกับคำตอบของ @ user186476 ส่งคืนชื่อของข้อ จำกัด ค่าเริ่มต้นสำหรับคอลัมน์ที่กำหนด (สำหรับผู้ใช้ที่ไม่ใช่ SQL Server คุณต้องมีชื่อของค่าเริ่มต้นเพื่อที่จะปล่อยและถ้าคุณไม่ได้ตั้งชื่อข้อ จำกัด เริ่มต้นด้วยตัวคุณเอง SQL Server จะสร้างชื่อที่บ้าคลั่งเช่น "DF_TableN_Colum_95AFE4B5" เพื่อให้ง่ายต่อการเปลี่ยนแปลง สคีมาของคุณในอนาคตตั้งชื่อข้อ จำกัด ของคุณอย่างชัดเจนเสมอ!)

-- 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
หมายเหตุ: เป็นไปได้ที่จะมีชื่อตารางเดียวกันในสคีมาที่แตกต่างกันดังนั้นคุณควรเข้าร่วมในตาราง sys.schemas ด้วย
Daniel James Bryars

1
เพิ่ม @DanielJamesBryars sys.schemas ในแบบสอบถามแล้ว
Stephen Turner

โปรดดูคำตอบของฉันซึ่งสั้นและไพเราะใช้ได้กับ SQL Server ทุกเวอร์ชันไม่มีsysตารางใด ๆและง่ายต่อการจดจำ
ErikE

2
@ErikE รหัสของคุณถือว่าชื่อของข้อ จำกัด เริ่มต้นเป็นที่รู้จัก นั่นเป็นปัญหาที่ง่ายในการแก้ไขเนื่องจากโค้ดของคุณแสดงให้เห็น ตอบดีคำถามผิด
DarLom

รหัสของฉันคิดว่าเป็นเพราะนั่นคือสิ่งที่ผู้ถามถาม - "ฉันต้องการรับ [ว่ามี" ข้อ จำกัด เริ่มต้นที่กำหนดหรือไม่ "] ตามชื่อของข้อ จำกัด หรือไม่" ฉันได้แก้ไขคำตอบของฉันเพื่อทำให้คำถามตรงประเด็น - ลักษณะที่ชัดเจนยิ่งขึ้น หวังว่าจะช่วยได้
ErikE

43

คุณสามารถใช้สิ่งต่อไปนี้เพื่อ จำกัด ผลลัพธ์ให้แคบลงโดยระบุชื่อตารางและชื่อคอลัมน์ที่ข้อ จำกัด เริ่มต้นมีความสัมพันธ์กับ:

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
ฉันค้นหาคำค้นหาง่ายๆนี้ตั้งแต่สองสามชั่วโมง ธันนนนนนนนนนนน!
Samuel

ควรมี o.xtype = 'D' ในการทำงานฐานข้อมูลที่คำนึงถึงขนาดตัวพิมพ์
IvanH

37

ดูเหมือนว่าจะไม่มีชื่อ Default Constraint ในInformation_Schemaมุมมอง

ใช้SELECT * FROM sysobjects WHERE xtype = 'D' AND name = @name เพื่อค้นหาข้อ จำกัด เริ่มต้นตามชื่อ


สิ่งที่ฉันต้องการ ขอบคุณ
drdwilcox

ตอบคำถามโดยตรงได้ดีกว่าทางเลือกอื่นในภายหลัง (SQL 2000 และแบบสอบถามตามชื่อข้อ จำกัด )
Marc L.

จะใช้ได้เฉพาะเมื่อคุณทราบชื่อข้อ จำกัด แต่ถ้าเป็นระบบที่กำหนด ....
TS

12

สคริปต์ด้านล่างแสดงข้อ จำกัด เริ่มต้นทั้งหมดและค่าดีฟอลต์สำหรับตารางผู้ใช้ในฐานข้อมูลที่กำลังเรียกใช้:

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

หากคุณต้องการรับข้อ จำกัด จากชื่อคอลัมน์หรือตารางหรือคุณต้องการรับข้อ จำกัด ทั้งหมดในฐานข้อมูลให้ดูคำตอบอื่น ๆ อย่างไรก็ตามหากคุณเพียงแค่มองหาสิ่งที่คำถามถามนั่นคือการ"ทดสอบว่ามีข้อ จำกัด เริ่มต้นที่กำหนดหรือไม่ ... ตามชื่อข้อ จำกัด "ก็มีวิธีที่ง่ายกว่ามาก

นี่คือคำตอบที่พิสูจน์ได้ในอนาคตที่ไม่ใช้ตารางsysobjectsอื่น ๆsysเลย:

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
ช่องว่างอีกเล็กน้อยจะดี แต่จะทำตามที่ผู้โพสต์ดั้งเดิมถามโดยใช้มุมมองแค็ตตาล็อกอ็อบเจ็กต์ (sys. *) ซึ่งแนะนำโดย Microsoft ในมุมมองตารางของระบบที่เข้ากันได้แบบย้อนหลัง
Robert Calhoun

2

คอลัมน์ COLUMN_DEFAULT ของ INFORMATION_SCHEMA.COLUMNS สิ่งที่คุณกำลังมองหาใช่หรือไม่


ใช่และไม่ใช่มันบอกฉันว่ามีค่าเริ่มต้นและมันคืออะไร แต่ฉันต้องการชื่อของข้อ จำกัด ด้วย
WildJoe

1
นอกจากนี้โปรดทราบว่าหากล็อกอิน SQL รันไทม์ของคุณไม่ได้เป็นเจ้าของสคีมา dbo คุณอาจพบเฉพาะค่า NULL ในคอลัมน์ COLUMN_DEFAULT
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

Necromancing
หากคุณต้องการตรวจสอบว่ามีข้อ จำกัด
เริ่มต้นหรือไม่ ( ข้อ จำกัดเริ่มต้นอาจมีชื่อแตกต่างกันในฐานข้อมูลที่มีการจัดการไม่ดี) ให้
ใช้ 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 

หากคุณต้องการตรวจสอบโดยใช้ชื่อข้อ จำกัด เท่านั้น:

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

สุดท้าย แต่ไม่ท้ายสุดคุณสามารถสร้างมุมมองที่เรียกว่า
INFORMATION_SCHEMA.DEFAULT_CONSTRAINTS:

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

ฉันไม่คิดว่ามันอยู่ใน INFORMATION_SCHEMA - คุณอาจจะต้องใช้ sysobjects หรือตาราง / มุมมองที่เกี่ยวข้องที่เลิกใช้แล้ว

คุณคิดว่าจะมีประเภทนี้ใน INFORMATION_SCHEMA.TABLE_CONSTRAINTS แต่ฉันไม่เห็น


0

อาจเป็นเพราะใน SQL DBMS อื่น ๆ "ข้อ จำกัด เริ่มต้น" ไม่ใช่ข้อ จำกัด จริงๆคุณจะไม่พบชื่อของมันใน "INFORMATION_SCHEMA.TABLE_CONSTRAINTS" ดังนั้นทางออกที่ดีที่สุดของคุณคือ "INFORMATION_SCHEMA.COLUMNS" ตามที่คนอื่นพูดถึงไปแล้ว

(SQLServer-ignoramus ที่นี่)

เหตุผลเดียวที่ฉันคิดได้เมื่อคุณต้องรู้ชื่อ "ข้อ จำกัด เริ่มต้น" คือถ้า SQLServer ไม่รองรับ"ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT..."คำสั่ง แต่คุณอยู่ในโซนที่ไม่ได้มาตรฐานแล้วและคุณต้องใช้วิธีการเฉพาะผลิตภัณฑ์เพื่อให้ได้สิ่งที่คุณต้องการ


0

วิธีการใช้ชุดค่าผสมของ CHECK_CONSTRAINTS และ 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 ไม่เก็บข้อมูลใด ๆ เกี่ยวกับข้อ จำกัด เริ่มต้น
Stephen Turner

0

ฉันกำลังใช้สคริปต์ folllowing เพื่อเรียกคืนค่าเริ่มต้นทั้งหมด (sp_binddefaults) และข้อ จำกัด เริ่มต้นทั้งหมดด้วยสคริปต์ต่อไปนี้:

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

มุมมองวัตถุแค็ตตาล็อก : sys.default_constraints

มุมมองสคีมาข้อมูลINFORMATION_SCHEMAเป็นไปตามมาตรฐาน ANSI แต่ข้อ จำกัด เริ่มต้นไม่ได้เป็นส่วนหนึ่งของมาตรฐาน ISO Microsoft SQL Server มีมุมมองแค็ตตาล็อกระบบสำหรับการรับข้อมูลเกี่ยวกับข้อมูลเมตาของอ็อบเจ็กต์ SQL Server

sys.default_constraints มุมมองแค็ตตาล็อกระบบที่ใช้ในการรับข้อมูลเกี่ยวกับข้อ จำกัด เริ่มต้น

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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.