segunda-feira, 29 de outubro de 2007

Criação de Índices com Procedures no PostgreSQL...

Vamos ver se consigo ajudar. Esta é uma dúvida do Juliano Fischer:

"Ola, estou com um problema em uma implementação e creio que pode me ajudar.
Preciso criar um subprograma armazenado que crie um indice,se já existir, informar o usuario, cado contratio, crie um indice.

criaIndice(campo,tabela);"

Não é tão difícil! A solução está abaixo, mas cuidado pois o meu código pode e deve ser melhorado. Nomes de parâmetros, métodos e variáveis e bons comentários podem ser adicionados.

Além disso, o exemplo só verifica um campo e exige que se tenha cuidado na nomenclatura dos campos, pois utiliza a cláusula LIKE.

1 - Recuperar informações dos índices.

A dica é utilizar a pg_indexes, visão de sistema mais amigável para saber se o índice existe:

select * from pg_indexes;

2 - Criar uma função parametrizada que indica se os índices existem. Observem que utilizei a linguagem SQL, e não Pl/ PgSql. Poderia utilizar qualquer outra liguagem, mas a lógica seria similar.

-- Verifica se existe o índice. Retorna ZERO se o índice não for encontrado
CREATE OR REPLACE FUNCTION retindex(in tabela varchar, in campo varchar) RETURNS bigint AS $$
select count(*) from pg_indexes where tablename = $1 and indexdef like '%' || $2 || '%'
$$
LANGUAGE SQL;


3 - Criar função parametrizada que cria o índice caso o mesmo não exista, e que utilize a função anterior. Linguagem Pl/ PgSQL.

-- Verifica e cria novo índice se for o caso
CREATE OR REPLACE FUNCTION criaindex (tabela varchar, campo varchar) RETURNS VARCHAR AS $$
DECLARE
func_cmd VARCHAR;
BEGIN
if retindex($1,$2) > 0 then
RETURN 'OK';
else
func_cmd := 'CREATE INDEX ' || $1 || '_IDX ON ' || $1 || ' (' || $2 || ')';
EXECUTE func_cmd;
RETURN func_cmd;
end if;
END;
$$ LANGUAGE plpgsql;

4 - Testando tudo

select retindex ('teste','c1');
select criaindex ('teste', 'c1');

Companheiros, quem pode dar um código que melhore ainda mais esta criação de índices com função armazenada? Juliano, resolvi seu problema?

2 comentários:

Anônimo disse...

Valws ai Claudio, muito legal!
Obrigado pela ajuda!
Vou testar aqui.

:D

Anônimo disse...

Pequena modificação necessária se você quiser criar mais de um índice na mesma tabela com esta função:

-- Verifica e cria novo índice se for o caso
CREATE OR REPLACE FUNCTION criaindex (tabela varchar, campo varchar)
RETURNS VARCHAR AS $$
DECLARE
func_cmd VARCHAR;
BEGIN
if retindex(tabela, campo) > 0 then
RETURN 'OK';
else
func_cmd := 'CREATE INDEX ' || tabela || '_' || campo || '_IDX ON ' || tabela || ' (' || campo || ')';
EXECUTE func_cmd;
RETURN func_cmd;
end if;
END;
$$ LANGUAGE plpgsql;