我在表中有一个叫做MealType
的列(VARCHAR
),它有一个CHECK
约束条件,限制值为{"Veg", "NonVeg", "Vegan"}
这样做可以确保插入数据时符合约束条件。
我想显示这些选项供选择,但我无法找到查询特定表中列的约束条件的SQL语句。
从SQL Server系统表的第一次扫描来看,似乎需要使用SQL Server的API获取信息。我希望可以通过SQL查询本身来实现。
我在表中有一个叫做MealType
的列(VARCHAR
),它有一个CHECK
约束条件,限制值为{"Veg", "NonVeg", "Vegan"}
这样做可以确保插入数据时符合约束条件。
我想显示这些选项供选择,但我无法找到查询特定表中列的约束条件的SQL语句。
从SQL Server系统表的第一次扫描来看,似乎需要使用SQL Server的API获取信息。我希望可以通过SQL查询本身来实现。
最简单和最快的方法是使用:
sp_help 'TableName'
这个查询应该能显示表上所有的约束:
select chk.definition
from sys.check_constraints chk
inner join sys.columns col
on chk.parent_object_id = col.object_id
inner join sys.tables st
on chk.parent_object_id = st.object_id
where
st.name = 'Tablename'
and col.column_id = chk.parent_column_id
可以使用这个语句替换select语句:
select substring(chk.Definition,2,3),substring(chk.Definition,9,6),substring(chk.Definition,20,5)
chk.parent_object_id = col.object_id
成立,那么 chk.parent_object_id = st.object_id
就不可能成立,除非它们有相同的对象ID,这违背了拥有ID的原则。 - undefinedSELECT obj_table.NAME AS 'table',
columns.NAME AS 'column',
obj_Constraint.NAME AS 'constraint',
obj_Constraint.type AS 'type'
FROM sys.objects obj_table
JOIN sys.objects obj_Constraint
ON obj_table.object_id = obj_Constraint.parent_object_id
JOIN sys.sysconstraints constraints
ON constraints.constid = obj_Constraint.object_id
JOIN sys.columns columns
ON columns.object_id = obj_table.object_id
AND columns.column_id = constraints.colid
WHERE obj_table.NAME='table_name'
ORDER BY 'table'
标签来创建段落。
sp_helpconstraint 'tableName', 'nomsg'
获取表的所有约束条件。
“sp_help”返回更多信息。
SELECT /* obj_table.NAME AS 'table',
columns.NAME AS 'column',
obj_Constraint.NAME AS 'constraint',
obj_Constraint.type AS 'type',
sss.name as 'schema',*/
'ALTER TABLE [' + ltrim(rtrim(sss.name))+'].['+ltrim(rtrim(obj_table.name)) + '] DROP CONSTRAINT [' + obj_Constraint.NAME + '];' As 'Wrong_Implicit_Constraint',
'ALTER TABLE [' + ltrim(rtrim(sss.name))+'].['+ltrim(rtrim(obj_table.name)) + '] ADD CONSTRAINT [' + CASE obj_Constraint.type
WHEN 'D' THEN 'DF' WHEN 'F' THEN 'FK'
WHEN 'U' THEN 'UX' WHEN 'PK' THEN 'PK' WHEN 'N' THEN 'NN' WHEN 'C' THEN 'CK'
END + '_' + ltrim(rtrim(obj_table.name)) + '_' + columns.NAME + ']' +
CASE obj_Constraint.type WHEN 'D' THEN ' DEFAULT (' + dc.definition +') FOR [' + columns.NAME + ']'
WHEN 'C' THEN ' CHECK (' + cc.definition +')'
ELSE '' END +
';' As 'Right_Explicit_Constraint'
FROM sys.objects obj_table
JOIN sys.objects obj_Constraint ON obj_table.object_id = obj_Constraint.parent_object_id
JOIN sys.sysconstraints constraints ON constraints.constid = obj_Constraint.object_id
JOIN sys.columns columns ON columns.object_id = obj_table.object_id
AND columns.column_id = constraints.colid
left join sys.schemas sss on obj_Constraint.schema_id=sss.schema_id
left join sys.default_constraints dc on dc.object_id = obj_Constraint.object_id
left join sys.check_constraints cc on cc.object_id = obj_Constraint.object_id
WHERE obj_Constraint.type_desc LIKE '%CONSTRAINT'
AND RIGHT(obj_Constraint.name,10) LIKE '[_][_]________' --match double underscore + 8 chars of anything
AND RIGHT(obj_Constraint.name,8) LIKE '%[A-Z]%' --Ensure alpha in last 8
AND RIGHT(obj_Constraint.name,8) LIKE '%[0-9]%' --Ensure numeric in last 8
AND RIGHT(obj_Constraint.name,8) not LIKE '%[^0-9A-Z]%' --Ensure no special chars
感谢orgtrigger提供的示例!我对其进行了改进,使其能够删除不必要的约束(然后创建它们的修改版本,如果需要的话)。也许这段代码对任何人都有用。
-- removing old constraints
DECLARE @ConstraintNames TABLE (Name VARCHAR(MAX), RowNum INT)
DECLARE @TableName VARCHAR(100) = 'HubSpot'
INSERT @ConstraintNames
SELECT [constraint].name,
ROW_NUMBER() OVER (ORDER BY [constraint].[name]) AS RowNum
FROM sys.default_constraints [constraint]
INNER JOIN sys.columns col
ON [constraint].parent_object_id = col.object_id
INNER JOIN sys.tables st
ON [constraint].parent_object_id = st.object_id
WHERE
st.name = @TableName
AND col.name IN ('ForceUpdateOnImport', 'ForceUpdateOnExport')
AND col.column_id = [constraint].parent_column_id
SELECT * FROM @ConstraintNames
DECLARE @i INT = 1,
@count INT,
@constraintName VARCHAR(MAX),
@sql VARCHAR(MAX)
SELECT @count = COUNT(1) FROM @ConstraintNames
WHILE @i <= @count
BEGIN
SELECT @constraintName = cn.Name FROM @ConstraintNames cn WHERE cn.RowNum = @i
SET @sql = 'ALTER TABLE ' + @TableName + ' DROP CONSTRAINT ' + @constraintName
EXEC (@sql)
SET @i = @i + 1
END
SELECT t1.TABLE_NAME, t1.COLUMN_NAME, STRING_AGG(COALESCE(t1.CONSTRAINT_TYPE,''),','), t1.ORDINAL_POSITION, STRING_AGG(COALESCE(t1.reference_table,''),'') AS reference_table, STRING_AGG(COALESCE(t1.reference_column,''),'') AS reference_column
FROM
(SELECT c.TABLE_NAME, c.COLUMN_NAME, tc.CONSTRAINT_TYPE, ORDINAL_POSITION, t2.TABLE_NAME AS reference_table, t2.COLUMN_NAME AS reference_column
FROM INFORMATION_SCHEMA.COLUMNS c
LEFT JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu ON c.COLUMN_NAME = ccu.COLUMN_NAME AND c.TABLE_NAME = ccu.TABLE_NAME
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc ON ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
LEFT JOIN (SELECT ccu1.TABLE_NAME, ccu1.COLUMN_NAME, rc.UNIQUE_CONSTRAINT_NAME, rc.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
LEFT JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu1 ON ccu1.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME)t2
ON ccu.CONSTRAINT_NAME = t2.CONSTRAINT_NAME
GROUP BY c.TABLE_NAME, c.COLUMN_NAME, tc.CONSTRAINT_TYPE,ORDINAL_POSITION, t2.TABLE_NAME, t2.COLUMN_NAME)t1
GROUP BY t1.TABLE_NAME, t1.COLUMN_NAME,t1.ORDINAL_POSITION
ORDER BY t1.TABLE_NAME, t1.ORDINAL_POSITION
sysobjects
和syscolumns
会很有用... - radarbob