ฉันกำลังทำงานกับฟังก์ชั่นที่อนุญาตให้ฉันเพิ่มดัชนีหากไม่มีอยู่ ฉันพบปัญหาที่ฉันไม่สามารถรับรายการดัชนีเพื่อเปรียบเทียบได้ ความคิดใด ๆ
นี่เป็นปัญหาที่คล้ายคลึงกับการสร้างคอลัมน์ที่แก้ไขด้วยรหัสนี้:
https://stackoverflow.com/a/12603892/368511
ฉันกำลังทำงานกับฟังก์ชั่นที่อนุญาตให้ฉันเพิ่มดัชนีหากไม่มีอยู่ ฉันพบปัญหาที่ฉันไม่สามารถรับรายการดัชนีเพื่อเปรียบเทียบได้ ความคิดใด ๆ
นี่เป็นปัญหาที่คล้ายคลึงกับการสร้างคอลัมน์ที่แก้ไขด้วยรหัสนี้:
https://stackoverflow.com/a/12603892/368511
คำตอบ:
หากคุณไม่สนใจเกี่ยวกับชื่อของดัชนีให้ Postgres ตั้งชื่อโดยอัตโนมัติ:
CREATE INDEX ON tbl1 (col1);
คือ (เกือบ) เหมือนกับ:
CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);
ยกเว้น Postgres จะหลีกเลี่ยงการชนกันของชื่อและเลือกชื่อฟรีถัดไปโดยอัตโนมัติ:
tbl1_col1_idx
tbl1_col1_idx2
tbl1_col1_idx3
...
แค่ลองดู. แต่แน่นอนคุณไม่ต้องการสร้างดัชนีซ้ำซ้อนหลายรายการ ดังนั้นจึงไม่ใช่ความคิดที่ดีที่จะสร้างใหม่เพียงแค่สุ่มสี่สุ่มห้า
วิธีที่ง่ายมากในการทดสอบคือการใช้ชื่อสคีมาเพื่อregclass
:
SELECT 'myschema.myname'::regclass;
ถ้ามันมีข้อยกเว้นชื่อเป็นอิสระ
หรือเพื่อทดสอบเดียวกันโดยไม่ทิ้งข้อยกเว้นใช้ในDO
คำสั่ง:
DO
$$
BEGIN
IF NOT EXISTS (
SELECT
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = 'mytable_mycolumn_idx'
AND n.nspname = 'myschema'
) THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
สิ่งนี้ใช้ไม่ได้CREATE INDEX CONCURRENTLY
เนื่องจากไม่สามารถห่อหุ้มตัวแปรในธุรกรรมภายนอกได้ ดูความคิดเห็นโดย @Gregoryด้านล่าง
DO
คำสั่งที่ถูกนำมาใช้กับ Postgres 9.0 ในรุ่นก่อนหน้าคุณต้องสร้างฟังก์ชั่นให้ทำเช่นเดียวกัน
รายละเอียดเกี่ยวกับในคู่มือpg_class
พื้นฐานเกี่ยวกับการจัดทำดัชนีในคู่มือ
คุณสามารถใช้ฟังก์ชั่นใหม่to_regclass()
เพื่อตรวจสอบได้โดยไม่ต้องทำการยกเว้น:
DO
$$
BEGIN
IF to_regclass('myschema.mytable_mycolumn_idx') IS NULL THEN
CREATE INDEX mytable_mycolumn_idx ON myschema.mytable (mycolumn);
END IF;
END
$$;
ส่งคืนค่า NULL ถ้าไม่มีดัชนี (หรือวัตถุอื่น) ของชื่อนั้น ดู:
วางจำหน่ายแล้ว:
CREATE INDEX IF NOT EXISTS ...
ที่ยังใช้งานCREATE INDEX CONCURRENTLY IF NOT EXISTS
ได้
อย่างไรก็ตามคู่มือเตือน :
โปรดทราบว่าไม่มีการรับประกันว่าดัชนีที่มีอยู่นั้นเป็นอะไรที่เหมือนกับดัชนีที่จะถูกสร้างขึ้น
มันเป็นการตรวจสอบธรรมดาสำหรับชื่อวัตถุ ใช้กับตัวแปรทั้งหมดได้ที่นี่
CONCURRENTLY
ด้วยวิธีนี้ ERROR: CREATE INDEX CONCURRENTLY cannot be executed from a function or multi-command string
คุณจะได้รับ
มันจะมีอยู่ใน 9.5 นี่คือคอมไพล์จริงยอมรับhttps://github.com/postgres/postgres/commit/08309aaf74ee879699165ec8a2d53e56f2d2e947
การอภิปรายเกี่ยวกับแฮกเกอร์ pg http://postgresql.nabble.com/CREATE-IF-NOT-EXISTS-INDEX-td5821173.html