เก็บผลลัพธ์การสืบค้นในตัวแปรโดยใช้ใน PL / pgSQL


130

วิธีกำหนดผลลัพธ์ของแบบสอบถามให้กับตัวแปรใน PL / pgSQL ซึ่งเป็นภาษาขั้นตอนของ PostgreSQL

ฉันมีฟังก์ชั่น:

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

ในฟังก์ชันข้างต้นฉันต้องการเก็บผลลัพธ์ของแบบสอบถามนี้:

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

nameให้กับตัวแปร

จะดำเนินการอย่างไร?

คำตอบ:


199

ฉันคิดว่าคุณกำลังมองหาSELECT INTO:

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

นั่นจะดึงอาร์กิวเมนต์ของฟังก์ชันของคุณnameมาจากtest_tableที่idใดและปล่อยไว้ในnameตัวแปร อย่าปล่อยคำนำหน้าชื่อตารางไว้มิtest_table.nameฉะนั้นคุณจะได้รับการร้องเรียนเกี่ยวกับการอ้างอิงที่ไม่ชัดเจน


2
จะเกิดอะไรขึ้นถ้าฉันต้องการตัวแปรหลายตัว เช่นเลือก test_table.name, test_table.id, test_table.ssn?
ดาวลำ

2
@DaoLam: จากเอกสารที่ฉันชอบถึง: "ผลลัพธ์ของคำสั่ง SQL ที่ให้แถวเดียว (อาจเป็นหลายคอลัมน์) สามารถกำหนดให้กับตัวแปรเร็กคอร์ดตัวแปรประเภทแถวหรือรายการตัวแปรสเกลาร์"
สั้นเกินไป

@muistooshort ดังนั้นคุณกำลังบอกว่าฉันทำแบบเดียวกันได้และฉันสามารถใช้ name.id, name.ssn เพื่อดึงข้อมูล? ฉันลองใช้ IF EXISTS แต่ไม่ได้ผล: IF EXISTS (เลือก * เป็นชื่อจาก test_table ... ))
Dao Lam

@ DaoLam ทำไมคุณถึงรวม INTO กับ IF EXISTS? บางทีคุณควรถามคำถามใหม่เพื่อที่คุณจะได้อธิบายสิ่งที่คุณกำลังพยายามทำ
สั้นเกินไป

3
ไม่มีตัวอย่างในเอกสาร (หรือฉันพลาดไป) แต่ตามที่ @muistooshort ระบุไว้คุณสามารถเลือกเป็นตัวแปรหลายตัวโดยเลือกเพียงครั้งเดียว:SELECT test_table.column1, test_table.column2 INTO variable1, variable2 FROM test_table WHERE id = x;
Grengas

78

ตราบเท่าที่คุณกำหนดตัวแปรเดียวคุณยังสามารถใช้การกำหนดธรรมดาในฟังก์ชัน plpgsql:

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

หรือใช้SELECT INTOเหมือนที่@mu จัดให้แล้ว .

ใช้งานได้เช่นกัน:

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

แต่ควรใช้หนึ่งในสองวิธีแรกที่ชัดเจนกว่าดังที่ @Pavel แสดงความคิดเห็น

ฉันย่อรูปแบบด้วยนามแฝงตารางเพิ่มเติม
ปรับปรุง: ฉันออกตัวอย่างเช่นรหัสของฉันและแนะนำให้ใช้IF EXISTS()แทนเช่นการให้บริการโดย @Pavel


1
นี่ไม่ใช่ความคิดที่ดี - คุณลักษณะนี้ไม่มีการบันทึกไว้และมันน่าเกลียด
Pavel Stehule

2
PL / pgSQL อนุญาตให้ใช้ SQL และ PL ผสมกัน - และบางครั้งคุณสามารถสร้างสิ่งมีชีวิตที่แปลกจริงๆได้ แต่ควรผสม PL และ SQL อย่างหมดจดในงบแยก
Pavel Stehule

@PavelStehule: ฉันเห็นด้วยแบบฟอร์มของคุณดีกว่า
Erwin Brandstetter

อันที่จริงฉันต้องการไวยากรณ์ของคุณ แต่ปัญหาคือเมื่อคุณจัดการกับข้อผิดพลาดคำสั่งของคุณจะไม่ส่ง FOUND เป็นจริงตรงข้ามกับคำสั่ง select into, checkout ( postgresql.org/docs/9.1/plpgsql-statements.html )
SENHAJI RHAZI Hamza

18

รูปแบบปกติคือEXISTS(subselect):

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

รูปแบบนี้ใช้ใน PL / SQL, PL / pgSQL, SQL / PSM, ...


2

สร้างตารางการเรียนรู้:

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

แทรกตารางการเรียนรู้ข้อมูล:

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');

ขั้นตอน: 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';

ขั้นตอน: 02

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

ขั้นตอน: 03

DROP FUNCTION get_all();

การสาธิต: ใส่คำอธิบายภาพที่นี่


-2

คุณสามารถใช้ตัวอย่างต่อไปนี้เพื่อจัดเก็บผลลัพธ์คิวรีในตัวแปรโดยใช้ PL / pgSQL:

 select * into demo from maintenanceactivitytrack ; 
    raise notice'p_maintenanceid:%',demo;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.