Se você precisar descobrir se um banco de dados possui tabelas que não possuem uma chave primária, poderá executar qualquer um dos scripts a seguir no SQL Server para retornar apenas essas tabelas.
Todos esses scripts aproveitam o
OBJECTPROPERTY()
função. Esta função aceita um TableHasPrimaryKey
argumento que você pode verificar para um valor de 0
. Se for 0
, a tabela não tem uma chave primária. Se for 1
ele faz. Portanto, você também pode usar esta função para retornar todas as tabelas com uma chave primária. Esses scripts simplesmente retornam o nome da tabela e seu esquema, mas você sempre pode modificá-los para retornar mais colunas.
Opção 1 – OBJECTPROPERTY() com sys.tables
O
sys.tables
a visualização do sistema é provavelmente o lugar mais óbvio para começar. Esta visão retorna uma linha para cada tabela de usuário e quando usamos OBJECTPROPERTY()
para filtrar os resultados com base no TableHasPrimaryKey
propriedade sendo 0
, obtemos apenas as tabelas sem chave primária. USE Test; SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTY(object_id, 'TableHasPrimaryKey') = 0 ORDER BY [Schema], [Table];
Resultado:
Changed database context to 'Test'. +----------+--------------------+ | Schema | Table | |----------+--------------------| | dbo | Datetime2Test | | dbo | Datetime2Test2 | | dbo | DatetimeoffsetTest | | dbo | Individual | | dbo | Occupation | | dbo | Team | | dbo | TimeTest | +----------+--------------------+ (7 rows affected)
Nesse caso, meu banco de dados atual é um banco de dados de teste com várias tabelas sem chaves primárias.
Se eu executar a mesma instrução em outro banco de dados, não obtenho resultados:
USE Music; SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTY(object_id, 'TableHasPrimaryKey') = 0 ORDER BY [Schema], [Table];
Resultado:
Changed database context to 'Music'. (0 rows affected)
Opção 2 – OBJECTPROPERTY() com INFORMATION_SCHEMA.TABLES
Este exemplo é semelhante ao anterior, exceto que desta vez estou consultando o
INFORMATION_SCHEMA.TABLES
visualizar. As exibições do esquema de informações incluídas no SQL Server estão em conformidade com a definição do padrão ISO para INFORMATION_SCHEMA. USE Test; SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE OBJECTPROPERTY(OBJECT_ID(CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)),'TableHasPrimaryKey') = 0 AND TABLE_TYPE='BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME;
Resultado:
Changed database context to 'Test'. +----------------+--------------------+ | TABLE_SCHEMA | TABLE_NAME | |----------------+--------------------| | dbo | Datetime2Test | | dbo | Datetime2Test2 | | dbo | DatetimeoffsetTest | | dbo | Individual | | dbo | Occupation | | dbo | Team | | dbo | TimeTest | +----------------+--------------------+ (7 rows affected)
Opção 3 – OBJECTPROPERTY() com sys.objects
Neste exemplo, eu consulto o
sys.objects
visualizar. Essa é uma visão mais geral quando comparada às duas anteriores e retorna informações sobre objetos com escopo de esquema (não apenas tabelas). Por isso, precisamos filtrar os resultados usando type = 'U'
. O U
aqui significa tabela definida pelo usuário. Novamente, podemos usar o
OBJECTPROPERTY()
função para filtrar os resultados apenas para as tabelas que não têm uma chave primária. USE Test; SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.objects WHERE type = 'U' AND OBJECTPROPERTY(OBJECT_ID(CONCAT(SCHEMA_NAME(schema_id), '.', name)), 'TableHasPrimaryKey') = 0 ORDER BY [Schema], [Table]
Resultado:
Changed database context to 'Test'. +----------+--------------------+ | Schema | Table | |----------+--------------------| | dbo | Datetime2Test | | dbo | Datetime2Test2 | | dbo | DatetimeoffsetTest | | dbo | Individual | | dbo | Occupation | | dbo | Team | | dbo | TimeTest | +----------+--------------------+ (7 rows affected)
Alternativamente, poderíamos filtrá-lo por
type_desc = 'USER_TABLE'
, o que produziria o mesmo resultado. USE Test; SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.objects WHERE type_desc = 'USER_TABLE' AND OBJECTPROPERTY(OBJECT_ID(CONCAT(SCHEMA_NAME(schema_id), '.', name)), 'TableHasPrimaryKey') = 0 ORDER BY [Schema], [Table]
Resultado:
Changed database context to 'Test'. +----------+--------------------+ | Schema | Table | |----------+--------------------| | dbo | Datetime2Test | | dbo | Datetime2Test2 | | dbo | DatetimeoffsetTest | | dbo | Individual | | dbo | Occupation | | dbo | Team | | dbo | TimeTest | +----------+--------------------+ (7 rows affected)