2010-10-14 14 views
97

Duplicar posible:
How do you list the primary key of a SQL Server table?SQL Server: Obtener la clave principal tabla mediante consulta SQL

Quiero obtener la clave principal de una tabla en particular mediante consulta SQL para base de datos SQL Server.

En MySQL estoy usando siguiente consulta para obtener la clave principal tabla:

SHOW KEYS FROM tablename WHERE Key_name = 'PRIMARY' 

Lo que es equivalente a consulta anterior para SQL Server?.

Si hay una consulta que funciona tanto para MySQL y SQL Server entonces será un caso ideal.

+1

Tenga cuidado al usar INFORMATION_SCHEMA.VIEWS porque no pueden regresar de forma fiable y CONSTRAINT_SCHEMA TABLE_SCHEMA (ver, por ejemplo: http://msdn.microsoft.com/en-us /library/ms181757.aspx) Para la discusión sobre este problema, consulte este subproceso de MSDN http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/732bd071-2c1f-4c23-9215-4ff3822c63c3 – Naomi

Respuesta

49

encontrado otra:

SELECT KU.table_name as TABLENAME,column_name as PRIMARYKEYCOLUMN 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC 
INNER JOIN 
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU 
      ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND 
      TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME AND 
      KU.table_name='yourTableName' 
ORDER BY KU.TABLE_NAME, KU.ORDINAL_POSITION; 

He probado esto en SQL Server 2003/2005

+4

Lo importante de esto es que le da los campos PK ** en orden **. ¡A veces importa! – Kip

+0

Otra versión que los ordena en una lista separada por comas está aquí: http://stackoverflow.com/a/42985271/1339704 – Soenhay

+0

Usando 'information_schema' (en contraste con' sys.'views) siempre es una buena idea, ya que es el estándar oficial y se implementa en un par de otros sistemas de bases de datos. – Jakub

9

De memoria, o es este

SELECT * FROM sys.objects 
WHERE type = 'PK' 
AND object_id = OBJECT_ID ('tableName') 

o esta ..

SELECT * FROM sys.objects 
WHERE type = 'PK' 
AND parent_object_id = OBJECT_ID ('tableName') 

Creo que uno de ellos probablemente deben trabajar en función de cómo se almacenan los datos pero me temo que tengo no tiene acceso a SQL para verificar realmente lo mismo.

47

utilizando SQL Server 2005, puede intentar

SELECT i.name AS IndexName, 
     OBJECT_NAME(ic.OBJECT_ID) AS TableName, 
     COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName 
FROM sys.indexes AS i INNER JOIN 
     sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID 
           AND i.index_id = ic.index_id 
WHERE i.is_primary_key = 1 

encontrar en SQL SERVER – 2005 – Find Tables With Primary Key Constraint in Database

+0

Donde colocará mi nombre de tabla deseado (clave principal requerida para) en la consulta anterior? – Awan

+0

Muy bueno porque los muestra en orden de aparición en lugar de A-Z –

+0

Esta consulta corrió mucho más rápido que la respuesta más votada en mi pequeña y vacía base de datos. – Gobe

4
select * 
from sysobjects 
where xtype='pk' and 
    parent_obj in (select id from sysobjects where name='tablename') 

esto funcionará en SQL 2005

+0

Si publica código o XML, ** por favor ** resalte esas líneas en el editor de texto y haga clic en el botón "código" (101 010) en la barra de herramientas del editor para formatear y sintaxis y resaltarlo. –

+1

Además, en SQL Server 2005 en adelante, se recomienda utilizar las vistas del catálogo 'sys' y dejar de usar la tabla' sysobjects' heredada. Entonces, en su caso, use 'sys.tables' y' sys.columns' y otras vistas del catálogo del sistema. –

3

El código te daré las obras y no, recupera solo claves, pero una gran cantidad de datos de una tabla en SQL Server. Se prueba en SQL Server 2k5/2k8, no sé aproximadamente 2k. ¡Disfrutar!

SELECT DISTINCT 
    sys.tables.object_id AS TableId, 
    sys.columns.column_id AS ColumnId, 
    sys.columns.name AS ColumnName, 
    sys.types.name AS TypeName, 
    sys.columns.precision AS NumericPrecision, 
    sys.columns.scale AS NumericScale, 
    sys.columns.is_nullable AS IsNullable, 
    ( SELECT 
      COUNT(column_name) 
     FROM 
      INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE 
     WHERE 
      TABLE_NAME = sys.tables.name AND 
      CONSTRAINT_NAME = 
       ( SELECT 
        constraint_name 
        FROM 
         INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
        WHERE 
         TABLE_NAME = sys.tables.name AND      
         constraint_type = 'PRIMARY KEY' AND 
         COLUMN_NAME = sys.columns.name 
       ) 
    ) AS IsPrimaryKey, 
    sys.columns.max_length/2 AS CharMaxLength /*BUG*/ 
FROM 
    sys.columns, sys.types, sys.tables 
WHERE 
    sys.tables.object_id = sys.columns.object_id AND 
    sys.types.system_type_id = sys.columns.system_type_id AND 
    sys.types.user_type_id = sys.columns.user_type_id AND 
    sys.tables.name = 'TABLE' 
ORDER BY 
    IsPrimaryKey 

Puede utilizar solo la parte de la clave principal, pero creo que el resto puede ser útil. Saludos, David

123

también encontraron otro para SQL Server:

SELECT COLUMN_NAME 
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + QUOTENAME(CONSTRAINT_NAME)), 'IsPrimaryKey') = 1 
AND TABLE_NAME = 'TableName' AND TABLE_SCHEMA = 'Schema' 
+0

No se está ejecutando en SQL Server 2005. Agregué otra respuesta que es útil tanto para SQL Server 2003 como para SQL Server 2005. – Awan

+2

No sé por qué, pero OBJECTPROPERTY (OBJECT_ID (constraint_name), 'IsPrimaryKey') devuelve NULL en mi caso. La solución a continuación funciona bien. Tal vez su solución no funciona para complejos PK (2 y más columnas). – nZeus

+3

Si tiene el mismo problema que yo, la función de propiedad del objeto devuelve nulo porque la función id del objeto devolverá nulo si la restricción está asociada a un objeto que no está en el esquema dbo. Debe concatenar el esquema de restricción al nombre de restricción dentro de la función de identificación de objeto. Espero que esto ayude a alguien más. – jwhaley58

1

También es (Transact-SQL) ... según BOL.

-- exec sp_serveroption 'SERVER NAME', 'data access', 'true' --execute once 

EXEC sp_primarykeys @table_server = N'server_name', 
    @table_name = N'table_name', 
    @table_catalog = N'db_name', 
    @table_schema = N'schema_name'; --frequently 'dbo' 
4

Esto debería enumerar todas las limitaciones y al final usted puede poner sus filtros

/* CAST IS DONE , SO THAT OUTPUT INTEXT FILE REMAINS WITH SCREEN LIMIT*/ 
WITH ALL_KEYS_IN_TABLE (CONSTRAINT_NAME,CONSTRAINT_TYPE,PARENT_TABLE_NAME,PARENT_COL_NAME,PARENT_COL_NAME_DATA_TYPE,REFERENCE_TABLE_NAME,REFERENCE_COL_NAME) 
AS 
(
SELECT CONSTRAINT_NAME= CAST (PKnUKEY.name AS VARCHAR(30)) , 
     CONSTRAINT_TYPE=CAST (PKnUKEY.type_desc AS VARCHAR(30)) , 
     PARENT_TABLE_NAME=CAST (PKnUTable.name AS VARCHAR(30)) , 
     PARENT_COL_NAME=CAST (PKnUKEYCol.name AS VARCHAR(30)) , 
     PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,   
     REFERENCE_TABLE_NAME='' , 
     REFERENCE_COL_NAME='' 

FROM sys.key_constraints as PKnUKEY 
    INNER JOIN sys.tables as PKnUTable 
      ON PKnUTable.object_id = PKnUKEY.parent_object_id 
    INNER JOIN sys.index_columns as PKnUColIdx 
      ON PKnUColIdx.object_id = PKnUTable.object_id 
      AND PKnUColIdx.index_id = PKnUKEY.unique_index_id 
    INNER JOIN sys.columns as PKnUKEYCol 
      ON PKnUKEYCol.object_id = PKnUTable.object_id 
      AND PKnUKEYCol.column_id = PKnUColIdx.column_id 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl 
      ON oParentColDtl.TABLE_NAME=PKnUTable.name 
      AND oParentColDtl.COLUMN_NAME=PKnUKEYCol.name 
UNION ALL 
SELECT CONSTRAINT_NAME= CAST (oConstraint.name AS VARCHAR(30)) , 
     CONSTRAINT_TYPE='FK', 
     PARENT_TABLE_NAME=CAST (oParent.name AS VARCHAR(30)) , 
     PARENT_COL_NAME=CAST (oParentCol.name AS VARCHAR(30)) , 
     PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,  
     REFERENCE_TABLE_NAME=CAST (oReference.name AS VARCHAR(30)) , 
     REFERENCE_COL_NAME=CAST (oReferenceCol.name AS VARCHAR(30)) 
FROM sys.foreign_key_columns FKC 
    INNER JOIN sys.sysobjects oConstraint 
      ON FKC.constraint_object_id=oConstraint.id 
    INNER JOIN sys.sysobjects oParent 
      ON FKC.parent_object_id=oParent.id 
    INNER JOIN sys.all_columns oParentCol 
      ON FKC.parent_object_id=oParentCol.object_id /* ID of the object to which this column belongs.*/ 
      AND FKC.parent_column_id=oParentCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/ 
    INNER JOIN sys.sysobjects oReference 
      ON FKC.referenced_object_id=oReference.id 
    INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl 
      ON oParentColDtl.TABLE_NAME=oParent.name 
      AND oParentColDtl.COLUMN_NAME=oParentCol.name 
    INNER JOIN sys.all_columns oReferenceCol 
      ON FKC.referenced_object_id=oReferenceCol.object_id /* ID of the object to which this column belongs.*/ 
      AND FKC.referenced_column_id=oReferenceCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/ 

) 

select * from ALL_KEYS_IN_TABLE 
where 
    PARENT_TABLE_NAME in ('YOUR_TABLE_NAME') 
    or REFERENCE_TABLE_NAME in ('YOUR_TABLE_NAME') 
ORDER BY PARENT_TABLE_NAME,CONSTRAINT_NAME; 

Como referencia, lea a través de - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx

5
SELECT COLUMN_NAME FROM {DATABASENAME}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE TABLE_NAME LIKE '{TABLENAME}' AND CONSTRAINT_NAME LIKE 'PK%' 

DONDE
{} = DataBaseName su base de datos de su servidor y
{TABLENAME} = Su nombre de la tabla de la que desea ver la clave principal.

NOTA: ingrese el nombre de su base de datos y el nombre de la tabla sin corchetes.

2

Tenga en cuenta que si desea obtener el campo primario exacto, debe poner TABLE_NAME y TABLE_SCHEMA en la condición.

esta solución debería funcionar:

select COLUMN_NAME from information_schema.KEY_COLUMN_USAGE 
where CONSTRAINT_NAME='PRIMARY' AND TABLE_NAME='TABLENAME' 
AND TABLE_SCHEMA='DATABASENAME' 
+1

CONSTRAINT_NAME no siempre es 'PRIMARIO' – frostymarvelous

Cuestiones relacionadas