PostgreSQL equivalente às variáveis ​​de consulta do MySQL?

9

Existe uma maneira simples de adaptar esses tipos de consultas MySQL ao PostgreSQL:

  1. definindo variáveis ​​no MySQL como

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

    Parece que não .

  2. Atribuindo variáveis ​​de consultas SELECT e usando essas variáveis ​​posteriormente no meu SQL, como:

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

Eu ficaria muito grato por dicas, especialmente em (2).

Daniel
fonte
Você pode achar que as variáveis ​​PSQL são o que você está procurando. dba.stackexchange.com/a/213009/2639
Evan Carroll

Respostas:

13

Isso é fácil de fazer dentro de uma função PL / pgSQL (ou um bloco 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 $$;

Você também pode usar variáveis GUC :

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

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

Ou você pode usar um CTE com uma associação:

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
fonte
Se você usa o método GUC, como configura uma variável com uma lista enumerada de números?
user952342
9

Eu uso as instruções 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)
user2641043
fonte
3

Você já respondeu a si mesmo: Não, não existe SQL simples. Você pode usar o PL / PgSQL se desejar variáveis, em uma função ou em um DObloco.

A maioria dos usos para variáveis ​​de consulta no MySQL são satisfeitos por CTEs ( WITHconsultas), funções de janela, etc. no PostgreSQL.


Bem, na verdade existe, mas eles não são adequados para uso geral em consultas. Você geralmente acessa GUCs personalizados com SETe SHOW, mas pode 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)

Os GUCs são caros e é uma má idéia usá-lo para consultas de uso geral, mas ocasionalmente há um uso válido. Você também pode usar configurações como myapp.variabletambém.

Craig Ringer
fonte
2

Variáveis ​​PSQL

Como pelo menos a versão 7.1, o cliente do PostgreSQL forneceu essa funcionalidade com psqlvariáveis

\set aintconst  -333
\set arealconst -9.999

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

Essencialmente, o que você deseja é a capacidade de criar scripts para SQL. O PSQL possui condicionais e variáveis ​​e a capacidade de alimentar SQL gerado dinamicamente, o que facilita esse trabalho. Isso não é uma funcionalidade do lado do servidor no mundo do PostgreSQL, e geralmente eu faria isso em uma linguagem de cliente (como Node.js ou Perl, e não em psql).

Evan Carroll
fonte
precisa de atualizações. porque o Postgresql mais recente permite:SET LOCAL variable value
Eugen Konkov
11
Essas são para parâmetros de configuração - isso é uma coisa totalmente diferente @EugenKonkov
Evan Carroll
1

Para o segundo exemplo, você não precisa de uma variável (nem no MySQL nem no Postgres):

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

Não tenha medo de subconsultas, o otimizador de consultas do Postgres é muito mais inteligente que o MySQL.

Se o acima for muito lento, reescrevê-lo em uma existsconsulta às vezes é mais rápido:

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