Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

3 maneiras de retornar todas as tabelas SEM uma chave primária no SQL Server


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)