Come trovo un vincolo predefinito usando INFORMATION_SCHEMA?
-
02-07-2019 - |
Domanda
Sto cercando di verificare se esiste un determinato vincolo predefinito. Non voglio usare la tabella sysobjects, ma il più standard INFORMATION_SCHEMA.
L'ho usato per verificare la presenza di tabelle e vincoli di chiave primaria prima, ma non vedo vincoli predefiniti da nessuna parte.
Non ci sono? (Sto usando MS SQL Server 2000).
EDIT: sto cercando di ottenere il nome del vincolo.
Soluzione
A quanto ho capito, i vincoli di valore predefiniti non fanno parte dello standard ISO, quindi non vengono visualizzati in INFORMATION_SCHEMA. INFORMATION_SCHEMA sembra la scelta migliore per questo tipo di attività perché è multipiattaforma, ma se le informazioni non sono disponibili si dovrebbero usare le viste del catalogo degli oggetti (sys. *) Invece delle viste della tabella di sistema, che sono deprecate in SQL Server 2005 e versioni successive.
Di seguito è praticamente la stessa della risposta di @ user186476. Restituisce il nome del vincolo del valore predefinito per una determinata colonna. (Per gli utenti non SQL Server, è necessario il nome del valore predefinito per eliminarlo e, se non si nomina il vincolo predefinito, SQL Server crea un nome pazzo come " DF_TableN_Colum_95AFE4B5 " ;. Per semplificare cambia il tuo schema in futuro, dai sempre un nome esplicito ai tuoi vincoli!)
-- 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'
Altri suggerimenti
Puoi utilizzare quanto segue per restringere ulteriormente i risultati specificando il Nome tabella e il Nome colonna a cui il Vincolo predefinito è correlato:
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'
Sembra che non ci siano nomi di vincoli predefiniti nelle viste Information_Schema
.
usa SELEZIONA * DA sysobjects DOVE xtype = 'D' AND name = @name
per trovare un vincolo predefinito per nome
Lo script seguente elenca tutti i vincoli predefiniti e i valori predefiniti per le tabelle utente nel database in cui viene eseguito:
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
Se si desidera ottenere un vincolo dai nomi di colonna o tabella o se si desidera ottenere tutti i vincoli nel database, consultare le altre risposte. Tuttavia, se stai solo cercando esattamente cosa pone la domanda, vale a dire, " test se esiste un determinato vincolo predefinito ... con il nome del vincolo " , allora c'è molto più facile modo.
Ecco una risposta a prova di futuro che non utilizza affatto le sysobjects
o altre tabelle sys
:
IF object_id('DF_CONSTRAINT_NAME', 'D') IS NOT NULL BEGIN
-- constraint exists, work with it.
END
È la colonna COLUMN_DEFAULT di INFORMATION_SCHEMA.COLUMNS che stai cercando?
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
Non penso che sia in INFORMATION_SCHEMA - probabilmente dovrai usare sysobject o tabelle / viste deprecate correlate.
Penseresti che ci sarebbe un tipo per questo in INFORMATION_SCHEMA.TABLE_CONSTRAINTS, ma non ne vedo uno.
Probabilmente perché su alcuni degli altri DBMS SQL il "vincolo predefinito" non è in realtà un vincolo, non troverai il suo nome in " INFORMATION_SCHEMA.TABLE_CONSTRAINTS " ;, quindi la tua scommessa migliore è " INFORMATION_SCHEMA.COLUMNS " come altri hanno già detto.
(SQLServer-ignoramus qui)
L'unico motivo che mi viene in mente quando devi conoscere il nome del "vincolo predefinito" è se SQL Server non supporta " ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT ... "
. Ma poi sei già in una zona non standard e devi usare i modi specifici del prodotto per ottenere ciò di cui hai bisogno.
Che ne dici di usare una combinazione di CHECK_CONSTRAINTS e 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
Sto usando il seguente script per recuperare tutte le impostazioni predefinite (sp_bindefault) e tutti i vincoli predefiniti con i seguenti script:
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 = ''
Vista catalogo oggetti : sys.default_constraints
Le viste dello schema di informazioni INFORMATION_SCHEMA
sono conformi ANSI, ma i vincoli predefiniti non fanno parte dello standard ISO. Microsoft SQL Server fornisce viste del catalogo di sistema per ottenere informazioni sui metadati degli oggetti di SQL Server.
sys.default_constraints
vista del catalogo di sistema utilizzata per ottenere le informazioni sui vincoli predefiniti.
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;