PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Fractionner la chaîne donnée et préparer l'instruction case

Nettoyer la configuration :

CREATE TABLE tbl (
  given_date date
, set_name varchar
);

Utilisez un terme au singulier comme nom de colonne pour un simple valeur.
Le type de données est évidemment date et non un timestamp .

Pour transformer vos paramètres de texte en un tableau utile :

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" est pratique mais a ses mises en garde. Postgres 9.4 ajoute une solution propre, Postgres 10 finalement aseptisé le comportement de celui-ci. Voir ci-dessous.

Exécution dynamique

Déclaration préparée

Les instructions préparées ne sont visibles que pour la session de création et meurent avec elle. Par documentation :

Les instructions préparées ne durent que pendant la durée de la session de base de données en cours.

PREPARE une fois par 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;

Ou utilisez les outils fournis par votre client pour préparer la déclaration.
Exécutez n fois avec des paramètres arbitraires :

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

Fonction côté serveur

Les fonctions sont persistantes et visibles pour tous séances.

CREATE FUNCTION une fois :

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;

Appel n fois :

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

Violon SQL

Conception supérieure

Utilisez des paramètres de tableau (peuvent toujours être fournis sous forme de littéraux de chaîne), un daterange type (les deux pg 9.3) et le nouveau parallèle unnest() (page 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;

<@ étant l'opérateur "l'élément est contenu par".

Appel :

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

Détails :

  • Désimbriquer plusieurs baies en parallèle