No PostgreSQL (8.4), estou tentando converter um parâmetro de string em uma data dentro de uma consulta SQL, voltando para now()
quando a string não é uma data válida (ou vazia).
Em "pseudo-SQL", seria algo assim:
SELECT CASE WHEN ? is not a valid date THEN now()::DATE ELSE CAST(? AS DATE) END;
Tentei simplificar o problema para detectar uma string vazia usando essas duas consultas:
SELECT CASE WHEN ?='' THEN now()::DATE ELSE CAST(? AS DATE) END;
SELECT DATE(CASE WHEN ?='' THEN now() ELSE ? END);
Por exemplo, se o parâmetro for ''
, isso é equivalente a isto:
SELECT CASE WHEN ''='' THEN now()::DATE ELSE CAST('' AS DATE) END;
SELECT DATE(CASE WHEN ''='' THEN now() ELSE '' END);
Ambos falham com ERROR: invalid input syntax for type timestamp with time zone: ""
Faz sentido, mas implica que o ELSE
bloco seja avaliado (ou pelo menos que seus tipos sejam resolvidos) independentemente de a CASE
condição ser verdadeira ou não. O seguinte funciona, mas o que eu gostaria que a CASE
condição (ou semelhante) tratasse é precisamente o caso em que não é uma data válida.
SELECT CASE WHEN '2011-12-01'='' THEN now()::DATE ELSE CAST('2011-12-01' AS DATE) END;
O mais próximo que cheguei de uma solução funcional é o seguinte:
SELECT DATE(COALESCE(NULLIF(?, '')::timestamptz, now()));
Neste caso, se o parâmetro for ''
, retorna a data atual, caso contrário, retorna a data passada no parâmetro string (desde que possa ser transformada em uma data válida).
O que eu gostaria é de dar um passo além e fazer com que qualquer coisa que não possa ser transformada em DATE
uso seja a data atual. Acho que isso poderia ser feito usando uma função PL/pgSQL personalizada que interceptaria esse erro , mas isso pode ser feito sem essa função, em SQL "simples" (ou pelo menos usando as funções existentes do PostgreSQL)?
Você não pode lidar com exceções SQL dentro de uma instrução SQL como você pode dentro do PL/pgSQL .
Você deve escrever uma função personalizada como você sugere, por exemplo:
teste: