PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Teilen Sie die angegebene Zeichenfolge und bereiten Sie die Case-Anweisung vor

Saubere Einrichtung:

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Verwenden Sie einen Begriff im Singular als Spaltennamen für einen Single value.
Der Datentyp ist offensichtlich date und kein timestamp .

Um Ihre Textparameter in eine nützliche Tabelle umzuwandeln:

SELECT unnest(string_to_array('2001-01-01to2001-01-05,2001-01-10to2001-01-15', ',')) AS date_range
     , unnest(string_to_array('s1,s2', ',')) AS set_name;

"Parallel Unnest" ist praktisch, hat aber seine Einschränkungen. Postgres 9.4 fügt eine saubere Lösung hinzu, Postgres 10 schließlich saniert das Verhalten dieser. Siehe unten.

Dynamische Ausführung

Vorbereitete Erklärung

Vorbereitete Anweisungen sind nur für die erstellende Sitzung sichtbar und sterben mit ihr. Per Dokumentation:

Vorbereitete Anweisungen gelten nur für die Dauer der aktuellen Datenbanksitzung.

PREPARE einmal pro Sitzung :

PREPARE upd_tbl AS
UPDATE tbl t
SET    set_name = s.set_name
FROM  (
   SELECT unnest(string_to_array($1, ',')) AS date_range
        , unnest(string_to_array($2, ',')) AS set_name
   ) s
WHERE t.given_date BETWEEN split_part(date_range, 'to', 1)::date
                       AND split_part(date_range, 'to', 2)::date;

Oder verwenden Sie Tools, die von Ihrem Kunden bereitgestellt werden, um die Anweisung vorzubereiten.
Führen Sie n-mal mit beliebigen Parametern aus:

EXECUTE upd_tbl('2001-01-01to2001-01-05,2001-01-10to2001-01-15', 's1,s4');

Serverseitige Funktion

Funktionen werden beibehalten und sind für alle sichtbar Sitzungen.

CREATE FUNCTION einmal :

CREATE OR REPLACE FUNCTION f_upd_tbl(_date_ranges text, _names text)
  RETURNS void AS
$func$
UPDATE tbl t
SET    set_name = s.set_name
FROM  (
   SELECT unnest(string_to_array($1, ',')) AS date_range
        , unnest(string_to_array($2, ',')) AS set_name
   ) s
WHERE  t.given_date BETWEEN split_part(date_range, 'to', 1)::date
                        AND split_part(date_range, 'to', 2)::date
$func$  LANGUAGE sql;

Aufruf n Mal:

SELECT f_upd_tbl('2001-01-01to2001-01-05,2001-01-20to2001-01-25', 's2,s5');

SQL-Geige

Überlegenes Design

Verwenden Sie Array-Parameter (können weiterhin als String-Literale bereitgestellt werden), einen daterange type (beide Seite 9.3) und das neue parallele unnest() (Seite 9.4 ).

CREATE OR REPLACE FUNCTION f_upd_tbl(_dr daterange[], _n text[])
  RETURNS void AS
$func$
UPDATE tbl t
SET    set_name = s.set_name
FROM   unnest($1, $2) s(date_range, set_name)
WHERE  t.given_date <@ s.date_range
$func$  LANGUAGE sql;

<@ der "Element ist enthalten in"-Operator.

Aufruf:

SELECT f_upd_tbl('{"[2001-01-01,2001-01-05]"
                  ,"[2001-01-20,2001-01-25]"}', '{s2,s5}');

Einzelheiten:

  • Entschachteln Sie mehrere Arrays parallel