Lưu trữ kết quả truy vấn trong một biến sử dụng trong PL / pgSQL


130

Làm cách nào để gán kết quả của truy vấn cho một biến trong PL / pgSQL, ngôn ngữ thủ tục của PostgreQuery?

Tôi có một chức năng:

CREATE OR REPLACE FUNCTION test(x numeric)
RETURNS character varying AS
$BODY$
DECLARE
name   character varying(255);
begin
 name ='SELECT name FROM test_table where id='||x;

 if(name='test')then
  --do somthing
 else
  --do the else part
 end if;
end;
return -- return my process result here
$BODY$
LANGUAGE plpgsql VOLATILE

Trong hàm trên tôi cần lưu trữ kết quả của truy vấn này:

'SELECT name FROM test_table where id='||x;

đến biến name.

Làm thế nào để xử lý này?

Câu trả lời:


198

Tôi nghĩ bạn đang tìm kiếm SELECT INTO:

select test_table.name into name from test_table where id = x;

Điều đó sẽ lấy nametừ test_tableđâu idlà đối số của hàm của bạn và để nó trong namebiến. Đừng bỏ tiền tố tên bảng trên test_table.namehoặc bạn sẽ nhận được khiếu nại về một tham chiếu mơ hồ.


2
Nếu tôi cần nhiều biến. Giống như chọn test_table.name, test_table.id, test_table.ssn?
Đào Lâm

2
@DaoLam: Từ tài liệu tôi thích: "Kết quả của lệnh SQL mang lại một hàng đơn (có thể là nhiều cột) có thể được gán cho một biến bản ghi, biến loại hàng hoặc danh sách các biến vô hướng."
mu quá ngắn

@muistooshort vì vậy bạn đang nói tôi có thể làm tương tự và tôi có thể sử dụng name.id, name.ssn để truy xuất? Tôi đã thử nó với IF EXISTS nhưng không hoạt động: IF EXISTS (chọn * vào tên từ test_table ...))
Dao Lam

@DaoLam Tại sao bạn kết hợp INTO với IF EXISTS? Có lẽ bạn nên hỏi một câu hỏi mới để bạn có thể giải thích những gì bạn đang cố gắng làm.
mu quá ngắn

3
Không có ví dụ nào trong tài liệu (hoặc tôi đã bỏ lỡ nó), nhưng như @muistooshort đã lưu ý, bạn có thể chọn thành nhiều biến với một lựa chọn duy nhất:SELECT test_table.column1, test_table.column2 INTO variable1, variable2 FROM test_table WHERE id = x;
Grengas

78

Miễn là bạn đang gán một biến duy nhất, bạn cũng có thể sử dụng phép gán đơn giản trong hàm plpgsql:

name := (SELECT t.name from test_table t where t.id = x);

Hoặc sử dụng SELECT INTOnhư @mu đã được cung cấp .

Điều này cũng hoạt động:

name := t.name from test_table t where t.id = x;

Nhưng tốt hơn nên sử dụng một trong hai phương pháp đầu tiên, rõ ràng hơn, như @Pavel nhận xét.

Tôi rút ngắn cú pháp với một bí danh bảng bổ sung.
Cập nhật: Tôi đã xóa ví dụ mã của mình và đề nghị sử dụng IF EXISTS()thay vì như được cung cấp bởi @Pavel .


1
Đây không phải là ý tưởng hay - tính năng này không được ghi lại và nó xấu xí
Pavel Stehule

2
PL / pgSQL cho phép kết hợp SQL và PL - và đôi khi bạn có thể tạo ra những sinh vật thực sự kỳ lạ, nhưng kết hợp tốt hơn PL và SQL một cách sạch sẽ - trong các câu lệnh bị cô lập.
Pavel Stehule

@PavelStehule: Tôi đồng ý, hình thức của bạn là thích hợp hơn.
Erwin Brandstetter

Trên thực tế tôi thực hiện trước cú pháp của bạn, nhưng vấn đề là khi bạn xử lý lỗi, câu lệnh của bạn không gửi FOUND thành true ngược lại với câu lệnh select, checkout ( postgresql.org/docs/9.1/plpgsql-statements.html )
SENHAJI RHAZI Hamza

18

Mẫu thông thường là EXISTS(subselect):

BEGIN
  IF EXISTS(SELECT name
              FROM test_table t
             WHERE t.id = x
               AND t.name = 'test')
  THEN
     ---
  ELSE
     ---
  END IF;

Mẫu này được sử dụng trong PL / SQL, PL / pgSQL, SQL / PSM, ...


2

Tạo bảng học tập:

CREATE TABLE "public"."learning" (
    "api_id" int4 DEFAULT nextval('share_api_api_id_seq'::regclass) NOT NULL,
    "title" varchar(255) COLLATE "default"
);

Chèn bảng học dữ liệu:

INSERT INTO "public"."learning" VALUES ('1', 'Google AI-01');
INSERT INTO "public"."learning" VALUES ('2', 'Google AI-02');
INSERT INTO "public"."learning" VALUES ('3', 'Google AI-01');

Bước: 01

CREATE OR REPLACE FUNCTION get_all (pattern VARCHAR) RETURNS TABLE (
        learn_id INT,
        learn_title VARCHAR
) AS $$
BEGIN
    RETURN QUERY SELECT
        api_id,
        title
    FROM
        learning
    WHERE
        title = pattern ;
END ; $$ LANGUAGE 'plpgsql';

Bước: 02

SELECT * FROM get_all('Google AI-01');

Bước: 03

DROP FUNCTION get_all();

Bản giới thiệu: nhập mô tả hình ảnh ở đây


-2

Bạn có thể sử dụng ví dụ sau để lưu trữ kết quả truy vấn trong một biến bằng PL / pgSQL:

 select * into demo from maintenanceactivitytrack ; 
    raise notice'p_maintenanceid:%',demo;
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.