كيف يمكنني العثور على قيد افتراضي باستخدام INFORMATION_SCHEMA؟

StackOverflow https://stackoverflow.com/questions/141682

سؤال

أحاول اختبار ما إذا كان هناك قيد افتراضي معين.لا أريد استخدام جدول sysobjects، بل أريد استخدام جدول INFORMATION_SCHEMA الأكثر معيارًا.

لقد استخدمت هذا للتحقق من الجداول وقيود المفتاح الأساسي من قبل، لكنني لا أرى القيود الافتراضية في أي مكان.

أليسوا هناك؟(أنا أستخدم MS SQL Server 2000).

يحرر:أنا أتطلع للحصول على اسم القيد.

هل كانت مفيدة؟

المحلول

كما أفهم، فإن قيود القيمة الافتراضية ليست جزءًا من معيار 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'

نصائح أخرى

يمكنك استخدام ما يلي لتضييق النتائج بشكل أكبر عن طريق تحديد اسم الجدول واسم العمود الذي يرتبط به القيد الافتراضي:

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'

يبدو أنه لا توجد أسماء قيود افتراضية في ملف Information_Schema الآراء.

يستخدم SELECT * FROM sysobjects WHERE xtype = 'D' AND name = @nameللعثور على القيد الافتراضي بالاسم

يسرد البرنامج النصي أدناه كافة القيود الافتراضية والقيم الافتراضية لجداول المستخدم في قاعدة البيانات التي يتم تشغيله فيها:

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
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

إذا كنت ترغب في الحصول على قيد من خلال أسماء الأعمدة أو الجداول، أو كنت ترغب في الحصول على كافة القيود في قاعدة البيانات، فابحث عن إجابات أخرى.ومع ذلك، إذا كنت تبحث فقط عن ما يطرحه السؤال بالضبط، أي "اختبار ما إذا كان هناك قيد افتراضي معين ...باسم القيد", ، ثم هناك طريقة أسهل بكثير.

إليك إجابة مستقبلية لا تستخدم sysobjects أو غيرها sys الجداول على الإطلاق:

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

هل العمود COLUMN_DEFAULT الخاص بـ INFORMATION_SCHEMA.COLUMNS هو ما تبحث عنه؟

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 

لا أعتقد أنه موجود في INFORMATION_SCHEMA - ربما يتعين عليك استخدام كائنات النظام أو الجداول/طرق العرض المهملة ذات الصلة.

قد تعتقد أنه سيكون هناك نوع لهذا في INFORMATION_SCHEMA.TABLE_CONSTRAINTS، لكنني لا أرى واحدًا.

ربما لأنه في بعض أنظمة إدارة قواعد بيانات SQL الأخرى، لا يعد "القيد الافتراضي" قيدًا حقًا، فلن تجد اسمه في "INFORMATION_SCHEMA.TABLE_CONSTRAINTS"، لذا فإن أفضل رهان لك هو "INFORMATION_SCHEMA.COLUMNS" كما ذكر الآخرون بالفعل.

(SQLServer-جاهل هنا)

السبب الوحيد الذي يمكنني التفكير فيه عندما يتعين عليك معرفة اسم "القيد الافتراضي" هو إذا كان SQLServer لا يدعم "ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT..." يأمر.ولكن بعد ذلك تكون بالفعل في منطقة غير قياسية ويتعين عليك استخدام الطرق الخاصة بالمنتج للحصول على ما تحتاجه.

ماذا عن استخدام مجموعة من 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

أنا أستخدم البرنامج النصي التالي لاستعادة كافة الإعدادات الافتراضية (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 = ''

عرض كتالوج الكائنات :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;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top