web-dev-qa-db-fra.com

Équivalent PostgreSQL des variables de requête MySQL?

Existe-t-il un moyen simple d'adapter ces types de requêtes MySQL à PostgreSQL:

  1. définir des variables dans MySQL comme

    set @aintconst = -333
    set @arealconst = -9.999
    

    Il semble que non .

  2. Assigner des variables à partir de requêtes SELECT et utiliser ces variables par la suite dans mon SQL comme:

     select @pfID := id from platform where bios like '%INTEL%'
     select @clientID := id from client where platformID = @pfID
    

Je serais très reconnaissant aux pointeurs, en particulier sur (2).

8
Daniel

C'est facile à faire dans une fonction PL/pgSQL (ou dans un bloc DO ):

create function myfunc() returns void language plpgsql as $$
  declare
    aintconst constant int = -333;
    arealconst constant real = -9.99;
    pfid int;
    clientid int;
  begin

    select id from platform where bios like '%INTEL%' into pfid;

    select id from client where platformID = pfid into clientid;

  end $$;

Vous pouvez également utiliser les variables GUC :

--set a session variable
set mycustom.var = 'value';

--use it
select * from mytable where some_column = current_setting('mycustom.var');

Ou vous pouvez utiliser un CTE avec une jointure:

with myvars as (
  select
    -333::int as aint,
    -9.99::real as areal
)

select 
  a.*
from mytable a
join myvars on true
where
  a.thing = aint
12
Neil McGuigan

J'utilise les instructions WITH:

WITH vars as (SELECT -333::double precision as aintconst,-9.999::double precision as arealconst)
UPDATE table SET col1 = (SELECT aintconst FROM vars)

et:

WITH platformx AS (SELECT id FROM platform WHERE bios like '%INTEL%')
SELECT id FROM client WHERE platformID = (SELECT id FROM platformx)
9
user2641043

Vous avez déjà répondu vous-même à cette question: non, il n'y en a pas en SQL simple. Vous pouvez utiliser PL/PgSQL si vous voulez des variables, dans une fonction ou un bloc DO.

La plupart des utilisations des variables de requête dans MySQL sont satisfaites par les CTE (WITH requêtes), les fonctions de fenêtre, etc. dans PostgreSQL.


Eh bien, en fait, il existe, mais ils ne conviennent pas à une utilisation générale dans les requêtes. Vous accédez généralement aux GUC personnalisés avec SET et SHOW, mais vous pouvez utiliser à la place:

regress=> select set_config('a.b', 'c', false);
 set_config 
------------
 c
(1 row)

regress=> select current_setting('a.b');
 current_setting 
-----------------
 c
(1 row)

Les GUC sont chers et c'est une mauvaise idée de l'utiliser pour des requêtes à usage général, mais il y a très occasionnellement une utilisation valide. Vous ne pouvez utiliser que des paramètres tels que myapp.variable, aussi.

3
Craig Ringer

Variables PSQL

Depuis au moins la version 7.1, le client PostgreSQL a fourni cette fonctionnalité avec psql variables

\set aintconst  -333
\set arealconst -9.999

SELECT :aintconst AS aintconst, :arealconst AS realconst;
 aintconst | realconst 
-----------+-----------
      -333 |    -9.999
(1 row)

Essentiellement, ce que vous voulez, c'est la possibilité de script SQL. PSQL a des conditions et des variables, et la possibilité de réinjecter du SQL généré dynamiquement, ce qui facilite ce travail. Ce n'est pas une fonctionnalité côté serveur dans le monde PostgreSQL, et généralement je le ferais dans un langage client (comme Node.js ou Perl plutôt que dans psql).

2
Evan Carroll

Pour le deuxième exemple, vous n'avez pas besoin d'une variable (ni dans MySQL ni dans Postgres):

select id 
from client 
where platformID in (select id 
                     from platform 
                     where bios like '%INTEL%');

N'ayez pas peur des sous-requêtes, l'optimiseur de requêtes de Postgres est beaucoup plus intelligent que MySQL.

Si ce qui précède est trop lent, le réécrire dans une requête exists est parfois plus rapide:

select c.id 
from client c
where exists  (select 1
               from platform p
               where c.platformID = p.id
                 and bios like '%INTEL%');
1