Typkonvertierung mit Standard-Fallback-Wert


12

In PostgreSQL (8.4) versuche ich, einen Zeichenfolgenparameter in ein Datum innerhalb einer SQL-Abfrage zu konvertieren, wobei ich darauf zurückgreife, now()wann die Zeichenfolge kein gültiges (oder leeres) Datum ist.

In "Pseudo-SQL" wäre dies ungefähr so:

SELECT CASE WHEN ? is not a valid date THEN now()::DATE ELSE CAST(? AS DATE) END;

Ich habe versucht, das Problem zu vereinfachen, um mithilfe dieser beiden Abfragen eine leere Zeichenfolge zu erkennen:

SELECT CASE WHEN ?='' THEN now()::DATE ELSE CAST(? AS DATE) END;
SELECT DATE(CASE WHEN ?='' THEN now() ELSE ?  END);

Wenn der Parameter beispielsweise lautet '', entspricht dies:

SELECT CASE WHEN ''='' THEN now()::DATE ELSE CAST('' AS DATE) END;
SELECT DATE(CASE WHEN ''='' THEN now() ELSE ''  END);

Beide scheitern mit ERROR: invalid input syntax for type timestamp with time zone: "" Es macht Sinn, aber es impliziert, dass der ELSEBlock ausgewertet wird (oder zumindest, dass seine Typen aufgelöst werden), ob die CASEBedingung wahr ist oder nicht . Das Folgende funktioniert, aber was ich möchte, dass die CASE(oder eine ähnliche) Bedingung behandelt wird, ist genau dann der Fall, wenn es sich nicht um ein gültiges Datum handelt.

SELECT CASE WHEN '2011-12-01'='' THEN now()::DATE ELSE CAST('2011-12-01' AS DATE) END;

Das, was ich einer funktionierenden Lösung am nächsten kam, ist Folgendes:

SELECT DATE(COALESCE(NULLIF(?, '')::timestamptz, now()));

In diesem Fall gibt der Parameter ''das aktuelle Datum zurück, andernfalls das im Zeichenfolgenparameter übergebene Datum (vorausgesetzt, es kann in ein gültiges Datum umgewandelt werden).

Was ich möchte, ist einen Schritt weiter zu gehen und alles, was nicht in eine DATEVerwendung umgewandelt werden kann, zum aktuellen Datum zu machen. Ich denke, dies könnte mit einer benutzerdefinierten PL / pgSQL-Funktion erfolgen, die diesen Fehler abfängt. Kann dies jedoch ohne eine solche Funktion in "einfachem" SQL (oder zumindest mit den vorhandenen PostgreSQL-Funktionen) erfolgen?

Antworten:


6

Sie können SQL-Ausnahmen in einer SQL-Anweisung nicht wie in PL / pgSQL behandeln .

Sie müssen eine benutzerdefinierte Funktion schreiben, wie Sie vorschlagen, zum Beispiel:

create function is_valid_date(text) returns boolean language plpgsql immutable as $$
begin
  return case when $1::date is null then false else true end;
exception when others then
  return false;
end;$$;

Prüfung:

with w as (select 'asdsad'::text dt1, '2011-12-01'::text dt2, null::text dt3)
select case when is_valid_date(dt1) then dt1::date else current_date end d1,
       case when is_valid_date(dt2) then dt2::date else current_date end d2,
       case when is_valid_date(dt3) then dt3::date else current_date end d3
from w;

     d1     |     d2     |     d3
------------+------------+------------
 2011-12-06 | 2011-12-01 | 2011-12-06

Gutschrift für diesen Mailinglistenbeitrag
Jack sagt, versuche topanswers.xyz
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.