Equivalente PostgreSQL delle variabili di query MySQL?


9

Esiste un modo semplice per adattare questi tipi di query MySQL a PostgreSQL:

  1. impostazione variabili in MySQL come

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

    Non sembra .

  2. Assegnare variabili dalle query SELECT e usare quelle variabili successivamente nel mio SQL come:

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

Sarei molto grato per i puntatori, specialmente su (2).


Potresti trovare le variabili PSQL che stai cercando. dba.stackexchange.com/a/213009/2639
Evan Carroll

Risposte:


13

Questo è facile da fare all'interno di una funzione PL / pgSQL (o di un blocco 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 $$;

Puoi anche usare le variabili GUC :

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

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

Oppure puoi usare un CTE con un join:

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

Se si utilizza il metodo GUC, come si imposta una variabile con un elenco numerato di numeri?
user952342

9

Uso le dichiarazioni WITH:

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

e:

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

3

Hai già risposto tu stesso: No, non esiste in SQL semplice. È possibile utilizzare PL / PgSQL se si desidera variabili, in una funzione o in un DOblocco.

La maggior parte degli usi per le variabili di query in MySQL sono soddisfatti da CTE ( WITHquery), funzioni di finestra, ecc. In PostgreSQL.


Bene, in realtà c'è, ma non sono adatti per l'uso generale all'interno delle query. Di solito accedi a GUC personalizzati con SETe SHOW, ma puoi invece usare:

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

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

I GUC sono costosi ed è una cattiva idea usarli per domande di carattere generale, ma a volte c'è un uso valido. Puoi anche usare solo impostazioni come myapp.variable.


2

Variabili PSQL

Almeno dalla versione 7.1 il client PostgreSQL ha fornito questa funzionalità con psqlvariabili

\set aintconst  -333
\set arealconst -9.999

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

Fondamentalmente quello che vuoi è la possibilità di eseguire script SQL. PSQL ha condizionali e variabili e la capacità di fornire un feedback SQL generato dinamicamente che semplifica questo lavoro. Questa non è una funzionalità lato server nel mondo PostgreSQL, e generalmente lo farei in un linguaggio client (come Node.js o Perl piuttosto che in psql).


bisogno di aggiornamenti. perché l'ultimo Postgresql consente:SET LOCAL variable value
Eugen Konkov,

1
Quelli sono per i parametri di configurazione - questa è una cosa completamente diversa @EugenKonkov
Evan Carroll

1

Per il secondo esempio non hai bisogno di una variabile (né in MySQL né in Postgres):

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

Non abbiate paura delle sottoquery, l'ottimizzatore delle query di Postgres è molto più intelligente di quello di MySQL.

Se quanto sopra è troppo lento, riscriverlo in una existsquery è talvolta più veloce:

select c.id 
from client c
where exists  (select 1
               from platform p
               where c.platformID = p.id
                 and bios like '%INTEL%');
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.