¿PostgreSQL equivalente a las variables de consulta de MySQL?

9

¿Existe una manera directa de adaptar estos tipos de consultas MySQL a PostgreSQL:

  1. establecer variables en MySQL como

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

    Parece que no .

  2. Asignando variables de consultas SELECT y usando esas variables posteriormente en mi SQL como:

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

Estaría muy agradecido por los consejos, especialmente en (2).

Daniel
fuente
Puede encontrar que las variables PSQL son lo que está buscando. dba.stackexchange.com/a/213009/2639
Evan Carroll

Respuestas:

13

Esto es fácil de hacer dentro de una función PL / pgSQL (o un bloque 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 $$;

También puede usar variables GUC :

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

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

O puede usar un CTE con una combinación:

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
Neil McGuigan
fuente
Si usa el método GUC, ¿cómo configura una variable con una lista enumerada de números?
user952342
9

Yo uso CON declaraciones:

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

y:

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

Usted ya respondió esto usted mismo: No, no existe en SQL simple. Puede usar PL / PgSQL si desea variables, en una función o un DObloque.

La mayoría de los usos de las variables de consulta en MySQL son satisfechos por CTE ( WITHconsultas), funciones de ventana, etc. en PostgreSQL.


Bueno, en realidad lo hay, pero no son adecuados para uso general dentro de las consultas. Por lo general, accede a GUC personalizados con SETy SHOW, pero en su lugar puede usar:

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

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

Los GUC son caros y es una mala idea usar esto para consultas de propósito general, pero ocasionalmente hay un uso válido. Solo puedes usar configuraciones como myapp.variable, también.

Craig Ringer
fuente
2

Variables PSQL

Desde al menos la versión 7.1, el cliente de PostgreSQL ha proporcionado esta funcionalidad con psqlvariables

\set aintconst  -333
\set arealconst -9.999

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

Esencialmente, lo que desea es la capacidad de script SQL. PSQL tiene condicionales y variables, y la capacidad de retroalimentar SQL generado dinámicamente, lo que facilita este trabajo. Esta no es la funcionalidad del lado del servidor en el mundo de PostgreSQL, y generalmente lo haría en un lenguaje de cliente (como Node.js o Perl en lugar de hacerlo en psql).

Evan Carroll
fuente
Necesito actualizaciones. porque el último Postgresql permite:SET LOCAL variable value
Eugen Konkov
1
Esos son para parámetros de configuración, eso es algo completamente diferente @EugenKonkov
Evan Carroll
1

Para el segundo ejemplo, no necesita una variable (ni en MySQL ni en Postgres):

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

No tenga miedo de las subconsultas, el optimizador de consultas de Postgres es mucho más inteligente que MySQL.

Si lo anterior es demasiado lento, reescribirlo en una existsconsulta a veces es más rápido:

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