2010-03-23 19 views
205

que tienen este SQL:¿Cómo verificar si existe una restricción en el servidor Sql?

ALTER TABLE dbo.ChannelPlayerSkins 
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels 

pero al parecer, en algunas otras bases de datos que utilizamos, la restricción tiene un nombre diferente. ¿Cómo puedo verificar si hay una restricción con el nombre FK_ChannelPlayerSkins_Channels?

+0

http://geekswithblogs.net/deadlydog/archive/2012/09/14/sql-server-script-commands-to-check-if-object-exists-and.aspx – gotqn

Respuesta

271

intente esto:

SELECT 
    * 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
    WHERE CONSTRAINT_NAME ='FK_ChannelPlayerSkins_Channels' 

- EDITAR -

Cuando originalmente respondió esta pregunta, estaba pensando en "clave externa" porque la pregunta original preguntaba acerca de cómo encontrar "FK_ChannelPlayerSkins_Channels". Desde entonces, muchas personas han comentado en la búsqueda de otras "restricciones" aquí hay algunas otras consultas para ello:

--Returns one row for each CHECK, UNIQUE, PRIMARY KEY, and/or FOREIGN KEY 
SELECT * 
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
    WHERE CONSTRAINT_NAME='XYZ' 


--Returns one row for each FOREIGN KEY constrain 
SELECT * 
    FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS 
    WHERE CONSTRAINT_NAME='XYZ' 


--Returns one row for each CHECK constraint 
SELECT * 
    FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS 
    WHERE CONSTRAINT_NAME='XYZ' 

aquí es un método alternativo

--Returns 1 row for each CHECK, UNIQUE, PRIMARY KEY, FOREIGN KEY, and/or DEFAULT 
SELECT 
    OBJECT_NAME(OBJECT_ID) AS NameofConstraint 
     ,SCHEMA_NAME(schema_id) AS SchemaName 
     ,OBJECT_NAME(parent_object_id) AS TableName 
     ,type_desc AS ConstraintType 
    FROM sys.objects 
    WHERE type_desc LIKE '%CONSTRAINT' 
     AND OBJECT_NAME(OBJECT_ID)='XYZ' 

Si necesita información aún más limitación, observar el interior del procedimiento almacenado del sistema master.sys.sp_helpconstraint para ver cómo obtener cierta información. Para ver el código fuente usando SQL Server Management Studio ingrese al "Explorador de Objetos". Desde allí, expande la base de datos "Master", luego expande "Programmability", luego "Stored Procedures", luego "System Stored Procedures". A continuación, puede encontrar "sys.sp_helpconstraint" y hacer clic con el botón derecho y seleccionar "modificar". Solo tenga cuidado de no guardar ningún cambio. Además, puede usar este procedimiento almacenado del sistema en cualquier tabla utilizándolo como EXEC sp_helpconstraint YourTableNameHere.

+2

Una cosa a tener en cuenta, en mi SQL para agregar la restricción, utilicé corchetes alrededor del nombre como, [fk_Client_ProjectID_Project]. DEBE eliminar los corchetes en la cláusula WHERE. – ScubaSteve

+2

No hay nada de malo entre corchetes. Esta es una pregunta de SQL Server, no una de MySQL. –

+1

Si se trata de una restricción única que necesita una versión ligeramente diferente: SI NO EXISTE (SELECCIONAR 1 DE INFORMATION_SCHEMA.TABLE_CONSTRAINTS donde CONSTRAINT_NAME = 'UNIQUE_Order_ExternalReferenceId') COMENZAR \t ALTER TABLE Solicitar \t \t Agregar restricción UNIQUE_Order_ExternalReferenceId \t \t único (ExternalReferenceId) END –

2

INFORMATION_SCHEMA es tu amigo. Tiene todo tipo de vistas que muestran todo tipo de información de esquema. Verifique las vistas de su sistema. Descubrirá que tiene tres vistas que tratan con restricciones, una de ellas es CHECK_CONSTRAINTS.

19

estás mirando algo como esto, a continuación se prueba en SQL Server 2005

SELECT * FROM sys.check_constraints WHERE 
object_id = OBJECT_ID(N'[dbo].[CK_accounts]') AND 
parent_object_id = OBJECT_ID(N'[dbo]. [accounts]') 
39

Si busca otro tipo de restricción, p. por defecto, debe usar una consulta diferente (De How do I find a default constraint using INFORMATION_SCHEMA? respondida por devio). Use:

SELECT * FROM sys.objects WHERE type = 'D' AND name = @name 

para encontrar una restricción predeterminada por su nombre.

He reunido diferente 'si no existe "cheques en mi post" DDL 'IF not Exists" conditions to make SQL scripts re-runnable"

+3

sysobjects se eliminarán en futuras versiones. Utilice sys.objects en su lugar –

+0

Si utiliza la consulta anterior, tenga en cuenta que la tabla sys.objects no tiene la columna xtype, debe ser de tipo. No se puede editar la respuesta directamente ya que es una actualización de un solo carácter (debe tener al menos 6 caracteres). – pennanth

+0

@pennanth: Gracias, corregido –

24
IF (OBJECT_ID('FK_ChannelPlayerSkins_Channels') IS NOT NULL) 
8

Sólo es algo a tener en cuenta ......

En SQL Server 2008 R2 SSMS , el "script restricción como -> DROP y CREATE a" comando produce T-SQL, como a continuación

USE [MyDatabase] 
GO 

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DEF_Detail_IsDeleted]') AND type = 'D') 
BEGIN 
ALTER TABLE [Patient].[Detail] DROP CONSTRAINT [DEF_Detail_IsDeleted] 
END 

GO 

USE [MyDatabase] 
GO 

ALTER TABLE [Patient].[Detail] ADD CONSTRAINT [DEF_Detail_IsDeleted] DEFAULT ((0)) FOR [IsDeleted] 
GO 

Fuera de la caja, este script no baja la restricción debido a la instrucción SELECT devuelve 0 filas. (ver la publicación Microsoft Connect).

El nombre de la restricción predeterminada es incorrecto, pero entiendo que también tiene algo que ver con la función OBJECT_ID porque cambiar el nombre no soluciona el problema.

Para corregir esto, eliminé el uso de OBJECT_ID y usé el nombre de restricción predeterminado en su lugar.

(SELECT * FROM dbo.sysobjects WHERE [name] = (N'DEF_Detail_IsDeleted') AND type = 'D') 
+1

Parece que el script no califica el nombre. Sería más seguro usar 'OBJECT_ID (N '[YourSchema]. [DEF_Detail_IsDeleted]')' en caso de que tenga 2 restricciones del mismo nombre en diferentes esquemas. –

1

Utilizo esto para comprobar y las restricciones remotas en una columna. Debería tener todo lo que necesitas.

DECLARE 
    @ps_TableName VARCHAR(300) 
    , @ps_ColumnName VARCHAR(300) 

SET @ps_TableName = 'mytable' 
SET @ps_ColumnName = 'mycolumn' 

DECLARE c_ConsList CURSOR LOCAL STATIC FORWARD_ONLY FOR 
    SELECT 
    'ALTER TABLE ' + RTRIM(tb.name) + ' drop constraint ' + sco.name AS csql 
    FROM 
     sys.Objects tb 
     INNER JOIN sys.Columns tc on (tb.Object_id = tc.object_id) 
     INNER JOIN sys.sysconstraints sc ON (tc.Object_ID = sc.id and tc.column_id = sc.colid) 
     INNER JOIN sys.objects sco ON (sc.Constid = sco.object_id) 
    where 
     [email protected]_TableName 
     AND [email protected]_ColumnName 
OPEN c_ConsList 
FETCH c_ConsList INTO @ls_SQL 
WHILE (@@FETCH_STATUS = 0) BEGIN 

    IF RTRIM(ISNULL(@ls_SQL, '')) <> '' BEGIN 
     EXECUTE(@ls_SQL) 
    END 
    FETCH c_ConsList INTO @ls_SQL 
END 
CLOSE c_ConsList 
DEALLOCATE c_ConsList 
181

La manera más fácil para comprobar la existencia de una restricción (y luego hacer algo como dejarlo caer si es que existe) es usar la función OBJECT_ID() ...

IF OBJECT_ID('dbo.[CK_ConstraintName]', 'C') IS NOT NULL 
    ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName 

OBJECT_ID puede se puede usar sin el segundo parámetro ('C' solo para restricciones de verificación) y eso también puede funcionar, pero si el nombre de la restricción coincide con el nombre de otros objetos en la base de datos, puede obtener resultados inesperados.

IF OBJECT_ID('dbo.[CK_ConstraintName]') IS NOT NULL 
    ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName 

OBJECT_ID también se puede utilizar con otros "limitaciones" tales como las limitaciones Exteriores clave o restricciones de clave principal, etc. Para obtener los mejores resultados, siempre incluir el tipo de objeto adecuado como el segundo parámetro para la función de OBJECT_ID:

Tipos de objetos restricción:

  • C = restricción CHECK
  • D = por defecto (de restricción o independiente)
  • F = restricción de clave externa
  • PK = CLAVE restricción PRIMARY
  • R = Regla (estilo antiguo, stand-alone)
  • UQ = restricción UNIQUE

También tenga en cuenta que el esquema es a menudo requerido. El esquema de restricciones generalmente toma el esquema de la tabla padre.

Si no coloca sus restricciones (o lo que sea que esté revisando) entre corchetes al usar este método, también puede causar un falso negativo: si su objeto utiliza caracteres inusuales (como a.), Se requieren corchetes.

+13

Lo importante es agregar el nombre del esquema en el parámetro a OBJECT_ID así: SI OBJECT_ID ('dbo.CK_ConstraintName', 'C') NO ES NULO. Sin especificar el esquema, devuelve NULL. – gator88

+0

Hola, gracias por tu respuesta, es realmente útil. ¿Me pregunto si se aplica a Oracle? –

+0

No funciona en sql2000. Simplemente use 'OBJECTPROPERTY (OBJECT_ID ('constraint_name'), 'IsConstraint') = 1' para que sea compatible desde la versión actual hasta sql2000. No se requiere el esquema 'dbo' también. – wqw

7

Utilizo la siguiente consulta para verificar una restricción existente antes de crearla.

IF (NOT EXISTS(SELECT 1 FROM sysconstraints WHERE OBJECT_NAME(constid) = 'UX_CONSTRAINT_NAME' AND OBJECT_NAME(id) = 'TABLE_NAME')) BEGIN 
... 
END 

Esto consulta la restricción por nombre que se dirige a un nombre de tabla dado. Espero que esto ayude.

3
IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.TableName')) 
BEGIN 
ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME 
END 
1
SELECT tabla.name as Tabla, 

     restriccion.name as Restriccion, 
     restriccion.type as Tipo, 
     restriccion.type_desc as Tipo_Desc 
FROM {DATABASE_NAME}.sys.objects tabla 

INNER JOIN {DATABASE_NAME}.sys.objects restriccion 

ON tabla.object_id = restriccion.parent_object_id 

WHERE tabla.type = 'U' - Solo tablas creadas por el usuario. 

AND restriccion.type = 'UQ' --Tipo de Restriccion UNIQUE 

ORDER BY tabla.name, restriccion.type_desc     
+1

Esta respuesta sería más útil si hubiera alguna explicación junto con ella, en lugar de solo el código de dumping. –

+1

Para el segundo @sphanley: Responde una vieja pregunta que ya tiene varias respuestas bien recibidas. Por favor explique qué es mejor o al menos específico acerca de su respuesta para que valga la pena publicarla. – honk

1

Puede utilizar la de arriba con una advertencia:

IF EXISTS(
    SELECT 1 FROM sys.foreign_keys 
    WHERE parent_object_id = OBJECT_ID(N'dbo.TableName') 
     AND name = 'CONSTRAINTNAME' 
) 
BEGIN 
    ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME 
END 

necesidad de utilizar el name = [Constraint name] ya que una tabla puede tener varias claves externas y todavía no tienen la clave externa está comprobando si

1
IF EXISTS(SELECT TOP 1 1 FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID(N'[dbo].[ChannelPlayerSkins]') AND name = 'FK_ChannelPlayerSkins_Channels') 
BEGIN 
    DROP CONSTRAINT FK_ChannelPlayerSkins_Channels 
END 
GO 
Cuestiones relacionadas