Array
(
)

Tratamento de exceções de banco php e postgres

Ef
   - 14 set 2014

Olá pessoal, gostaria de saber como eu posso tratar os erros do postgres com o php, pois quando da uma exceção por exemplo de uma foreing key o erro aparece "grosseiramente" para o usuário, e eu gostaria de trata-lo para então mostrar a mensagem para que o usuário comum entenda.
Como posso fazer isso?
Obrigado.

William (devwilliam)
   - 15 set 2014

Olá edinho, se você estiver usando PDO para se conectar esse link vai ajudar você a lançar suas próprias exceções:
http://pt.stackoverflow.com/questions/2380/como-lan%C3%A7ar-minhas-pr%C3%B3prias-exce%C3%A7%C3%B5es-com-o-pdo

Ef
   - 16 set 2014

Olá wilian, valeu pela força, mas não estou usando pdo não.

Marisiana
   - 17 set 2014

Por acaso, você está utilizando function no PostgreSQL?

Wander :)
   - 17 set 2014

Ve se tem como pegar o codigo do erro. Exemplo: se codigo for igual a 407 = algum dado nao esta preenchido

Marisiana
   - 17 set 2014

No final da pagina deste link ( http://www.postgresql.org/docs/9.1/static/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING ) tem uma explicação de como você pode realizar o controle de exceções no próprio PostgreSQL. Assim, vc pode criar, por exemplo, uma function para uma determinada finalidade e o EXCEPTION para verificar as possíveis ocorrências de erros.
#Código

CREATE TABLE db (a INT PRIMARY KEY, b TEXT);

CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
$$
BEGIN
    LOOP
        -- first try to update the key
        UPDATE db SET b = data WHERE a = key;
        IF found THEN
            RETURN;
        END IF;
        -- not there, so try to insert the key
        -- if someone else inserts the same key concurrently,
        -- we could get a unique-key failure
        BEGIN
            INSERT INTO db(a,b) VALUES (key, data);
            RETURN;
        EXCEPTION WHEN unique_violation THEN
            -- Do nothing, and loop to try the UPDATE again.
        END;
    END LOOP;
END;
$$
LANGUAGE plpgsql;

SELECT merge_db(1, 'david');
SELECT merge_db(1, 'dennis');

Ef
   - 17 set 2014

Marisiana, sim, estou usando function, porém já consegui resolver de outra maneira.

Primeiramente no pg_query eu coloquei o @ antes ficando '@pg_query', para não mostrar o erro ao usuário.
Depois para pegar o erro eu usei o comando 'pg_last_error()'.
E para tratar eu criei uma view onde pega qual chave estrangeira foi violada e mostra a mensagem personalizada ao usuário.

Obrigado a todos.

Marisiana
   - 18 set 2014

Por nada Edinho!
Uma curiosidade: Essa view vc consegue utilizar em todas as functions?

Ef
   - 18 set 2014

Então Marisiana, na verdade essa view eu criei especificamente para o caso que eu quero tratar, que no caso é o tratamento dos erros referente a violação de chaves estrangeiras.

Primeiramente em todas as tabelas do meu banco eu coloquei um comentário, por exemplo, tabela alunos, coloquei o comentário 'Cadastro de alunos', e assim sucessivamente.
Depois eu criei a view, que segue o código abaixo.

CREATE OR REPLACE VIEW v_restricao_banco AS
SELECT tab.nome_restricao,
tab.tabela_origem,
tab.comentario_origem,
tab.tabela_destino,
tab.comentario_destino,
((('Restrição de integridade! O '||tab.comentario_destino)||' esta sendo usado pelo ')||tab.comentario_origem)||'.' AS excecao
FROM (SELECT c.conname AS nome_restricao,
t.relname AS tabela_origem,
obj_description(t.oid) AS comentario_origem,
t2.relname AS tabela_destino,
obj_description(t2.oid) AS comentario_destino
FROM pg_constraint c,
pg_class t,
pg_class t2,
pg_namespace n
WHERE c.conrelid = t.oid
AND c.confrelid = t2.oid
AND n.oid = t.relnamespace
AND n.oid = t2.relnamespace
AND n.nspname = 'public'
AND c.contype = 'f') tab

Depois que eu criei a view, quando dispara um erro de chave estrangeira eu faço o select abaixo para trazer a informação do problema mais limpo para o usuário verificar.

"select aa.excecao from v_restricao_banco aa where '".pg_last_error()."' like '%'||aa.nome_restricao||'%'".

Marisiana
   - 19 set 2014

Entendi Edinho!
Mas vou fazer uma observação...
Você criou um objeto pra tratar uma situação que pode ser tratada na própria function, pois o postgreSQL tem recursos próprios pra tratar exceções.