2008-09-26 10 views
86

Estoy tratando de probar si existe una restricción predeterminada dada. No quiero usar la tabla sysobjects, pero el más estándar INFORMATION_SCHEMA.¿Cómo puedo encontrar una restricción predeterminada usando INFORMATION_SCHEMA?

Lo he usado para verificar las tablas y las restricciones de la clave principal antes, pero no veo las restricciones predeterminadas en ninguna parte.

¿No están allí? (Estoy usando MS SQL Server 2000).

EDIT: Estoy buscando para obtener el nombre de la restricción.

Respuesta

86

lo que tengo entendido, las limitaciones de valor por defecto no son parte de la Norma ISO, por lo que no aparecen en INFORMATION_SCHEMA. INFORMATION_SCHEMA parece ser la mejor opción para este tipo de tarea porque es multiplataforma, pero si la información no está disponible, se deben usar las vistas de catálogo de objetos (sys. *) En lugar de las vistas de tablas del sistema, que están en desuso en SQL Server. 2005 y más tarde.

Debajo está casi igual que la respuesta de @ user186476. Devuelve el nombre de la restricción de valor predeterminada para una columna determinada. (Para los usuarios que no son servidores SQL, necesita el nombre del valor predeterminado para poder soltarlo, y si usted no nombra la restricción predeterminada usted mismo, SQL Server crea un nombre loco como "DF_TableN_Colum_95AFE4B5".Para que sea más fácil cambiar su esquema en el futuro, siempre nombrar explícitamente sus limitaciones!)

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

Nota: es posible tener el mismo nombre de tabla en diferentes esquemas, por lo que también debe unirse a la tabla sys.schemas. –

+1

@DanielJamesBryars sys.schemas ahora se agregó a la consulta. –

+0

Por favor vea [mi respuesta] (http://stackoverflow.com/a/32750390/57611), que es corto y agradable, funciona en todas las versiones de SQL Server, no tiene tablas 'sys', y es fácil de recordar . – ErikE

2

¿La columna COLUMN_DEFAULT de INFORMATION_SCHEMA.COLUMNS es lo que está buscando?

+0

Sí y no, me dice que hay un valor predeterminado y de qué se trata, pero también necesito el nombre de la restricción. – WildJoe

+1

Además, tenga en cuenta que si el inicio de sesión SQL de su tiempo de ejecución no posee el esquema dbo, solo puede encontrar valores NULOS en la columna COLUMN_DEFAULT. –

0

No creo que esté en INFORMATION_SCHEMA; probablemente tendrá que usar sysobjects o tablas/vistas en desuso relacionadas.

Pensaría que habría un tipo para esto en INFORMATION_SCHEMA.TABLE_CONSTRAINTS, pero no veo uno.

0

Probablemente porque en algunos de los DBMS SQL la "restricción predeterminada" no es realmente una restricción, no encontrará su nombre en "INFORMATION_SCHEMA.TABLE_CONSTRAINTS", por lo que su mejor opción es "INFORMATION_SCHEMA.COLUMNS" como otros ya lo he mencionado.

(SQLServer-ignorante aquí)

La única razón que se me ocurre cuando usted tiene que saber el nombre "default restricción" 's es si SQL Server no admite "ALTER TABLE xxx ALTER COLUMN yyy SET DEFAULT..." comando. Pero entonces ya se encuentra en una zona no estándar y debe usar las formas específicas del producto para obtener lo que necesita.

33

Parece que no hay nombres de Restricciones predeterminadas en las vistas Information_Schema.

uso SELECT * FROM sysobjects WHERE xtype = 'D' AND name = @name encontrar una restricción predeterminada por su nombre

+2

+1 para una consulta más simple –

+0

justo lo que necesitaba. Gracias – drdwilcox

+0

Responde directamente a la pregunta mejor que las alternativas posteriores (SQL 2000 y consulta por nombre de restricción). –

34

Se puede utilizar el siguiente para reducir los resultados aún más especificando el nombre de tabla y el nombre de columna que la restricción predeterminada se correlaciona con:

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' 
+0

Busco esta consulta simple desde hace un par de horas. Thannnnnkkk youuuu! – Samuel

+0

Debe haber o.xtype = 'D' para trabajar no es una base de datos sensible a mayúsculas y minúsculas. – IvanH

+0

@IvanH ¡Buen punto! –

0

Cómo sobre el uso de una combinación de CHECK_CONSTRAINTS y ​​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 
+0

CONSTRAINT_COLUMN_USAGE no contiene información sobre las restricciones predeterminadas. –

2
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

Un poco más de espacio en blanco sería bueno, pero esto es lo que el cartel original solicitó utilizando las vistas de catálogo de objetos (sys. *), Que Microsoft recomienda sobre las vistas de tablas del sistema de compatibilidad con versiones anteriores. –

11

El guión siguiente se enumeran todas las restricciones predeterminadas y los valores por defecto para las tablas de usuario en la base de datos en la que se está ejecutando:

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 
2

Si desea obtener una restricción por los nombres de columna o de la tabla, o si desea obtener todas las restricciones en el base de datos, busque otras respuestas. Sin embargo, si solo está buscando exactamente lo que la pregunta hace, a saber, "probar si existe una restricción predeterminada dada ... por el nombre de la restricción", entonces hay una manera mucho más fácil.

Aquí es una respuesta preparada para el futuro que no utilice los sysobjects u otro sys tablas en absoluto:

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

estoy usando la escritura siguientes iniciales es posible recuperar todos los valores predeterminados (sp_binddefaults) y toda restricción predeterminada con secuencias de comandos siguientes :

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

objeto de catálogo Ver: sys.default_const rounds

Las vistas del esquema de información INFORMATION_SCHEMA son ANSI-obedientes, pero las restricciones predeterminadas no son parte del estándar ISO. Microsoft SQL Server proporciona vistas de catálogo del sistema para obtener información sobre los metadatos de los objetos de SQL Server.

sys.default_constraints vista de catálogo del sistema utilizada para obtener información sobre las restricciones predeterminadas.

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; 
Cuestiones relacionadas