MySQL เก็บขั้นตอนการทำงานกับฟังก์ชั่นที่ฉันจะใช้เมื่อไหร่?


160

ฉันกำลังดู MySQL และขั้นตอนการทำงานที่เก็บไว้ ความแตกต่างที่แท้จริงคืออะไร?

ดูเหมือนว่าจะคล้ายกัน แต่ฟังก์ชันมีข้อ จำกัด มากกว่า

ฉันอาจจะผิด แต่ดูเหมือนว่าขั้นตอนการจัดเก็บสามารถทำทุกอย่างและฟังก์ชั่นที่เก็บไว้สามารถทำได้มากขึ้น ทำไม / เมื่อไรที่ฉันจะใช้โพรซีเดอร์กับฟังก์ชัน?

คำตอบ:


101

คุณไม่สามารถผสมในกระบวนงานที่เก็บไว้กับ SQL ธรรมดาในขณะที่มีฟังก์ชันที่เก็บไว้คุณสามารถทำได้

เช่นSELECT get_foo(myColumn) FROM mytableไม่ถูกต้องหากget_foo()เป็นขั้นตอน แต่คุณสามารถทำได้หากget_foo()เป็นฟังก์ชัน ราคาคือฟังก์ชั่นมีข้อ จำกัด มากกว่าขั้นตอน


18
ฟังก์ชั่นมีข้อ จำกัด อะไรบ้าง?
Fantius

11
อ่าฉันพบข้อมูลที่ดีบางอย่างที่นี่: dev.mysql.com/doc/refman/5.0/en/…
Fantius

262

ความแตกต่างทั่วไปที่สุดระหว่างขั้นตอนและฟังก์ชั่นคือมันถูกเรียกแตกต่างกันและเพื่อวัตถุประสงค์ที่แตกต่างกัน:

  1. กระบวนการไม่ส่งคืนค่า แต่จะถูกเรียกใช้พร้อมกับคำสั่ง CALL เพื่อดำเนินการเช่นปรับเปลี่ยนตารางหรือประมวลผลระเบียนที่ดึงมา
  2. ฟังก์ชั่นจะถูกเรียกใช้ภายในการแสดงออกและส่งกลับค่าเดียวโดยตรงไปยังผู้โทรที่จะใช้ในการแสดงออก
  3. คุณไม่สามารถเรียกใช้ฟังก์ชันที่มีคำสั่ง CALL และไม่สามารถเรียกใช้โพรซีเดอร์ในนิพจน์ได้

ไวยากรณ์สำหรับการสร้างงานประจำแตกต่างกันบ้างสำหรับโพรซีเดอร์และฟังก์ชัน

  1. พารามิเตอร์ขั้นตอนสามารถกำหนดเป็นอินพุตเท่านั้น, เอาต์พุตเท่านั้นหรือทั้งสองอย่าง ซึ่งหมายความว่ากระบวนการสามารถส่งผ่านค่ากลับไปยังผู้โทรโดยใช้พารามิเตอร์เอาต์พุต ค่าเหล่านี้สามารถเข้าถึงได้ในข้อความที่ตามหลังคำสั่ง CALL ฟังก์ชั่นมีเพียงอินพุตพารามิเตอร์ ดังนั้นแม้ว่าทั้งสองโพรซีเดอร์และฟังก์ชั่นสามารถมีพารามิเตอร์ได้ แต่การประกาศพารามิเตอร์โพรซีเดอร์นั้นแตกต่างจากฟังก์ชั่นนั้น ๆ
  2. ฟังก์ชั่นคืนค่าดังนั้นจะต้องมีข้อ RETURNS ในการกำหนดฟังก์ชั่นเพื่อระบุประเภทข้อมูลของค่าตอบแทน นอกจากนี้ต้องมีคำสั่ง RETURN อย่างน้อยหนึ่งคำภายในเนื้อหาของฟังก์ชันเพื่อส่งคืนค่าไปยังผู้เรียก RETURNS และ RETURN ไม่ปรากฏในคำจำกัดความของขั้นตอน

    • CALL statementจะก่อให้เกิดการจัดเก็บใช้ ในการเรียกใช้ฟังก์ชันที่เก็บไว้ให้อ้างอิงในนิพจน์ ฟังก์ชันส่งคืนค่าระหว่างการประเมินค่านิพจน์

    • โพรซีเดอร์ถูกเรียกใช้โดยใช้คำสั่ง CALL และสามารถส่งกลับค่าโดยใช้ตัวแปรเอาต์พุตเท่านั้น ฟังก์ชั่นสามารถเรียกใช้จากภายในคำสั่งเช่นเดียวกับฟังก์ชั่นอื่น ๆ (นั่นคือโดยการเรียกชื่อฟังก์ชั่น) และสามารถส่งกลับค่าสเกลา

    • การระบุพารามิเตอร์เป็น IN, OUT หรือ INOUT จะใช้ได้สำหรับ PROCEDURE เท่านั้น สำหรับฟังก์ชั่นพารามิเตอร์จะถูกพิจารณาว่าเป็นพารามิเตอร์ IN เสมอ

    หากไม่มีการระบุคำสำคัญก่อนชื่อพารามิเตอร์จะเป็นพารามิเตอร์ IN ตามค่าเริ่มต้น พารามิเตอร์สำหรับฟังก์ชั่นที่เก็บไว้จะไม่นำหน้าด้วย IN, OUT หรือ INOUT พารามิเตอร์ฟังก์ชั่นทั้งหมดจะถือว่าเป็นพารามิเตอร์ IN

ในการกำหนดโพรซีเดอร์หรือฟังก์ชันที่เก็บไว้ให้ใช้ CREATE PROCEDURE หรือ CREATE FUNCTION ตามลำดับ:

CREATE PROCEDURE proc_name ([parameters])
 [characteristics]
 routine_body


CREATE FUNCTION func_name ([parameters])
 RETURNS data_type       // diffrent
 [characteristics]
 routine_body

ส่วนขยาย MySQL สำหรับโพรซีเดอร์ที่เก็บไว้ (ไม่ใช่ฟังก์ชั่น) คือโพรซีเดอร์สามารถสร้างชุดผลลัพธ์หรือแม้แต่ชุดผลลัพธ์หลายชุดซึ่งผู้เรียกดำเนินการในลักษณะเดียวกับผลลัพธ์ของคำสั่ง SELECT อย่างไรก็ตามเนื้อหาของชุดผลลัพธ์ดังกล่าวไม่สามารถใช้โดยตรงในการแสดงออก

รูทีนที่เก็บ (หมายถึงทั้งโพรซีเดอร์ที่เก็บไว้และฟังก์ชั่นที่เก็บไว้) นั้นเชื่อมโยงกับฐานข้อมูลเฉพาะเช่นตารางหรือมุมมอง เมื่อคุณปล่อยฐานข้อมูลรูทีนที่เก็บไว้ใด ๆ ในฐานข้อมูลจะถูกลบเช่นกัน

กระบวนงานและฟังก์ชันที่เก็บไว้ไม่ใช้เนมสเปซเดียวกัน เป็นไปได้ที่จะมีโพรซีเดอร์และฟังก์ชันที่มีชื่อเดียวกันในฐานข้อมูล

ในโพรซีเดอร์ Stored dynamic SQL สามารถใช้ได้ แต่ไม่สามารถใช้ในฟังก์ชั่นหรือทริกเกอร์

คำสั่ง SQL ที่เตรียมไว้ (PREPARE, EXECUTE, DEALLOCATE PREPARE) สามารถใช้ในโพรซีเดอร์ที่เก็บไว้ แต่ไม่สามารถใช้ฟังก์ชันหรือทริกเกอร์ที่เก็บไว้ได้ ดังนั้นฟังก์ชั่นและทริกเกอร์ที่เก็บไว้จะไม่สามารถใช้ Dynamic SQL (ซึ่งคุณสร้างคำสั่งเป็นสตริงแล้วจึงเรียกใช้งาน) (Dynamic SQL ใน MySQL จัดเก็บรูทีน)

ความแตกต่างที่น่าสนใจยิ่งขึ้นระหว่างฟังก์ชั่นและขั้นตอนการเก็บรักษา:

  1. ( จุดนี้จะคัดลอกมาจาก blogpost . ) การจัดเก็บเป็น precompiled แผนการดำเนินการในขณะที่ฟังก์ชั่นไม่ได้ ฟังก์ชันแยกวิเคราะห์และคอมไพล์เมื่อรันไทม์ ขั้นตอนการจัดเก็บเก็บไว้เป็นรหัสเทียมในฐานข้อมูลเช่นรูปแบบที่รวบรวม

  2. ( ฉันไม่แน่ใจในจุดนี้ )
    ขั้นตอนการจัดเก็บมีความปลอดภัยและลดทราฟฟิกเครือข่ายและเรายังสามารถเรียกขั้นตอนการจัดเก็บได้ไม่ว่าในกรณีใด ของแอปพลิเคชันในแต่ละครั้ง การอ้างอิง

  3. โดยปกติฟังก์ชั่นจะใช้สำหรับการคำนวณโดยที่ปกติจะใช้โพรซีเดอร์ในการดำเนินการทางตรรกะทางธุรกิจ

  4. ฟังก์ชั่นไม่สามารถส่งผลกระทบต่อสถานะของฐานข้อมูล (งบที่ไม่ชัดเจนหรือโดยปริยายกระทำหรือย้อนกลับไม่ได้รับอนุญาตในการทำงาน) โดยวิธีการจัดเก็บสามารถส่งผลกระทบต่อสถานะของฐานข้อมูลโดยใช้กระทำ ฯลฯ
    refrence: J.1 ข้อ จำกัด ในการปฏิบัติและทริกเกอร์ที่เก็บไว้

  5. ฟังก์ชั่นไม่สามารถใช้คำสั่งล้างในขณะที่ขั้นตอนการจัดเก็บสามารถทำได้

  6. ฟังก์ชั่นที่จัดเก็บไม่สามารถเรียกซ้ำได้โดยที่กระบวนงานที่เก็บไว้สามารถ หมายเหตุ: กระบวนงานที่เก็บไว้แบบเรียกซ้ำจะถูกปิดใช้งานโดยค่าเริ่มต้น แต่สามารถเปิดใช้งานบนเซิร์ฟเวอร์โดยการตั้งค่าตัวแปรระบบเซิร์ฟเวอร์ max_sp_recursion_depth ให้เป็นค่าที่ไม่ใช่ศูนย์ ดูหัวข้อ 5.2.3“ ตัวแปรระบบ”สำหรับข้อมูลเพิ่มเติม

  7. ภายในฟังก์ชั่นหรือทริกเกอร์ที่เก็บไว้จะไม่ได้รับอนุญาตให้แก้ไขตารางที่มีการใช้งานแล้ว (สำหรับการอ่านหรือการเขียน) โดยคำสั่งที่เรียกใช้ฟังก์ชันหรือทริกเกอร์ ตัวอย่างที่ดี: วิธีอัปเดตตารางเดียวกันกับการลบใน MYSQL อย่างไร

หมายเหตุ : แม้ว่าข้อ จำกัด บางอย่างจะใช้กับฟังก์ชันและทริกเกอร์ที่เก็บไว้ แต่ไม่ใช่กับกระบวนงานที่เก็บไว้ข้อ จำกัด เหล่านั้นจะใช้กับโพรซีเดอร์ที่เก็บหากถูกเรียกใช้จากภายในฟังก์ชันหรือทริกเกอร์ที่เก็บไว้ ตัวอย่างเช่นแม้ว่าคุณสามารถใช้ล้างข้อมูลในกระบวนงานที่เก็บไว้ได้กระบวนงานที่เก็บไว้ไม่สามารถเรียกได้จากฟังก์ชันหรือทริกเกอร์ที่เก็บไว้


2
@GrijeshChauhan คุณหมายถึงอะไรเมื่อคุณพูดว่า"ฟังก์ชั่นการแยกวิเคราะห์และรวบรวมที่รันไทม์" ?
Pacerier

@Pacerier หมายถึงฟังก์ชั่นใน MySQL เป็นเหมือนสคริปต์ที่รวบรวมและดำเนินการได้ทันที ฉันคัดลอกมาจากการโพสต์บล็อกแต่ไม่ได้ใช้งานได้จริงเพื่อตรวจสอบพฤติกรรมนี้
Grijesh Chauhan

ในโพรซีเดอร์คุณสามารถส่งตัวแปรออกเป็นพารามิเตอร์แล้วเรียกมันด้วยคำสั่ง select
LTroya

1
สัญลักษณ์หัวข้อ # 4 ในส่วนล่างของคำตอบนี้คือฉันคิดว่าหลักของความแตกต่างระหว่างขั้นตอนและฟังก์ชั่น ขั้นตอนสามารถเปลี่ยนฐานข้อมูลฟังก์ชั่นไม่สามารถ ความแตกต่างอื่น ๆ ทั้งหมดเป็นเพียงเพื่อให้บริการที่มีประสิทธิภาพมากขึ้น
Woodrow Barlow

51

ข้อแตกต่างที่สำคัญอย่างหนึ่งคือคุณสามารถรวมฟังก์ชันในแบบสอบถาม SQL ของคุณ แต่สามารถเรียกใช้กระบวนงานที่เก็บไว้ได้ด้วยCALLคำสั่ง:

ตัวอย่าง UDF:

CREATE FUNCTION hello (s CHAR(20))
   RETURNS CHAR(50) DETERMINISTIC
   RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)

CREATE TABLE names (id int, name varchar(20));
INSERT INTO names VALUES (1, 'Bob');
INSERT INTO names VALUES (2, 'John');
INSERT INTO names VALUES (3, 'Paul');

SELECT hello(name) FROM names;
+--------------+
| hello(name)  |
+--------------+
| Hello, Bob!  |
| Hello, John! |
| Hello, Paul! |
+--------------+
3 rows in set (0.00 sec)

ตัวอย่าง Sproc:

delimiter //

CREATE PROCEDURE simpleproc (IN s CHAR(100))
BEGIN
   SELECT CONCAT('Hello, ', s, '!');
END//
Query OK, 0 rows affected (0.00 sec)

delimiter ;

CALL simpleproc('World');
+---------------------------+
| CONCAT('Hello, ', s, '!') |
+---------------------------+
| Hello, World!             |
+---------------------------+
1 row in set (0.00 sec)

1
ฟังก์ชั่นของคุณมีสองคืน ? ฉันหมายความว่าสายนี้คืออะไร? RETURNS CHAR(50) DETERMINISTIC?
Martin AJ

RETURNS CHAR(50)รัฐประเภทของข้อมูลที่จะถูกส่งกลับ RETURN CONCAT(...เป็นข้อมูลที่ถูกส่งกลับ ทั้งคู่มีความจำเป็น DETERMINISTICเป็นสิ่งจำเป็นเพื่อรัฐว่าข้อมูลพื้นฐานที่จะไม่ได้รับการแก้ไข
lemming622

8

ฟังก์ชั่นที่เก็บไว้สามารถใช้ภายในแบบสอบถาม จากนั้นคุณสามารถนำไปใช้กับทุกแถวหรือภายในส่วนคำสั่ง WHERE

ขั้นตอนดำเนินการโดยใช้แบบสอบถามโทร


0

กระบวนงานที่เก็บไว้สามารถเรียกซ้ำ แต่ฟังก์ชันที่เก็บไว้ไม่สามารถ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.