كيف يمكنني العثور على قيد افتراضي باستخدام INFORMATION_SCHEMA؟
-
02-07-2019 - |
سؤال
أحاول اختبار ما إذا كان هناك قيد افتراضي معين.لا أريد استخدام جدول 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;