PostgreSQL tương đương với các biến truy vấn MySQL?


9

Có cách nào đơn giản để điều chỉnh các loại truy vấn MySQL này với PostgreSQL không:

  1. thiết lập các biến trong MySQL như

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

    Có vẻ như không .

  2. Chỉ định các biến từ các truy vấn CHỌN và sử dụng các biến đó sau đó trong SQL của tôi như:

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

Tôi rất biết ơn về con trỏ, đặc biệt là trên (2).


Bạn có thể tìm thấy các biến PSQL là những gì bạn đang tìm kiếm. dba.stackexchange.com/a/213009/2639
Evan Carroll

Câu trả lời:


13

Điều này rất dễ thực hiện bên trong hàm PL / pgSQL (hoặc khối 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 $$;

Bạn cũng có thể sử dụng các biến GUC :

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

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

Hoặc bạn có thể sử dụng CTE với sự tham gia:

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

Nếu bạn sử dụng phương pháp GUC, làm thế nào để bạn thiết lập một biến với một danh sách liệt kê các số?
dùng952342

9

Tôi sử dụng câu lệnh VỚI:

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

và:

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

3

Bạn đã tự trả lời điều này: Không, không có SQL đơn giản. Bạn có thể sử dụng PL / PGQuery nếu bạn muốn các biến, trong một hàm hoặc một DOkhối.

Hầu hết việc sử dụng các biến truy vấn trong MySQL được thỏa mãn bởi CTEs ( WITHtruy vấn), các hàm cửa sổ, v.v. trong PostgreQuery.


Chà, thực tế là có, nhưng chúng không phù hợp để sử dụng chung trong các truy vấn. Bạn thường truy cập GUC tùy chỉnh với SETSHOW, nhưng thay vào đó bạn có thể sử dụng:

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 đắt tiền và đó là một ý tưởng tồi để sử dụng điều này cho các truy vấn mục đích chung, nhưng đôi khi có một cách sử dụng hợp lệ. Bạn chỉ có thể sử dụng các cài đặt như myapp.variable, quá.


2

Biến PSQL

Vì ít nhất phiên bản 7.1 Máy khách của PostgreQuery đã cung cấp chức năng này với psqlcác biến

\set aintconst  -333
\set arealconst -9.999

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

Về cơ bản những gì bạn muốn là khả năng kịch bản SQL. PSQL có các điều kiện và biến và khả năng cung cấp lại SQL được tạo động giúp công việc này dễ dàng hơn. Đây không phải là chức năng phía máy chủ trong thế giới PostgreQuery và nói chung tôi sẽ làm điều này bằng ngôn ngữ máy khách (như Node.js hoặc Perl chứ không phải trong psql).


cần cập nhật. bởi vì Postgresql mới nhất cho phép:SET LOCAL variable value
Eugen Konkov

1
Đó là những thông số cấu hình - đó là một điều hoàn toàn khác @EugenKonkov
Evan Carroll

1

Đối với ví dụ thứ hai, bạn không cần một biến (không phải trong MySQL cũng như Postgres):

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

Đừng sợ các truy vấn phụ, trình tối ưu hóa truy vấn của Postgres thông minh hơn nhiều so với MySQL.

Nếu cách trên quá chậm, việc viết lại thành existstruy vấn đôi khi nhanh hơn:

select c.id 
from client c
where exists  (select 1
               from platform p
               where c.platformID = p.id
                 and bios like '%INTEL%');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.