ข้อ จำกัด ของตัวดำเนินการ in () คือรากของความชั่วทั้งหมด
มันใช้งานได้กับกรณีเล็ก ๆ น้อย ๆ และคุณสามารถขยายได้ด้วย "การสร้างคำสั่งที่เตรียมไว้โดยอัตโนมัติ" แต่ก็มีข้อ จำกัด อยู่เสมอ
- หากคุณกำลังสร้างคำสั่งที่มีพารามิเตอร์จำนวนตัวแปรที่จะทำให้ค่าใช้จ่ายในการแยกวิเคราะห์ sql ในแต่ละสาย
- บนแพลตฟอร์มจำนวนมากจำนวนพารามิเตอร์ของตัวดำเนินการ in () มี จำกัด
- บนแพลตฟอร์มทั้งหมดขนาดตัวอักษร SQL โดยรวมจะถูก จำกัด ทำให้ไม่สามารถส่งตัวยึด 2000 รายการสำหรับพารามิเตอร์ภายใน
- การส่งตัวแปรการเชื่อมโยงที่มีขนาด 1,000-10k เป็นไปไม่ได้เนื่องจากไดรเวอร์ JDBC มีข้อ จำกัด
วิธี In () อาจดีพอสำหรับบางกรณี แต่ไม่สามารถพิสูจน์ได้ด้วยจรวด :)
วิธีการแก้ปัญหาจรวดคือการส่งผ่านจำนวนพารามิเตอร์โดยพลการในการโทรแยกต่างหาก (โดยผ่านการอุดตันของ params เช่น) แล้วมีมุมมอง (หรือวิธีอื่นใด) เพื่อเป็นตัวแทนของพวกเขาใน SQL และใช้ในที่ของคุณ เกณฑ์
ตัวแปรแปรผันกำลังมาที่นี่http://tkyte.blogspot.hu/2006/06/varying-in-lists.html
อย่างไรก็ตามถ้าคุณสามารถใช้ PL / SQL, ระเบียบนี้สามารถสวยเรียบร้อย
function getCustomers(in_customerIdList clob) return sys_refcursor is
begin
aux_in_list.parse(in_customerIdList);
open res for
select *
from customer c,
in_list v
where c.customer_id=v.token;
return res;
end;
จากนั้นคุณสามารถส่งหมายเลขรหัสลูกค้าที่คั่นด้วยเครื่องหมายจุลภาคโดยพลการในพารามิเตอร์และ:
- จะไม่ล่าช้าในการแยกวิเคราะห์เนื่องจาก SQL สำหรับการเลือกมีความเสถียร
- ไม่มีความซับซ้อนของฟังก์ชั่น pipelined - มันเป็นเพียงแค่แบบสอบถามเดียว
- SQL กำลังใช้การรวมอย่างง่ายแทนที่จะเป็นตัวดำเนินการ IN ซึ่งค่อนข้างเร็ว
- ท้ายที่สุดมันเป็นกฎง่ายๆที่ไม่ต้องกดปุ่มฐานข้อมูลด้วยการเลือกแบบธรรมดาหรือ DML เนื่องจากเป็น Oracle ซึ่งให้แสงมากกว่า MySQL หรือฐานข้อมูลอย่างง่าย PL / SQL ช่วยให้คุณสามารถซ่อนรูปแบบการจัดเก็บจากรูปแบบโดเมนแอปพลิเคชันของคุณในวิธีที่มีประสิทธิภาพ
เคล็ดลับที่นี่คือ:
- เราต้องการการโทรที่รับสายยาวและเก็บที่ใดก็ได้ที่เซสชัน db สามารถเข้าถึงได้ (เช่นตัวแปรแพ็กเกจแบบง่ายหรือ dbms_session.set_context)
- จากนั้นเราต้องการมุมมองที่สามารถแยกวิเคราะห์สิ่งนี้เป็นแถว
- และจากนั้นคุณมีมุมมองที่มีรหัสที่คุณกำลังสอบถามดังนั้นสิ่งที่คุณต้องมีคือการเข้าร่วมตารางอย่างง่าย ๆ
มุมมองดูเหมือนว่า:
create or replace view in_list
as
select
trim( substr (txt,
instr (txt, ',', 1, level ) + 1,
instr (txt, ',', 1, level+1)
- instr (txt, ',', 1, level) -1 ) ) as token
from (select ','||aux_in_list.getpayload||',' txt from dual)
connect by level <= length(aux_in_list.getpayload)-length(replace(aux_in_list.getpayload,',',''))+1
โดยที่ aux_in_list.getpayload อ้างถึงสตริงอินพุตดั้งเดิม
แนวทางที่เป็นไปได้คือการส่งผ่านอาร์เรย์ pl / sql (รองรับโดย Oracle เท่านั้น) แต่คุณไม่สามารถใช้ใน SQL จริงได้ดังนั้นจึงจำเป็นต้องมีขั้นตอนการแปลงเสมอ การแปลงไม่สามารถทำได้ใน SQL ดังนั้นหลังจากทั้งหมดผ่าน clob กับพารามิเตอร์ทั้งหมดในสตริงและแปลงด้วยปัญญาในมุมมองเป็นทางออกที่มีประสิทธิภาพมากที่สุด