Como faço para descobrir se um índice de SQLite é único? (Com SQL)

StackOverflow https://stackoverflow.com/questions/157392

  •  03-07-2019
  •  | 
  •  

Pergunta

Eu quero descobrir, com uma consulta SQL, se um índice é ou não UNIQUE. Eu estou usando SQLite 3.

Eu tentei duas abordagens:

SELECT * FROM sqlite_master WHERE name = 'sqlite_autoindex_user_1'

Este retorna informações sobre o índice ( "tipo", "nome", "nome_tabela", "rootpage" e "SQL"). Note-se que a coluna SQL está vazia, quando o índice é criado automaticamente pelo SQLite.

PRAGMA index_info(sqlite_autoindex_user_1);

Isso retorna a colunas no índice ( "SEQNO", "cid" e "nome").

Qualquer outra sugestão?

Editar: O exemplo acima é de um índice gerado automaticamente, mas a minha pergunta é sobre índices em geral. Por exemplo, posso criar um índice com "CREATE UNIQUE INDEX index1 ON visita (usuário, data)". Parece nenhum comando SQL irá mostrar se o meu novo índice é ou não UNIQUE.

Foi útil?

Solução

PRAGMA INDEX_LIST('table_name');

Retorna uma tabela com 3 colunas:

  1. seq Unique ID numérico do índice
  2. name Nome do índice
  3. unique bandeira Singularidade (diferente de zero se o índice UNIQUE.)

Em seguida, basta percorrer as linhas resultantes até ver o nome do índice que deseja consulta (infelizmente você não pode ter uma cláusula WHERE em um comunicado PRAGMA.)

Outras dicas

Desde há ninguém venha com uma resposta boa, eu acho que a melhor solução é a seguinte:

  • Se o índice começa com "sqlite_autoindex", é um índice gerado automaticamente para uma coluna UNIQUE única
  • Caso contrário, olhar para a palavra-chave UNIQUE na coluna sql no sqlite_master mesa, com algo parecido com isto:

    SELECT * FROM sqlite_master ONDE type = 'index' e SQL LIKE '% UNIQUE%'

você pode programaticamente criar uma instrução SELECT para ver se alguma tuplas apontam para mais de uma linha. Se você voltar três colunas, foo, bar e baz, crie a seguinte consulta

select count(*) from t
group by foo, bar, baz
having count(*) > 1

Se que retorna nenhuma linha, o índice não é único, uma vez que mais de uma linha mapeia para a tupla dado. Se suportes sqlite3 derivado tabelas (eu ainda não tenho a necessidade, então eu não sei fora de mão), você pode fazer isso ainda mais sucinta:

select count(*) from (
    select count(*) from t
    group by foo, bar, baz
    having count(*) > 1
)

Isso irá retornar uma única linha no resultado, denotando o número de conjuntos de tuplas duplicadas. Se positivo, o índice não é único.

Você está perto:

1) Se o índice começa com "sqlite_autoindex", é um índice gerado automaticamente para a chave primária. No entanto, este será nas tabelas sqlite_master ou sqlite_temp_master dependendo dependendo se a tabela a ser indexada é temporário.

2) Você precisa estar atento para nomes de tabelas e colunas que contêm o unique substring, para que você deseja usar:

SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE 'CREATE UNIQUE INDEX%'

Consulte a documentação do website sqlite em Criar índice

Como de sqlite 3.16.0 você também pode usar funções Pragma:

SELECT distinct il.name
  FROM sqlite_master AS m,
       pragma_index_list(m.name) AS il,
       pragma_index_info(il.name) AS ii
 WHERE m.type='table' AND il.[unique] = 1;

A declaração acima irá listar todos os nomes de índices únicos.

SELECT DISTINCT m.name as table_name, ii.name as column_name
  FROM sqlite_master AS m,
       pragma_index_list(m.name) AS il,
       pragma_index_info(il.name) AS ii
 WHERE m.type='table' AND il.[unique] = 1;

A declaração acima irá retornar todas as tabelas e suas colunas se a coluna é parte de um índice exclusivo.

A partir da docs :

As funções com valor de tabela para recurso PRAGMA foi adicionado em SQLite versão 3.16.0 (2017/01/02). Versões anteriores do SQLite não pode usar esse recurso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top