PostgreSQL эквивалент переменных запроса MySQL?


9

Существует ли простой способ адаптации этих типов запросов MySQL к PostgreSQL:

  1. установка переменных в MySQL как

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

    Кажется нет .

  2. Назначение переменных из запросов SELECT и последующее использование этих переменных в моем SQL, например:

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

Я был бы очень благодарен за указатели, особенно на (2).


Вы можете найти переменные PSQL - это то, что вы ищете. dba.stackexchange.com/a/213009/2639
Эван Кэрролл,

Ответы:


13

Это легко сделать внутри функции PL / pgSQL (или блока 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 $$;

Вы также можете использовать переменные GUC :

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

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

Или вы можете использовать CTE с объединением:

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

Если вы используете метод GUC, как вы настраиваете переменную с нумерованным списком чисел?
user952342

9

Я использую операторы WITH:

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

а также:

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

3

Вы уже ответили на это сами: нет, нет простого SQL. Вы можете использовать PL / PgSQL, если вам нужны переменные, в функции или DOблоке.

Большинство применений для переменных запросов в MySQL удовлетворяются CTE ( WITHзапросами), оконными функциями и т. Д. В PostgreSQL.


Ну, на самом деле, есть, но они не подходят для общего использования в запросах. Обычно вы получаете доступ к пользовательским GUC с помощью SETи SHOW, но вместо этого можете использовать:

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

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

GUC стоят дорого, и это плохая идея, чтобы использовать это для запросов общего назначения, но очень редко есть правильное применение. Вы можете использовать только такие настройки, как myapp.variableтоже.


2

Переменные PSQL

Начиная с версии 7.1, клиент PostgreSQL предоставил эту функцию с psqlпеременными

\set aintconst  -333
\set arealconst -9.999

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

По сути, вам нужна возможность написания сценариев SQL. PSQL имеет условные выражения и переменные, а также возможность передавать динамически сгенерированный SQL, что облегчает эту работу. Это не функциональность на стороне сервера в мире PostgreSQL, и обычно я делаю это на языке клиента (например, Node.js или Perl, а не на языке psql).


нужны обновления. потому что последние Postgresql позволяют:SET LOCAL variable value
Евгений Коньков

1
Это для параметров конфигурации - это совсем другое дело @EugenKonkov
Эван Кэрролл

1

Для второго примера вам не нужна переменная (ни в MySQL, ни в Postgres):

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

Не бойтесь подзапросов, оптимизатор запросов Postgres намного умнее, чем MySQL.

Если вышеупомянутое слишком медленно, переписать его в existsзапрос иногда быстрее:

select c.id 
from client c
where exists  (select 1
               from platform p
               where c.platformID = p.id
                 and bios like '%INTEL%');
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.