0Pricing
SQL Academy · บทเรียน

พื้นฐานฟังก์ชัน PL/pgSQL

เขียนฟังก์ชัน PL/pgSQL ที่มีพารามิเตอร์ RETURNS TABLE การควบคุมลำดับการทำงาน (IF, LOOP, FOREACH) และการจัดการข้อยกเว้น

พื้นฐานฟังก์ชัน PL/pgSQL เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน

PL/pgSQL คืออะไร

ภาษาขั้นตอนการทำงานในตัวของ PostgreSQL เป็น SQL ที่เพิ่มตัวแปร การควบคุมลำดับการทำงาน ข้อยกเว้น และความสามารถในการเรียกใช้ query แบบไดนามิก ใช้สำหรับกระบวนงานที่จัดเก็บไว้และฟังก์ชันทริกเกอร์

โครงร่างฟังก์ชัน

ฟังก์ชันอย่างง่าย:

CREATE OR REPLACE FUNCTION add(a INT, b INT)
RETURNS INT AS $$
BEGIN
  RETURN a + b;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

SELECT add(2, 3);   -- 5

ตัวแปร

ประกาศด้วย DECLARE และกำหนดค่าด้วย := หรือ INTO:

CREATE FUNCTION user_orders(uid BIGINT)
RETURNS INT AS $$
DECLARE
  cnt INT;
BEGIN
  SELECT COUNT(*) INTO cnt FROM orders WHERE user_id = uid;
  RETURN cnt;
END;
$$ LANGUAGE plpgsql STABLE;

การควบคุมลำดับการทำงาน

IF / ELSE, FOR, WHILE, CASE:

IF cnt = 0 THEN
  RAISE NOTICE 'no orders';
ELSIF cnt < 10 THEN
  RAISE NOTICE 'few';
ELSE
  RAISE NOTICE 'many';
END IF;

FOR i IN 1..10 LOOP
  RAISE NOTICE '%', i;
END LOOP;

วนซ้ำผ่านผลลัพธ์ของ query

การวนซ้ำแบบเคอร์เซอร์:

CREATE FUNCTION recalc_totals() RETURNS VOID AS $$
DECLARE
  r RECORD;
BEGIN
  FOR r IN SELECT id FROM users LOOP
    UPDATE users SET
      order_count = (SELECT COUNT(*) FROM orders WHERE user_id = r.id)
    WHERE id = r.id;
  END LOOP;
END;
$$ LANGUAGE plpgsql;

RETURNS TABLE

คืนค่าชุดผลลัพธ์:

CREATE FUNCTION top_buyers(n INT)
RETURNS TABLE (user_id BIGINT, total NUMERIC) AS $$
BEGIN
  RETURN QUERY
    SELECT o.user_id, SUM(o.total)
    FROM orders o
    GROUP BY o.user_id
    ORDER BY SUM(o.total) DESC
    LIMIT n;
END;
$$ LANGUAGE plpgsql STABLE;

SELECT * FROM top_buyers(10);

พารามิเตอร์ IN / OUT / INOUT

ค่าที่คืนหลายค่า:

CREATE FUNCTION stats(uid BIGINT,
  OUT total NUMERIC,
  OUT cnt INT) AS $$
BEGIN
  SELECT SUM(total), COUNT(*) INTO total, cnt
  FROM orders WHERE user_id = uid;
END;
$$ LANGUAGE plpgsql STABLE;

SELECT * FROM stats(42);   -- total | cnt

การจัดการข้อยกเว้น

BEGIN ... EXCEPTION WHEN ... THEN:

BEGIN
  INSERT INTO users (email) VALUES ($1);
EXCEPTION
  WHEN unique_violation THEN
    RAISE NOTICE 'email already exists';
  WHEN OTHERS THEN
    RAISE;
END;

RAISE สำหรับการบันทึกข้อมูล

ระดับต่าง ๆ ได้แก่ DEBUG, LOG, INFO, NOTICE, WARNING, EXCEPTION:

RAISE NOTICE 'processed % rows', cnt;
RAISE EXCEPTION 'bad state: %', state USING ERRCODE = 'check_violation';

เครื่องหมายบอกความแปรผัน

ระบุคุณสมบัติของฟังก์ชันให้ถูกต้องสำหรับตัววางแผนคำสั่ง:

  • IMMUTABLE — อาร์กิวเมนต์เดียวกันให้ผลลัพธ์เดิมเสมอ (ไม่มีการรับส่งข้อมูล) ช่วยให้ฝังการเรียกใช้ได้และใช้กับดัชนีได้
  • STABLE — อาร์กิวเมนต์เดียวกันให้ผลลัพธ์เดิมภายใน query เดียวกัน
  • VOLATILE — ผลลัพธ์อาจแตกต่างกันในแต่ละครั้งที่เรียกใช้ (ค่าเริ่มต้น เหมาะสำหรับ NOW() และ RANDOM())

SECURITY DEFINER

ทำงานด้วยสิทธิ์ของเจ้าของฟังก์ชัน — โปรดใช้อย่างระมัดระวัง:

CREATE FUNCTION sensitive_op() RETURNS VOID
LANGUAGE plpgsql
SECURITY DEFINER
AS $$ ... $$;

-- Always set search_path explicitly to avoid hijacking:
ALTER FUNCTION sensitive_op() SET search_path = public, pg_temp;

สรุป

PL/pgSQL ขยายความสามารถของภาษาเอสคิวแอลด้วยลูป, IF, ข้อยกเว้น และการคืนค่าที่มีโครงสร้าง ควรใช้กับตรรกะหลายขั้นตอนที่เป็นเรื่องเดียวกันและได้ประโยชน์จากการทำงานใกล้กับข้อมูล

ตรวจสอบอย่างรวดเร็ว

ควรใช้เครื่องหมายระบุความผันผวนใดกับฟังก์ชันที่คืนผลลัพธ์เดียวกันเมื่อได้รับอาร์กิวเมนต์เดียวกัน โดยไม่มีผลข้างเคียงหรือการรับส่งข้อมูล?

คำถามที่พบบ่อย

บทเรียน “พื้นฐานฟังก์ชัน PL/pgSQL” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “พื้นฐานฟังก์ชัน PL/pgSQL” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “พื้นฐานฟังก์ชัน PL/pgSQL”

เขียนฟังก์ชัน PL/pgSQL ที่มีพารามิเตอร์ RETURNS TABLE การควบคุมลำดับการทำงาน (IF, LOOP, FOREACH) และการจัดการข้อยกเว้น คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “พื้นฐานฟังก์ชัน PL/pgSQL” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม

ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โครงสร้างทริกเกอร์: BEFORE/AFTER, FOR EACH ROW
  2. พื้นฐานฟังก์ชัน PL/pgSQL
  3. บล็อก DO และโค้ดนิรนาม
  4. การตรวจสอบตารางด้วยทริกเกอร์
← กลับไปที่ SQL Academy