ฟังก์ชันกับกระบวนงานที่เก็บไว้ใน SQL Server


830

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

บางคนบอกฉันได้ไหมว่าเพราะอะไร





3
ความเร็วเป็นอย่างไร อันไหนเรียกใช้เคียวรีเดียวกันเร็วขึ้น
AmiNadimi

คำตอบ:


709

ฟังก์ชั่นเป็นค่าที่คำนวณได้และไม่สามารถทำการเปลี่ยนแปลงด้านสิ่งแวดล้อมอย่างถาวรได้SQL Server(เช่นไม่อนุญาตINSERTหรือใช้UPDATEคำสั่ง)

ฟังก์ชั่นสามารถใช้แบบอินไลน์ในSQLงบถ้ามันส่งกลับค่าสเกลาร์หรือสามารถเข้าร่วมหากมันส่งกลับชุดผลลัพธ์

ประเด็นที่ควรสังเกตจากความคิดเห็นซึ่งสรุปคำตอบ ขอบคุณ @Sean K Anderson:

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

วิธีการเรียก SQLฟังก์ชั่นจากขั้นตอนการจัดเก็บและเมื่อเราใช้ฟังก์ชั่นแทนขั้นตอนการจัดเก็บ

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

https://programmingtechtutorial.blogspot.com/2020/01/when-use-storeprocedure-and-when-use.html


13
โดยพื้นฐานแล้วไม่อนุญาตให้ใช้ DML?
david blaine

173
ฟังก์ชั่นเป็นไปตามคำจำกัดความคอมพิวเตอร์ในการที่พวกเขาจะต้องส่งกลับค่าและไม่สามารถแก้ไขข้อมูลที่พวกเขาได้รับเป็นพารามิเตอร์ (อาร์กิวเมนต์) ฟังก์ชั่นไม่ได้รับอนุญาตให้เปลี่ยนแปลงอะไรต้องมีอย่างน้อยหนึ่งพารามิเตอร์และพวกเขาจะต้องส่งกลับค่า Procs ที่เก็บไว้ไม่จำเป็นต้องมีพารามิเตอร์สามารถเปลี่ยนวัตถุฐานข้อมูลและไม่ต้องส่งคืนค่า
Sean Anderson

23
ในความเป็นจริงคุณสามารถมีคำสั่ง INSERT, UPDATE และ DELETE ในฟังก์ชั่นสำหรับการปรับเปลี่ยนตัวแปรตารางท้องถิ่น
Ani

14
@Ani - คุณสามารถสร้างอินสแตนซ์และปรับเปลี่ยนตัวแปรท้องถิ่นจำนวนเท่าใดก็ได้ด้วยในฟังก์ชั่น แต่คุณไม่สามารถแก้ไขอะไรนอกขอบเขตของฟังก์ชั่น
MyItchyChin

40
ฟังก์ชัน @SeanKAnderson "ต้องมีอย่างน้อยหนึ่งพารามิเตอร์" ไม่เป็นความจริง
เหลียง

623

ความแตกต่างระหว่าง SP และ UDF แสดงไว้ด้านล่าง:

+---------------------------------+----------------------------------------+
| Stored Procedure (SP)           | Function (UDF - User Defined           |
|                                 | Function)                              |
+---------------------------------+----------------------------------------+
| SP can return zero , single or  | Function must return a single value    |
| multiple values.                | (which may be a scalar or a table).    |
+---------------------------------+----------------------------------------+
| We can use transaction in SP.   | We can't use transaction in UDF.       |
+---------------------------------+----------------------------------------+
| SP can have input/output        | Only input parameter.                  |
| parameter.                      |                                        |
+---------------------------------+----------------------------------------+
| We can call function from SP.   | We can't call SP from function.        |
+---------------------------------+----------------------------------------+
| We can't use SP in SELECT/      | We can use UDF in SELECT/ WHERE/       |
| WHERE/ HAVING statement.        | HAVING statement.                      |
+---------------------------------+----------------------------------------+
| We can use exception handling   | We can't use Try-Catch block in UDF.   |
| using Try-Catch block in SP.    |                                        |
+---------------------------------+----------------------------------------+

21
ฟังก์ชั่นจะต้องคืนค่าหนึ่งค่าหรือเป็นชุด
Rafareino

8
เรื่องนี้เกิดขึ้นในอีก 3 ปีต่อมา แต่ควรอยู่ด้านบนเพราะมันอ่านได้และครอบคลุม
DanteTheSmith

SP อาจใช้ทั้งตารางชั่วคราวและตัวแปรตารางในขณะที่ UDF อาจใช้ตัวแปรตารางเท่านั้น ตัวแปรตารางอาจไม่ใช้ดัชนี UDF สามารถถูกเรียกใช้ใน CROSS ใช้ไม่เหมือนกับ SP
Ludovic Aubert

190

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

ฟังก์ชั่นตามปกติจะมีเอาต์พุตและอินพุตเป็นทางเลือก เอาท์พุทนั้นจะสามารถใช้เป็นข้อมูลในการฟังก์ชั่นอื่น ๆ (ของ SQL Server ในตัวเช่น DATEDIFF เลน ฯลฯ ) หรือเป็นคำกริยากับคำถาม SQL - การเช่นหรือSELECT a, b, dbo.MyFunction(c) FROM tableSELECT a, b, c FROM table WHERE a = dbo.MyFunc(c)

Procs ที่จัดเก็บจะใช้ในการผูกเคียวรี SQL เข้าด้วยกันในธุรกรรมและส่วนต่อประสานกับโลกภายนอก กรอบงานเช่น ADO.NET ฯลฯ ไม่สามารถเรียกใช้ฟังก์ชันได้โดยตรง แต่สามารถเรียก proc ที่จัดเก็บได้โดยตรง

ฟังก์ชั่นมีอันตรายซ่อนอยู่แม้ว่า: พวกเขาสามารถใช้ในทางที่ผิดและทำให้เกิดปัญหาประสิทธิภาพการทำงานที่น่ารังเกียจ: พิจารณาคำถามนี้:

SELECT * FROM dbo.MyTable WHERE col1 = dbo.MyFunction(col2)

ตำแหน่งที่ MyFunction ถูกประกาศเป็น:

CREATE FUNCTION MyFunction (@someValue INTEGER) RETURNS INTEGER
AS
BEGIN
   DECLARE @retval INTEGER

   SELECT localValue 
      FROM dbo.localToNationalMapTable
      WHERE nationalValue = @someValue

   RETURN @retval
END

สิ่งที่เกิดขึ้นที่นี่คือฟังก์ชัน MyFunction นั้นถูกเรียกใช้สำหรับทุกแถวในตาราง MyTable หาก MyTable มี 1,000 แถวแสดงว่าเป็นอีก 1,000 แบบสอบถามแบบเฉพาะกิจเมื่อเทียบกับฐานข้อมูล หากฟังก์ชันถูกเรียกใช้เมื่อระบุในข้อมูลจำเพาะของคอลัมน์ฟังก์ชันจะถูกเรียกใช้สำหรับแต่ละแถวที่ส่งคืนโดย SELECT

ดังนั้นคุณต้องระวังฟังก์ชั่นการเขียน ถ้าคุณเลือกจากตารางในฟังก์ชั่นคุณต้องถามตัวเองว่าสามารถทำได้ดีกว่าด้วย JOIN ใน parent ที่จัดเก็บ proc หรือสร้าง SQL อื่น ๆ (เช่น CASE ... เมื่อ ... ELSE ... END)


2
คุณช่วยอธิบายรายละเอียดเกี่ยวกับ "Frameworks เช่น ADO.NET และอื่น ๆ ไม่สามารถเรียกฟังก์ชันได้โดยตรง" ฉันใช้งานฟังก์ชั่นกับผู้ให้บริการข้อมูล ADO.NET ที่ไม่มีปัญหา
Ian Kemp

24
คุณต้องเรียกฟังก์ชันผ่านคำสั่ง SELECT บางคำสั่ง - ฟังก์ชันไม่สามารถเรียกได้ว่าเป็นชิ้นส่วนอิสระของรหัสในสิทธิของตนเอง - มันจะต้องถูกเรียกว่าเป็นส่วนหนึ่งของคำสั่ง SQL ที่มีขนาดใหญ่แม้ว่าคำสั่ง SQL นั้นจะไม่มีอะไรเพิ่มเติม SELECT * from dbo.MyTableValuedFunction()กว่า sprocs บน otherhand สามารถเรียกโดยตรงกับ ADO.NET โดยการตั้งค่าไปSqlCommand.CommandType CommandType.StoredProcedure
Chris J

60

ความแตกต่างระหว่างขั้นตอนการจัดเก็บและฟังก์ชั่นที่ผู้ใช้กำหนด:

  • กระบวนงานที่เก็บไว้ไม่สามารถใช้ในคำสั่ง Select
  • ขั้นตอนการจัดเก็บสนับสนุนการแก้ปัญหาชื่อที่เลื่อนออกไป
  • ขั้นตอนการจัดเก็บโดยทั่วไปจะใช้สำหรับการดำเนินการตรรกะทางธุรกิจ
  • ขั้นตอนการจัดเก็บสามารถส่งกลับประเภทข้อมูลใด ๆ
  • กระบวนงานที่เก็บไว้สามารถยอมรับพารามิเตอร์อินพุตจำนวนมากกว่าฟังก์ชันที่ผู้ใช้กำหนด กระบวนงานที่เก็บไว้สามารถมีพารามิเตอร์อินพุตได้มากถึง 21,000 พารามิเตอร์
  • ขั้นตอนการจัดเก็บสามารถเรียกใช้ Dynamic SQL
  • ขั้นตอนการจัดเก็บรองรับการจัดการข้อผิดพลาด
  • ฟังก์ชันที่ไม่สามารถกำหนดค่าได้สามารถใช้ในขั้นตอนการจัดเก็บได้

  • ฟังก์ชันที่ผู้ใช้กำหนดสามารถใช้ในคำสั่ง Select
  • ฟังก์ชั่นที่ผู้ใช้กำหนดไม่สนับสนุนการแก้ไขชื่อที่เลื่อนออกไป
  • ฟังก์ชั่นที่ผู้ใช้กำหนดมักใช้สำหรับการคำนวณ
  • ฟังก์ชั่นที่ผู้ใช้กำหนดควรคืนค่า
  • ฟังก์ชั่นที่ผู้ใช้กำหนดไม่สามารถส่งคืนรูปภาพได้
  • ฟังก์ชันที่ผู้ใช้กำหนดเองยอมรับพารามิเตอร์อินพุตจำนวนน้อยกว่าขั้นตอนการจัดเก็บ UDF สามารถมีพารามิเตอร์อินพุตได้สูงสุด 1,023 รายการ
  • ตารางชั่วคราวไม่สามารถใช้ในฟังก์ชั่นที่ผู้ใช้กำหนด
  • ฟังก์ชั่นที่ผู้ใช้กำหนดไม่สามารถเรียกใช้ Dynamic SQL ได้
  • ฟังก์ชั่นที่ผู้ใช้กำหนดไม่รองรับการจัดการข้อผิดพลาด RAISEERRORหรือ@@ERRORไม่ได้รับอนุญาตใน UDF
  • ไม่สามารถใช้ฟังก์ชันที่ไม่ได้กำหนดไว้ใน UDF ตัวอย่างเช่นGETDATE()ไม่สามารถใช้ใน UDF ได้

1
หากต้องการอ้างอิง @curiousBoy ด้านล่างอีกครั้ง อีกคำตอบที่ไม่ได้เครดิต (โดย @Ankit) (<- ดูว่าฉันทำอย่างนั้นได้อย่างไร?)): "คุณควรให้การอ้างอิงแหล่งที่มาซึ่งมาจาก ( blogs.msdn.microsoft.com/pradeepsvs/2014/10 / 08 / … ). โปรดเคารพงานที่คนอื่นทำ!”
Tom

7
บล็อกนี้เขียนขึ้นตั้งแต่วันที่ 8 ตุลาคม 2014 และคำตอบนี้เขียนตั้งแต่ 2 พฤษภาคม 2556 @Tom
Kumar Manish

1
@ Code Rider: อ่าขอโทษด้วย! ไม่อยากจะเชื่อว่าฉันไม่ได้สังเกตว่า! ดังนั้นบล็อกคัดลอกคุณ (หรือคนอื่นที่ไม่ได้) โดยไม่ต้องเครดิต?
ทอม

GETDATE()สามารถใช้ในฟังก์ชั่น สาระสำคัญของNon-deterministicไม่ใช่สิ่งที่ดี
PerformanceDBA

56

เขียนฟังก์ชั่นที่ผู้ใช้กำหนดเมื่อคุณต้องการคำนวณและคืนค่าเพื่อใช้ในคำสั่ง SQL อื่น ๆ เขียนกระบวนงานที่เก็บไว้เมื่อคุณต้องการแทนคือการจัดกลุ่มชุดคำสั่ง SQL ที่อาจซับซ้อน นี่เป็นสองกรณีใช้ที่แตกต่างกันมาก!


18
มีฟังก์ชั่นที่ผู้ใช้กำหนดแตกต่างกัน ค่าสเกลาร์ส่งคืนค่าเท่านั้น ชุดผลการสืบค้นซ้ำชนิดอื่น ๆ
AK

44
              STORE PROCEDURE                 FUNCTION (USER DEFINED FUNCTION)    
 * Procedure can return 0, single or   | * Function can return only single value   
   multiple values.                    |
                                       |
 * Procedure can have input, output    | * Function  can have only input 
   parameters.                         |   parameters.         
                                       |
 * Procedure cannot be called from     | * Functions can be called from 
   function.                           |   procedure.
                                       |
 * Procedure allows select as well as  | * Function allows only select statement 
   DML statement in it.                |   in it.
                                       |
 * Exception can be handled by         | * Try-catch block cannot be used in a 
   try-catch block in a procedure.     |   function.
                                       |
 * We can go for transaction management| * We can't go for transaction 
   in procedure.                       |   management in function.
                                       |
 * Procedure cannot be utilized in a   | * Function can be embedded in a select 
   select statement                    |   statement.
                                       |
 * Procedure can affect the state      | * Function can not affect the state 
   of database means it can perform    |   of database means it can not    
   CRUD operation on database.         |   perform CRUD operation on 
                                       |   database. 
                                       |
 * Procedure can use temporary tables. | * Function can not use 
                                       |   temporary tables. 
                                       |
 * Procedure can alter the server      | * Function can not alter the  
   environment parameters.             |   environment parameters.
                                       |   
 * Procedure can use when we want      | * Function can use when we want
   instead is to group a possibly-     |   to compute and return a value
   complex set of SQL statements.      |   for use in other SQL 
                                       |   statements.

1
UDF สามารถถูกเรียกใช้ใน CROSS ใช้ไม่เหมือน SP
Ludovic Aubert

24

ความแตกต่างพื้นฐาน

ฟังก์ชันต้องส่งคืนค่า แต่ใน Stored Procedure จะเป็นตัวเลือก (กระบวนงานสามารถคืนค่าเป็นศูนย์หรือค่า n)

ฟังก์ชั่นสามารถมีเพียงพารามิเตอร์อินพุตในขณะที่ขั้นตอนสามารถมีพารามิเตอร์อินพุต / เอาต์พุต

ฟังก์ชั่นรับพารามิเตอร์อินพุตหนึ่งรายการซึ่งเป็นข้อบังคับ แต่กระบวนงานที่เก็บไว้อาจใช้พารามิเตอร์อินพุต n ถึง n ..

สามารถเรียกใช้ฟังก์ชันได้จากกระบวนงานในขณะที่กระบวนการไม่สามารถเรียกใช้จากฟังก์ชันได้

ความแตกต่างล่วงหน้า

โพรซีเดอร์อนุญาตให้ SELECT รวมถึงคำสั่ง DML (INSERT / UPDATE / DELETE) ในขณะที่ Function อนุญาตเฉพาะคำสั่ง SELECT ในนั้น

ไม่สามารถใช้โพรซีเดอร์ในคำสั่ง SELECT ได้ในขณะที่ฟังก์ชันสามารถฝังในคำสั่ง SELECT

กระบวนงานที่เก็บไว้ไม่สามารถใช้ในคำสั่ง SQL ที่ใดก็ได้ในส่วน WHERE / HAVING / SELECT ในขณะที่ Function สามารถ

ฟังก์ชั่นที่ส่งคืนตารางสามารถถือเป็น rowset อื่นได้ สามารถใช้ร่วมกับตารางอื่น ๆ

ฟังก์ชั่นอินไลน์อาจเป็นมุมมองที่รับพารามิเตอร์และสามารถใช้ในการเข้าร่วมและการดำเนินการ Rowset อื่น ๆ

ข้อยกเว้นสามารถจัดการได้โดย try-catch block ในกระบวนงานในขณะที่ try-catch block ไม่สามารถใช้ใน Function ได้

เราสามารถไปทำธุรกรรมการจัดการในขั้นตอนในขณะที่เราไม่สามารถไปทำงานได้

แหล่ง


25
คุณควรให้การอ้างอิงแหล่งที่มา นี้เป็นจากdotnet-tricks.com/Tutorial/sqlserver/... โปรดเคารพงานที่คนอื่นทำ!
อยากรู้อยากเห็นบอย

16
ไม่มีเหตุผลที่จะไม่ให้การอ้างอิงแหล่งที่มา คุณสามารถพูดถึงในตอนท้ายของมัน!
อยากรู้อยากเห็นบอย

2
เรื่อง "ฟังก์ชั่นจะต้องคืนค่า แต่ใน Stored Procedure มันเป็นทางเลือก .... ": ฉันจะชี้แจงว่า: "ฟังก์ชั่นจะต้องส่งคืนค่าหนึ่งค่าเดียวเท่านั้น (ซึ่งจะต้องทำผ่านReturnsคำหลักและต้องเป็นประเภทสเกลาร์หรือตาราง) แต่กระบวนงานที่เก็บไว้สามารถเลือกที่จะส่งคืน: a) Intรหัสผลลัพธ์1 ประเภทผ่านทางReturnคำชี้แจงและ / หรือ b) 1+ พารามิเตอร์ (รวมถึงCursorประเภท) ผ่านทางOutputคำหลักและ / หรือ c) ชุดแถว 1+ ผ่านชุดSelectคำสั่งหากชุดแถว 1 ชุดเท่านั้น ถูกส่งคืนสามารถใช้เป็นอาร์กิวเมนต์ "execute_statement" ของคำสั่ง "แทรกลงใน"
Tom

20

User Defined Function เป็นเครื่องมือสำคัญสำหรับโปรแกรมเมอร์เซิร์ฟเวอร์ sql คุณสามารถใช้มันแบบอินไลน์ในคำสั่ง SQL เช่นนั้น

SELECT a, lookupValue(b), c FROM customers 

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

  • ไม่สามารถสร้างการเปลี่ยนแปลงถาวร
  • ไม่สามารถเปลี่ยนข้อมูล

ขั้นตอนการจัดเก็บสามารถทำสิ่งเหล่านั้น

สำหรับฉันการใช้งานแบบอินไลน์ของ UDF เป็นการใช้งานที่สำคัญที่สุดของ UDF


14

วิธีการจัดเก็บ จะถูกใช้เป็นสคริปต์ พวกเขาใช้ชุดคำสั่งสำหรับคุณและคุณสามารถกำหนดเวลาให้เรียกใช้ในบางช่วงเวลา มักจะรันคำสั่ง DML หลายรายการเช่น INSERT, UPDATE, DELETE และอื่น ๆ หรือแม้แต่ SELECT

ฟังก์ชั่น จะใช้เป็นวิธีการ คุณผ่านบางสิ่งและส่งคืนผลลัพธ์ ควรมีขนาดเล็กและรวดเร็ว - ทำทันที มักใช้ในคำสั่ง SELECT


2
นี่เป็นบทสรุปที่ดีของทั้งสองวิธีคิดอย่างรวดเร็วและสกปรก
Eric Bishard

2
สรุปแน่นอนดี คำตอบอื่น ๆ มุ่งเน้นไปที่ความแตกต่างทางทฤษฎีของทั้งสองในขณะที่ยังคงทิ้งฉันไม่แน่ใจว่าเมื่อใดจะใช้อันไหนในทางปฏิบัติ
jf328

8

ขั้นตอนการเก็บ:

  • เป็นเหมือนโปรแกรมจิ๋วใน SQL Server
  • สามารถทำได้ง่ายเหมือนคำสั่ง select หรือซับซ้อนเหมือนสคริปต์แบบยาวที่เพิ่มลบอัปเดตและ / หรืออ่านข้อมูลจากหลายตารางในฐานข้อมูล
  • (สามารถใช้ลูปและเคอร์เซอร์ซึ่งทั้งสองอย่างช่วยให้คุณสามารถทำงานกับผลลัพธ์ที่มีขนาดเล็กลงหรือการดำเนินการตามแถวในข้อมูล)
  • ควรจะเรียกใช้EXECหรือEXECUTEคำสั่ง
  • ส่งคืนตัวแปรตาราง แต่เราไม่สามารถใช้OUTพารามิเตอร์ได้
  • รองรับการทำธุรกรรม

ฟังก์ชั่น:

  • ไม่สามารถใช้เพื่ออัปเดตลบหรือเพิ่มระเบียนในฐานข้อมูล
  • เพียงแค่ส่งกลับค่าเดียวหรือค่าตาราง
  • สามารถใช้เพื่อเลือกบันทึกเท่านั้น อย่างไรก็ตามสามารถเรียกได้ง่ายจากภายใน SQL มาตรฐานเช่น:

    SELECT dbo.functionname('Parameter1')

    หรือ

    SELECT Name, dbo.Functionname('Parameter1') FROM sysObjects
  • สำหรับการดำเนินการเลือกที่ใช้ซ้ำได้ง่ายฟังก์ชั่นสามารถทำให้รหัสง่ายขึ้น เพียงระวังการใช้JOINคำสั่งในฟังก์ชั่นของคุณ หากฟังก์ชันของคุณมีส่วนJOINคำสั่งและคุณเรียกใช้จากคำสั่ง select อื่นที่ส่งคืนผลลัพธ์หลายรายการการเรียกใช้ฟังก์ชันJOIN นั้นจะรวมตารางเหล่านั้นสำหรับแต่ละบรรทัดที่ส่งคืนในชุดผลลัพธ์ ดังนั้นแม้ว่าจะมีประโยชน์ในการทำให้ตรรกะบางอย่างง่ายขึ้น แต่ก็อาจเป็นปัญหาคอขวดของการใช้งานหากไม่ได้ใช้อย่างถูกต้อง

  • ส่งคืนค่าโดยใช้OUTพารามิเตอร์
  • ไม่รองรับการทำธุรกรรม

8

ฟังก์ชั่นที่ผู้ใช้กำหนด

  1. ฟังก์ชันต้องส่งคืนค่า
  2. จะอนุญาตเฉพาะคำสั่ง Select เท่านั้นจะไม่อนุญาตให้เราใช้คำสั่ง DML
  3. จะอนุญาตเฉพาะพารามิเตอร์อินพุตเท่านั้นไม่รองรับพารามิเตอร์เอาต์พุต
  4. มันจะไม่อนุญาตให้เราใช้บล็อกแบบลองจับ
  5. ไม่อนุญาตให้ทำธุรกรรมภายในฟังก์ชั่น
  6. เราสามารถใช้ตัวแปรตารางเท่านั้นมันจะไม่อนุญาตให้ใช้ตารางชั่วคราว
  7. กระบวนงานที่เก็บไว้ไม่สามารถเรียกได้จากฟังก์ชัน
  8. ฟังก์ชั่นสามารถเรียกใช้จากคำสั่งเลือก
  9. UDF สามารถใช้ในการเข้าร่วมอนุประโยคเป็นชุดผลลัพธ์

ขั้นตอนการเก็บ

  1. กระบวนงานที่เก็บไว้อาจหรือไม่ส่งคืนค่า
  2. สามารถมีคำสั่งที่เลือกรวมถึงคำสั่ง DML เช่นแทรกอัปเดตลบและอื่น ๆ
  3. มันสามารถมีทั้งพารามิเตอร์อินพุตและเอาต์พุต
  4. สำหรับการจัดการข้อยกเว้นเราสามารถใช้ลอง catch catch
  5. สามารถใช้ธุรกรรมภายในกระบวนงานที่เก็บไว้
  6. สามารถใช้ตัวแปรตารางทั้งสองเช่นเดียวกับตารางชั่วคราวในมัน
  7. ขั้นตอนการจัดเก็บสามารถเรียกใช้ฟังก์ชั่น
  8. ขั้นตอนไม่สามารถเรียกได้จากเลือก / ที่ไหน / มีและอื่น ๆ ในงบ คำสั่ง Execute / Exec สามารถใช้เรียก / ดำเนินการ Stored Procedure
  9. ไม่สามารถใช้ขั้นตอนในข้อเข้าร่วมได้

6

เพื่อตัดสินใจว่าเมื่อใดควรใช้ประเด็นต่อไปนี้ที่อาจช่วยได้ -

  1. กระบวนงานที่เก็บไว้ไม่สามารถส่งกลับตัวแปรตารางซึ่งฟังก์ชันสามารถทำเช่นนั้นได้

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

ไชโย


6

ฟังก์ชั่น SQL Server เช่นเคอร์เซอร์มีไว้เพื่อใช้เป็นอาวุธสุดท้ายของคุณ! พวกเขามีปัญหาเรื่องประสิทธิภาพดังนั้นการใช้ฟังก์ชั่นที่มีค่าเป็นตารางจึงควรหลีกเลี่ยงให้มากที่สุด การพูดคุยเกี่ยวกับประสิทธิภาพกำลังพูดถึงตารางที่มีมากกว่า 1,000,000 เรคคอร์ดที่โฮสต์บนเซิร์ฟเวอร์บนฮาร์ดแวร์ระดับกลาง ไม่เช่นนั้นคุณไม่ต้องกังวลเกี่ยวกับประสิทธิภาพที่เกิดจากฟังก์ชั่น

  1. อย่าใช้ฟังก์ชั่นเพื่อส่งคืนชุดผลลัพธ์เป็นรหัสภายนอก (เช่น ADO.Net)
  2. ใช้การรวมการดู / การจัดเก็บ procs ให้มากที่สุด คุณสามารถกู้คืนจากปัญหาประสิทธิภาพการเติบโตในอนาคตโดยใช้คำแนะนำ DTA (ที่ปรึกษาการปรับฐานข้อมูล) จะให้ (เช่นมุมมองที่จัดทำดัชนีและสถิติ) - บางครั้ง!

สำหรับการอ้างอิงเพิ่มเติมดู: http://database.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html


1
ขอบคุณ เขียนฟังก์ชันวันนี้เพื่อโทรภายในเคียวรีเพื่อเติมค่าสำหรับหนึ่งคอลัมน์ รันการทำงานนานกว่า 3 นาทีก่อนที่ฉันจะหยุดมัน คิดหาวิธีเข้าร่วมเพื่อทำมัน ดำเนินการเสร็จใน 15 วินาที (ชุดข้อมูลคือ 3456 แถว) ประสิทธิภาพที่แตกต่าง
VISQL

แก้ไข: ดำเนินการเสร็จสิ้นระหว่าง 15 และ 50 วินาทีขึ้นอยู่กับคอลัมน์ที่ฉัน "สั่งซื้อโดย" (ชุดข้อมูลเป็น 3456 แถว) ความแตกต่างของประสิทธิภาพที่ยิ่งใหญ่
VISQL

ความแตกต่างด้านประสิทธิภาพอาจมีรูตในคอลัมน์ประเภทต่าง ๆ ที่คุณสั่งซื้อผลลัพธ์ SQL Server ทำงานได้ดีกับตัวเลขมากกว่าข้อมูลตัวละคร คุณสามารถใช้ DTA กับแบบสอบถาม 50secs นั้นและดูว่าสามารถเกิดขึ้นกับคำแนะนำสถิติ / ดัชนีบางประเภทเพื่อให้แบบสอบถามทำงานเร็วขึ้นหรือไม่
Achilles

1
ฉันไม่แน่ใจว่ามีหลักฐานเพียงพอที่จะบอกว่าควรเป็นทางเลือกสุดท้าย คุณสามารถนึกถึงฟังก์ชั่นเป็นมุมมองแบบกำหนดพารามิเตอร์ซึ่งสามารถดำเนินการเพิ่มเติมได้ เช่นคุณต้องการเข้าร่วมลูกค้าเพื่อสั่งซื้อ แต่เฉพาะมิชิแกน คุณสร้างฟังก์ชั่น customerOrders (@StateCode) ซึ่งจะเข้าร่วมมูลค่าของลูกค้าเพียงรัฐเดียว จากนั้นฉันสามารถทำงานเพิ่มเติมในชุดนี้เป็นเลือกชื่อ, นามสกุล, OrderTotal, StoreName จากลูกค้า OrderOrders ('MI') เข้าร่วมร้านค้าในร้านค้า Store = คำสั่งซื้อเก็บที่ไหนสั่งซื้อทั้งหมด> 100; นี่จะเป็นความเจ็บปวดของ SP เนื่องจากคุณต้องคัดลอกชั่วคราว
MPavlak

คุณมีกี่ระเบียนในตารางนั้น หากฮาร์ดแวร์ของคุณจัดการอย่างถูกต้องคุณไม่จำเป็นต้องกังวลเกี่ยวกับการเลือกอาวุธ ช้อนสามารถทำงานได้เมื่อมันยากพอที่จะทำลายดาบ ความแข็งนี้เรียกว่าฮาร์ดแวร์!
จุดอ่อน

3

เริ่มต้นด้วยฟังก์ชั่นที่คืนค่าเดียว สิ่งที่ดีคือคุณสามารถใส่รหัสที่ใช้บ่อยในฟังก์ชั่นและส่งกลับเป็นคอลัมน์ในชุดผลลัพธ์

จากนั้นคุณอาจใช้ฟังก์ชันสำหรับรายการพารามิเตอร์ของเมือง dbo.GetCitiesIn ("NY") ที่ส่งคืนตารางที่สามารถใช้เป็นการเข้าร่วม

มันเป็นวิธีการจัดระเบียบรหัส การรู้ว่าเมื่อไรที่บางสิ่งสามารถนำมาใช้ซ้ำได้และเมื่อเสียเวลาเป็นสิ่งที่ได้มาจากการลองผิดลองถูกและประสบการณ์

นอกจากนี้ฟังก์ชั่นเป็นความคิดที่ดีใน SQL Server มันเร็วกว่าและมีพลังมาก เลือกแบบอินไลน์และโดยตรง ระวังอย่าให้มากเกินไป


3

นี่คือเหตุผลในทางปฏิบัติที่ต้องการฟังก์ชั่นมากกว่ากระบวนการ หากคุณมีโพรซีเดอร์ที่เก็บไว้ซึ่งต้องการผลลัพธ์ของโพรซีเดอร์ที่เก็บอื่นคุณต้องใช้คำสั่ง insert-exec ซึ่งหมายความว่าคุณต้องสร้างตารางชั่วคราวและใช้execคำสั่งเพื่อแทรกผลลัพธ์ของกระบวนงานที่เก็บไว้ลงในตารางชั่วคราว มันยุ่ง ปัญหาหนึ่งของสิ่งนี้คือinsert-execs ไม่สามารถซ้อนกันได้

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

( นี่เป็นอีกเหตุผลหนึ่งที่เราควรแยกตรรกะทางธุรกิจออกจากฐานข้อมูล )


2
  • มันเป็นสิ่งจำเป็นสำหรับ Function ที่จะส่งคืนค่าในขณะที่ไม่ใช่สำหรับกระบวนงานที่เก็บไว้
  • เลือกข้อความสั่งที่ยอมรับใน UDF เท่านั้นในขณะที่ไม่จำเป็นต้องมีข้อความสั่ง DML
  • กระบวนงานที่เก็บไว้ยอมรับคำสั่งใด ๆ รวมถึงคำสั่ง DML
  • UDF อนุญาตเฉพาะอินพุตและไม่เอาต์พุต
  • ขั้นตอนการจัดเก็บช่วยให้ทั้งอินพุตและเอาต์พุต
  • Catch catch ไม่สามารถใช้ใน UDF ได้ แต่สามารถใช้ในกระบวนงานที่เก็บไว้ได้
  • ไม่อนุญาตให้ทำธุรกรรมในฟังก์ชั่นใน UDF แต่ในขั้นตอนการจัดเก็บพวกเขาจะได้รับอนุญาต
  • สามารถใช้ตัวแปรตารางเท่านั้นใน UDF ไม่ใช่ตารางชั่วคราว
  • ขั้นตอนการจัดเก็บช่วยให้ทั้งตัวแปรตารางและตารางชั่วคราว
  • UDF ไม่อนุญาตให้เรียกใช้กระบวนงานที่เก็บไว้จากฟังก์ชันในขณะที่กระบวนงานที่เก็บไว้อนุญาตให้เรียกใช้ฟังก์ชันได้
  • UDF ใช้ในการรวมประโยคในขณะที่กระบวนงานที่เก็บไว้ไม่สามารถใช้ในการรวมประโยคได้.
  • กระบวนงานที่เก็บไว้จะอนุญาตให้กลับเป็นศูนย์ได้ตลอดเวลา UDF ตรงกันข้ามมีค่าที่ต้องกลับมาสู่จุดที่กำหนดไว้

1
  • สามารถใช้ฟังก์ชั่นในข้อความสั่ง select ที่ไม่สามารถใช้โพรซีเดอร์ได้

  • กระบวนงานที่เก็บไว้ใช้ทั้งพารามิเตอร์อินพุตและเอาต์พุต แต่ฟังก์ชันใช้พารามิเตอร์อินพุตเท่านั้น

  • ฟังก์ชั่นไม่สามารถคืนค่าของข้อความประเภท, ntext, รูปภาพและเวลาที่สามารถทำได้

  • ฟังก์ชั่นสามารถใช้เป็นประเภทข้อมูลที่ผู้ใช้กำหนดในการสร้างตาราง แต่ขั้นตอนไม่สามารถทำได้

*** ตัวอย่าง: -create table <tablename>(name varchar(10),salary getsal(name))

getsal ที่นี่เป็นฟังก์ชั่นที่ผู้ใช้กำหนดซึ่งส่งคืนประเภทเงินเดือนเมื่อตารางถูกสร้างขึ้นไม่มีการจัดสรรที่เก็บสำหรับประเภทเงินเดือนและฟังก์ชั่น getal ก็ไม่ได้ถูกดำเนินการ แต่เมื่อเราดึงค่าบางค่าจากตารางนี้ return type ถูกส่งคืนเป็นชุดผลลัพธ์


1

ฉันรู้ว่านี่เป็นคำถามที่เก่ามาก แต่ฉันไม่เห็นสิ่งสำคัญอย่างใดอย่างหนึ่งที่กล่าวถึงในคำตอบใด ๆ : ฝังเข้าไปในแผนแบบสอบถาม

ฟังก์ชั่นสามารถ ...

  1. เกลา:

    CREATE FUNCTION ... RETURNS scalar_type AS BEGIN ... END

  2. ตารางมูลค่าหลายงบ:

    CREATE FUNCTION ... RETURNS @r TABLE(...) AS BEGIN ... END

  3. มูลค่าตารางอินไลน์:

    CREATE FUNCTION ... RETURNS TABLE AS RETURN SELECT ...

ประเภทที่สาม (ค่าในตารางแบบอินไลน์) ได้รับการปฏิบัติโดยการเพิ่มประสิทธิภาพการสืบค้นโดยพื้นฐานแล้วเป็นมุมมอง (parametrized) ซึ่งหมายความว่าการอ้างอิงฟังก์ชันจากแบบสอบถามของคุณคล้ายกับการคัดลอกวางเนื้อหา SQL ของฟังก์ชัน (โดยไม่ต้องคัดลอกจริง) เพื่อประโยชน์ดังต่อไปนี้:

  • ตัววางแผนคิวรีสามารถปรับการดำเนินการของฟังก์ชั่นอินไลน์ได้เช่นเดียวกับการสืบค้นย่อยอื่น ๆ (เช่นกำจัดคอลัมน์ที่ไม่ได้ใช้งาน, ผลักภาคลง, เลือกกลยุทธ์เข้าร่วมที่แตกต่างกันเป็นต้น)
  • การรวมฟังก์ชั่นอินไลน์เข้าด้วยกันหลายตัวไม่ต้องการผลลัพธ์ที่เกิดขึ้นจากฟังก์ชันแรกก่อนที่จะส่งไปยังฟังก์ชันถัดไป

ด้านบนสามารถนำไปสู่การประหยัดประสิทธิภาพที่สำคัญโดยเฉพาะอย่างยิ่งเมื่อรวมฟังก์ชั่นหลายระดับ


หมายเหตุ: ดูเหมือนว่า SQL Server 2019 จะแนะนำรูปแบบของฟังก์ชั่นสเกลาร์อินไลน์เช่นกัน


-2

ใน SQL Server ฟังก์ชันและกระบวนงานที่เก็บไว้เป็นเอนทิตีที่แตกต่างกันสองประเภท

ฟังก์ชั่น:ในฐานข้อมูล SQL Server ฟังก์ชั่นที่ใช้ในการดำเนินการบางอย่างและการกระทำผลตอบแทนทันที ฟังก์ชั่นมีสองประเภท:

  1. กำหนดระบบ

  2. ผู้ใช้กำหนด

กระบวนงานที่เก็บไว้:ใน SQL Server กระบวนงานที่เก็บไว้จะถูกเก็บไว้ในเซิร์ฟเวอร์และสามารถคืนค่าศูนย์ค่าเดียวและหลายค่า กระบวนงานที่เก็บไว้มีสองประเภท:

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