sql >> Databasteknik >  >> RDS >> PostgreSQL

Dela en given sträng och förbered fallbeskrivning

Rengör installationen:

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Använd en singular term som kolumnnamn för en singular värde.
Datatypen är uppenbarligen date och inte en timestamp .

För att omvandla dina textparametrar till en användbar tabell:

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;

"Parallell unnest" är behändig men har sina varningar. Postgres 9.4 lägger till en ren lösning, Postgres 10 så småningom sanerade beteendet av detta. Se nedan.

Dynamiskt utförande

Förberett uttalande

Förberedda uttalanden är endast synliga för den skapande sessionen och dör med den. Per dokumentation:

Förberedda satser varar bara under den aktuella databassessionen.

PREPARE en gång per session :

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;

Eller använd verktyg från din klient för att förbereda uttalandet.
Kör n gånger med godtyckliga parametrar:

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

Serversidans funktion

Funktioner kvarstår och är synliga för alla sessioner.

CREATE FUNCTION en gång :

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;

Ring n gånger:

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

SQL Fiddle

Överlägsen design

Använd arrayparametrar (kan fortfarande tillhandahållas som strängliteral), ett daterange typ (både sid 9.3) och den nya parallella unnest() (sid 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;

<@ är operatorn "elementet ingår av".

Ring:

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

Detaljer:

  • Ta bort flera arrayer parallellt


  1. Hur lagrar man lösenord i databasen säkert?

  2. Grunderna för att hantera datafiler i SQL Server

  3. Vad behöver jag för att undvika när jag skickar en förfrågan?

  4. Hur man skapar användare i Oracle och tilldelar privilegier