Chức năng so với thủ tục lưu trữ trong SQL Server


831

Tôi đã học Hàm và Thủ tục lưu trữ trong một thời gian dài nhưng tôi không biết tại sao và khi nào tôi nên sử dụng một hàm hoặc một thủ tục được lưu trữ. Họ trông giống tôi, có lẽ vì tôi là người mới về điều đó.

Ai đó có thể cho tôi biết tại sao?





3
tốc độ như thế nào? cái nào chạy cùng một truy vấn nhanh hơn?
AmiNadimi

Câu trả lời:


708

Các hàm là các giá trị được tính toán và không thể thực hiện các thay đổi môi trường vĩnh viễn thành SQL Server(nghĩa là không INSERThoặc các UPDATEcâu lệnh được phép).

Một hàm có thể được sử dụng nội tuyến trong các SQLcâu lệnh nếu nó trả về giá trị vô hướng hoặc có thể được nối nếu nó trả về một tập kết quả.

Một điểm đáng chú ý từ các ý kiến, trong đó tóm tắt câu trả lời. Cảm ơn @Sean K Anderson:

Các hàm tuân theo định nghĩa khoa học máy tính ở chỗ chúng PHẢI trả về một giá trị và không thể thay đổi dữ liệu chúng nhận được dưới dạng tham số (các đối số). Các hàm không được phép thay đổi bất cứ điều gì, phải có ít nhất một tham số và chúng phải trả về một giá trị. Các procs được lưu trữ không phải có một tham số, có thể thay đổi các đối tượng cơ sở dữ liệu và không phải trả về một giá trị.

Cách gọi SQLhàm từ thủ tục lưu trữ và khi chúng ta sử dụng hàm thay vì thủ tục được lưu trữ.

Xin chào các bạn, hôm nay chúng ta sẽ thảo luận Khi nào nên sử dụng thủ tục được lưu trữ và khi nào nên sử dụng chức năng. Trong nhóm đơn giản Nếu bạn muốn tính toán một số giá trị và nó sẽ trả về một giá trị duy nhất, do đó không bắt buộc:

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


13
Về cơ bản không có DML được phép?
david blaine

173
Các hàm tuân theo định nghĩa về độ tin cậy của máy tính ở chỗ chúng PHẢI trả về một giá trị và không thể thay đổi dữ liệu mà chúng nhận được dưới dạng tham số (các đối số). Các hàm không được phép thay đổi bất cứ điều gì, phải có ít nhất một tham số và chúng phải trả về một giá trị. Các procs được lưu trữ không phải có một tham số, có thể thay đổi các đối tượng cơ sở dữ liệu và không phải trả về một giá trị.
Sean Anderson

23
Trong thực tế, bạn có thể có các câu lệnh INSERT, UPDATE và DELETE trong một hàm để sửa đổi các biến bảng cục bộ.
Ani

14
@Ani - Bạn có thể khởi tạo và sửa đổi bất kỳ số lượng biến cục bộ nào trong một hàm tuy nhiên bạn không thể sửa đổi bất cứ điều gì ngoài phạm vi của hàm.
MyItchyChin

40
Hàm @SeanKAnderson "phải có ít nhất một tham số" là không đúng.
liang

624

Sự khác biệt giữa SP và UDF được liệt kê dưới đây:

+---------------------------------+----------------------------------------+
| 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
Các hàm phải trả về một giá trị hoặc một tập hợp.
Rafareino

8
Điều này đến 3 năm sau nhưng nên được đặt lên hàng đầu vì nó vừa dễ đọc vừa mở rộng.
DanteTheSmith

SP có thể sử dụng cả bảng tạm thời và biến bảng trong khi UDF chỉ có thể sử dụng biến bảng. Các biến bảng lần lượt có thể không sử dụng các chỉ mục. UDF có thể được gọi trong ỨNG DỤNG CROSS không giống như SP
Ludovic Aubert

190

Chức năng và thủ tục lưu trữ phục vụ các mục đích riêng biệt. Mặc dù nó không phải là sự tương tự tốt nhất, các hàm có thể được xem theo nghĩa đen như bất kỳ chức năng nào khác mà bạn sử dụng trong bất kỳ ngôn ngữ lập trình nào, nhưng các procs được lưu trữ giống như các chương trình riêng lẻ hoặc một tập lệnh bó.

Các chức năng thường có một đầu ra và đầu vào tùy chọn. Đầu ra sau đó có thể được sử dụng làm đầu vào cho một chức năng khác (Máy chủ SQL tích hợp sẵn như DATEDIFF, LEN, v.v.) hoặc làm vị ngữ cho Truy vấn SQL - ví dụ: SELECT a, b, dbo.MyFunction(c) FROM tablehoặc SELECT a, b, c FROM table WHERE a = dbo.MyFunc(c).

Các procs được lưu trữ được sử dụng để liên kết các truy vấn SQL với nhau trong một giao dịch và giao diện với thế giới bên ngoài. Các khung như ADO.NET, v.v. không thể gọi hàm trực tiếp, nhưng chúng có thể gọi trực tiếp một Proc được lưu trữ.

Các chức năng có một mối nguy hiểm tiềm ẩn: chúng có thể bị sử dụng sai và gây ra các vấn đề hiệu suất khá khó chịu: xem xét truy vấn này:

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

Trường hợp MyFactor được khai báo là:

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

   SELECT localValue 
      FROM dbo.localToNationalMapTable
      WHERE nationalValue = @someValue

   RETURN @retval
END

Điều xảy ra ở đây là hàm MyFunction được gọi cho mỗi hàng trong bảng MyTable. Nếu MyTable có 1000 hàng, thì đó là 1000 truy vấn đặc biệt khác đối với cơ sở dữ liệu. Tương tự, nếu hàm được gọi khi được chỉ định trong thông số cột, thì hàm sẽ được gọi cho mỗi hàng được trả về bởi SELECT.

Vì vậy, bạn cần phải cẩn thận chức năng viết. Nếu bạn thực hiện CHỌN từ một bảng trong một hàm, bạn cần tự hỏi liệu nó có thể được thực hiện tốt hơn với THAM GIA trong phần lưu trữ cha mẹ hoặc một số cấu trúc SQL khác (như CASE ... KHI ... ELSE ... KẾT THÚC).


2
Bạn có thể giải thích rõ hơn về "Các khung như ADO.NET, v.v. không thể gọi hàm trực tiếp" không? Tôi đã thực hiện các chức năng với các nhà cung cấp dữ liệu ADO.NET mà không gặp vấn đề gì.
Ian Kemp

24
Bạn phải gọi một hàm thông qua một số câu lệnh CHỌN - một hàm không thể được gọi là một đoạn mã độc lập theo cách riêng của nó - nó phải được gọi là một phần của một câu lệnh SQL lớn hơn, ngay cả khi câu lệnh SQL đó không là gì nữa hơn SELECT * from dbo.MyTableValuedFunction(). Sprocs, mặt khác, có thể được gọi trực tiếp với ADO.NET bằng cách đặt SqlCommand.CommandTypethành CommandType.StoredProcedure.
Chris J

60

Sự khác nhau giữa các thủ tục được lưu trữ và các chức năng do người dùng xác định:

  • Các thủ tục lưu trữ không thể được sử dụng trong Chọn câu lệnh.
  • Thủ tục lưu trữ hỗ trợ Nghị quyết Tên hoãn lại.
  • Thủ tục lưu trữ thường được sử dụng để thực hiện logic kinh doanh.
  • Thủ tục lưu trữ có thể trả về bất kỳ kiểu dữ liệu.
  • Các thủ tục được lưu trữ có thể chấp nhận số lượng tham số đầu vào lớn hơn các hàm do người dùng xác định. Thủ tục lưu trữ có thể có tới 21.000 tham số đầu vào.
  • Các thủ tục lưu trữ có thể thực thi SQL động.
  • Thủ tục lưu trữ hỗ trợ xử lý lỗi.
  • Các hàm không xác định có thể được sử dụng trong các thủ tục được lưu trữ.

  • Các hàm do người dùng định nghĩa có thể được sử dụng trong Chọn câu lệnh.
  • Các chức năng do người dùng xác định không hỗ trợ Độ phân giải tên hoãn lại.
  • Các hàm do người dùng định nghĩa thường được sử dụng để tính toán.
  • Các hàm do người dùng định nghĩa sẽ trả về một giá trị.
  • Các chức năng do người dùng xác định không thể trả về Hình ảnh.
  • Các hàm do người dùng xác định chấp nhận số lượng tham số đầu vào nhỏ hơn các thủ tục được lưu trữ. UDF có thể có tới 1.023 tham số đầu vào.
  • Các bảng tạm thời không thể được sử dụng trong các hàm do người dùng định nghĩa.
  • Các hàm do người dùng định nghĩa không thể thực thi SQL động.
  • Các chức năng do người dùng xác định không hỗ trợ xử lý lỗi. RAISEERRORHOẶC @@ERRORkhông được phép trong UDFs.
  • Các hàm không xác định có thể được sử dụng trong UDFs. Ví dụ, GETDATE()không thể được sử dụng trong UDFs.

1
Để trích dẫn @cantlyBoy bên dưới re. một câu trả lời không có uy tín khác (bởi @Ankit) (<- xem tôi đã làm như thế nào ?;)): "Bạn nên đưa ra tài liệu tham khảo nguồn. Đây là từ ( blog.msdn.microsoft.com/pradeepsvs/2014/10 / 08 / Bắn ). Hãy tôn trọng công việc mà người khác làm! "
Tom

7
Blog này đã được viết từ ngày 8 tháng 10 năm 2014 và câu trả lời này đã được viết từ ngày 2 tháng 5 năm 2013 @Tom
Kumar Manish

1
@Code Rider: Ah, lời xin lỗi của tôi! Không thể tin rằng tôi đã không nhận thấy điều đó! Vì vậy, blog đã sao chép bạn (hoặc người khác đã làm) mà không có tín dụng?
Tom

GETDATE()có thể được sử dụng trong Hàm. Trục trên Không xác định không phải là một tốt.
PerformanceDBA

56

Viết hàm do người dùng định nghĩa khi bạn muốn tính toán và trả về giá trị để sử dụng trong các câu lệnh SQL khác; viết một thủ tục được lưu trữ khi bạn muốn thay vào đó là nhóm một tập hợp các câu lệnh SQL có thể phức tạp. Đây là hai trường hợp sử dụng khá khác nhau, sau khi tất cả!


18
có nhiều loại khác nhau của hàm do người dùng định nghĩa. Những cái vô hướng chỉ trả về giá trị; các loại kết quả truy xuất khác.
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 có thể được gọi trong ỨNG DỤNG CROSS, không giống như SP
Ludovic Aubert

24

Sự khác biệt cơ bản

Hàm phải trả về một giá trị nhưng trong Thủ tục lưu trữ thì nó là tùy chọn (Quy trình có thể trả về giá trị 0 hoặc n).

Các hàm chỉ có thể có các tham số đầu vào cho nó trong khi Thủ tục có thể có các tham số đầu vào / đầu ra.

Hàm lấy một tham số đầu vào là bắt buộc nhưng Thủ tục lưu trữ có thể mất o đến n tham số đầu vào ..

Hàm có thể được gọi từ Thủ tục trong khi Thủ tục không thể được gọi từ Hàm.

Sự khác biệt trước

Quy trình cho phép câu lệnh CHỌN cũng như DML (INSERT / UPDATE / DELETE) trong đó trong khi Hàm chỉ cho phép câu lệnh CHỌN trong đó.

Các thủ tục không thể được sử dụng trong câu lệnh SELECT trong khi Hàm có thể được nhúng trong câu lệnh SELECT.

Các thủ tục được lưu trữ không thể được sử dụng trong các câu lệnh SQL ở bất cứ đâu trong phần WHERE / HAVING / SELECT trong khi Hàm có thể.

Các hàm trả về bảng có thể được coi là một hàng khác. Điều này có thể được sử dụng trong THAM GIA với các bảng khác.

Hàm Inline có thể mặc dù là các khung nhìn lấy tham số và có thể được sử dụng trong THAM GIA và các hoạt động Rowset khác.

Ngoại lệ có thể được xử lý bằng khối bắt thử trong Quy trình trong khi khối bắt thử có thể được sử dụng trong Hàm.

Chúng tôi có thể đi Quản lý giao dịch trong Thủ tục trong khi chúng tôi không thể vào Chức năng.

nguồn


25
Bạn nên đưa ra các tài liệu tham khảo nguồn. Đây là từ dotnet-tricks.com/Tutorial/sqlserver/ . Hãy tôn trọng công việc mà người khác làm!
tò mòBoy

16
Nó không phải là một lý do để không cung cấp một tài liệu tham khảo nguồn. Bạn có thể đề cập ở phần cuối của nó!
tò mòBoy

2
Re. "Hàm phải trả về một giá trị nhưng trong Thủ tục lưu trữ, nó là tùy chọn ....": Tôi sẽ làm rõ rằng: "Hàm phải trả về một và chỉ một giá trị (phải được thực hiện thông qua Returnstừ khóa và phải là loại vô hướng hoặc bảng) , nhưng Các thủ tục được lưu trữ có thể tùy ý trả về: a) 1 Intloại Mã kết quả thông qua ReturnTuyên bố và / hoặc b) 1+ Tham số (loại bao gồm Cursor) thông qua Outputtừ khóa và / hoặc c) 1+ Bộ hàng thông qua SelectBáo cáo. Nếu chỉ có 1 Hàng được trả về, nó có thể được sử dụng làm đối số "exec_statement" của câu lệnh "Chèn vào".
Tom

20

Hàm do người dùng xác định là một công cụ quan trọng có sẵn cho lập trình viên máy chủ sql. Bạn có thể sử dụng nó nội tuyến trong một câu lệnh SQL như vậy

SELECT a, lookupValue(b), c FROM customers 

nơi lookupValuesẽ là một UDF. Loại chức năng này là không thể khi sử dụng một thủ tục được lưu trữ. Đồng thời bạn không thể thực hiện một số điều nhất định trong UDF. Điều cơ bản cần nhớ ở đây là UDF:

  • không thể tạo ra những thay đổi vĩnh viễn
  • không thể thay đổi dữ liệu

một thủ tục lưu trữ có thể làm những điều đó.

Đối với tôi, việc sử dụng nội tuyến của UDF là việc sử dụng UDF quan trọng nhất.


14

Thủ tục lưu trữ được sử dụng như các kịch bản . Họ chạy một loạt các lệnh cho bạn và bạn có thể lên lịch để chạy vào những thời điểm nhất định. Thường chạy nhiều câu lệnh DML như INSERT, UPDATE, DELETE, v.v. hoặc thậm chí CHỌN.

Các hàm được sử dụng làm phương thức. Bạn vượt qua nó một cái gì đó và nó trả về một kết quả. Nên nhỏ và nhanh - làm điều đó một cách nhanh chóng. Thường được sử dụng trong một câu lệnh CHỌN.


2
Đây là một bản tóm tắt tốt về hai, cách nhanh chóng và bẩn thỉu để nghĩ về họ.
Eric Bishard

2
Quả thực là một bản tóm tắt tốt. Các câu trả lời khác tập trung vào sự khác biệt về lý thuyết của hai người, trong khi vẫn khiến tôi không chắc chắn khi nào nên sử dụng cái nào trong thực tế.
jf328

8

Thủ tục lưu trữ:

  • Giống như một chương trình thu nhỏ trong SQL Server.
  • Có thể đơn giản như một câu lệnh chọn hoặc phức tạp như một tập lệnh dài thêm, xóa, cập nhật và / hoặc đọc dữ liệu từ nhiều bảng trong cơ sở dữ liệu.
  • (Có thể thực hiện các vòng lặp và con trỏ, cả hai đều cho phép bạn làm việc với các kết quả nhỏ hơn hoặc theo từng thao tác hàng trên dữ liệu.)
  • Nên được gọi bằng cách sử dụng EXEChoặc EXECUTEtuyên bố.
  • Trả về các biến của bảng, nhưng chúng ta không thể sử dụng OUTtham số.
  • Hỗ trợ giao dịch.

Chức năng:

  • Không thể được sử dụng để cập nhật, xóa hoặc thêm hồ sơ vào cơ sở dữ liệu.
  • Đơn giản chỉ cần trả về một giá trị duy nhất hoặc một giá trị bảng.
  • Chỉ có thể được sử dụng để chọn hồ sơ. Tuy nhiên, nó có thể được gọi rất dễ dàng từ bên trong SQL tiêu chuẩn, chẳng hạn như:

    SELECT dbo.functionname('Parameter1')

    hoặc là

    SELECT Name, dbo.Functionname('Parameter1') FROM sysObjects
  • Đối với các thao tác chọn tái sử dụng đơn giản, các chức năng có thể đơn giản hóa mã. Chỉ cần cảnh giác với việc sử dụng JOINmệnh đề trong các chức năng của bạn. Nếu hàm của bạn có một JOINmệnh đề và bạn gọi nó từ một câu lệnh chọn khác trả về nhiều kết quả, lệnh gọi hàm đó sẽ JOIN kết hợp các bảng đó cho mỗi dòng được trả về trong tập kết quả. Vì vậy, mặc dù chúng có thể hữu ích trong việc đơn giản hóa một số logic, chúng cũng có thể là một nút cổ chai hiệu năng nếu chúng không được sử dụng đúng cách.

  • Trả về các giá trị sử dụng OUTtham số.
  • Không hỗ trợ giao dịch.

8

Hàm do người dùng xác định.

  1. Hàm phải trả về một giá trị.
  2. Sẽ chỉ cho phép Chọn các câu lệnh, nó sẽ không cho phép chúng tôi sử dụng các câu lệnh DML.
  3. Nó sẽ chỉ cho phép các tham số đầu vào, không hỗ trợ các tham số đầu ra.
  4. Nó sẽ không cho phép chúng tôi sử dụng các khối thử.
  5. Giao dịch không được phép trong các chức năng.
  6. Chúng tôi chỉ có thể sử dụng các biến bảng, nó sẽ không cho phép sử dụng các bảng tạm thời.
  7. Thủ tục lưu trữ không thể được gọi từ một chức năng.
  8. Các chức năng có thể được gọi từ một câu lệnh chọn.
  9. Một UDF có thể được sử dụng trong mệnh đề nối như một tập kết quả.

Thủ tục lưu trữ

  1. Thủ tục lưu trữ có thể hoặc không trả về giá trị.
  2. Có thể có các câu lệnh chọn cũng như các câu lệnh DML như chèn, cập nhật, xóa, v.v.
  3. Nó có thể có cả tham số đầu vào và đầu ra.
  4. Để xử lý ngoại lệ, chúng ta có thể sử dụng thử khối bắt.
  5. Có thể sử dụng các giao dịch trong Thủ tục lưu trữ.
  6. Có thể sử dụng cả hai biến bảng cũng như bảng tạm thời trong đó.
  7. Thủ tục lưu trữ có thể gọi các chức năng.
  8. Các thủ tục không thể được gọi từ các câu lệnh Chọn / Ở đâu / Có và v.v. Lệnh Execute / Exec có thể được sử dụng để gọi / thực hiện Thủ tục lưu trữ.
  9. Các thủ tục không thể được sử dụng trong mệnh đề Tham gia

6

Để quyết định khi nào nên sử dụng những điểm nào sau đây có thể giúp-

  1. Các thủ tục được lưu trữ không thể trả về một biến bảng trong đó hàm có thể làm điều đó.

  2. Bạn có thể sử dụng các thủ tục được lưu trữ để thay đổi các tham số môi trường máy chủ trong khi sử dụng các chức năng bạn không thể.

chúc mừng


6

Các chức năng của SQL Server, như con trỏ, được dùng làm vũ khí cuối cùng của bạn! Họ có vấn đề về hiệu năng và do đó sử dụng hàm có giá trị bảng nên tránh càng nhiều càng tốt. Nói về hiệu suất là nói về một bảng có hơn 1.000.000 bản ghi được lưu trữ trên một máy chủ trên phần cứng hạng trung; nếu không, bạn không cần phải lo lắng về hiệu năng gây ra bởi các chức năng.

  1. Không bao giờ sử dụng hàm để trả về tập kết quả cho mã bên ngoài (như ADO.Net)
  2. Sử dụng kết hợp lượt xem / lưu trữ procs càng nhiều càng tốt. bạn có thể phục hồi từ các vấn đề về hiệu suất phát triển trong tương lai bằng cách sử dụng các đề xuất DTA (Cố vấn điều chỉnh cơ sở dữ liệu) sẽ cung cấp cho bạn (như các chế độ xem và thống kê được lập chỉ mục) - đôi khi!

để tham khảo thêm, hãy xem: http://database.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-dposed-f ghép.html


1
Cảm ơn. Đã viết một hàm ngày hôm nay để gọi trong một truy vấn để điền các giá trị cho một cột. Thực thi đã chạy trong hơn 3 phút trước khi tôi dừng nó. Tìm ra một cách THAM GIA để làm điều đó. Thực hiện xong trong 15 giây. (Tập dữ liệu là 3456 hàng). Hiệu suất lớn khác nhau.
VISQL

chỉnh sửa: Thực hiện kết thúc trong khoảng từ 15 đến 50 giây tùy thuộc vào cột tôi "ĐẶT HÀNG B" NG "(Tập dữ liệu là 3456 hàng). Hiệu suất lớn khác biệt.
VISQL

Sự khác biệt về hiệu suất có thể bắt nguồn từ các loại cột khác nhau mà bạn sắp xếp kết quả theo. SQL Server hoạt động tốt hơn nhiều với số lượng so với dữ liệu ký tự. Bạn có thể sử dụng DTA trên truy vấn 50 giây đó và xem liệu nó có thể đưa ra một số loại đề xuất chỉ số / chỉ mục để làm cho truy vấn chạy nhanh hơn một chút không.
Achilles

1
Tôi không chắc chắn đủ bằng chứng đã được cung cấp để nói rằng đó là biện pháp cuối cùng. Bạn có thể nghĩ về một chức năng như một khung nhìn được tham số hóa có thể được vận hành thêm. Ví dụ, bạn muốn tham gia khách hàng để đặt hàng, nhưng chỉ cho michigan. Bạn tạo một hàm khách hàng (@StateCode) sẽ chỉ tham gia một giá trị khách hàng của một tiểu bang. Sau đó, tôi có thể tiếp tục hoạt động trên bộ này như Chọn FirstName, LastName, OrderTotal, StoreName From CustomerOrder ('MI') INNER THAM GIA Cửa hàng TRÊN Cửa hàng.StoreID = Đơn hàng.StoreID WHERE OrderTotal> 100; Đây sẽ là một nỗi đau với SP vì bạn phải tạm thời sao chép.
MPavlak

Bạn có bao nhiêu hồ sơ trong bảng đó? Nếu phần cứng của bạn xử lý đúng cách, bạn sẽ không cần phải lo lắng về việc chọn vũ khí. Một cái muỗng có thể thực hiện công việc khi nó đủ cứng để làm gãy thanh kiếm; độ cứng này được gọi là PHẦN CỨNG!
Achilles

3

Bắt đầu với các hàm trả về một giá trị duy nhất. Điều tuyệt vời là bạn có thể đặt mã được sử dụng thường xuyên vào một hàm và trả về chúng dưới dạng một cột trong tập kết quả.

Sau đó, bạn có thể sử dụng một chức năng cho một danh sách các thành phố được tham số hóa. dbo.GetCitiesIn ("NY") Trả về một bảng có thể được sử dụng như một phép nối.

Đó là một cách tổ chức mã. Biết khi nào một cái gì đó có thể tái sử dụng và khi nó là một sự lãng phí thời gian là một cái gì đó chỉ có được thông qua thử nghiệm và lỗi và kinh nghiệm.

Ngoài ra, các chức năng là một ý tưởng tốt trong SQL Server. Chúng nhanh hơn và có thể khá mạnh mẽ. Nội tuyến và lựa chọn trực tiếp. Cẩn thận không lạm dụng.


3

Đây là một lý do thực tế để thích các chức năng hơn các thủ tục được lưu trữ. Nếu bạn có một thủ tục được lưu trữ cần kết quả của một thủ tục được lưu trữ khác, bạn phải sử dụng câu lệnh insert-exec. Điều này có nghĩa là bạn phải tạo một bảng tạm thời và sử dụng một execcâu lệnh để chèn kết quả của thủ tục được lưu trữ vào bảng tạm thời. Nó lộn xộn. Một vấn đề với điều này là insert-execs không thể được lồng nhau .

Nếu bạn bị mắc kẹt với các thủ tục được lưu trữ gọi các thủ tục được lưu trữ khác, bạn có thể gặp phải điều này. Nếu thủ tục lưu trữ lồng nhau chỉ đơn giản trả về một tập dữ liệu, nó có thể được thay thế bằng hàm có giá trị bảng và bạn sẽ không còn gặp phải lỗi này nữa.

( đây là một lý do khác chúng ta nên giữ logic kinh doanh ra khỏi cơ sở dữ liệu )


2
  • Điều bắt buộc là Hàm trả về một giá trị trong khi nó không dành cho thủ tục được lưu trữ.
  • Chọn các câu lệnh chỉ được chấp nhận trong UDF trong khi các câu lệnh DML không bắt buộc.
  • Thủ tục lưu trữ chấp nhận mọi câu lệnh cũng như câu lệnh DML.
  • UDF chỉ cho phép đầu vào và không đầu ra.
  • Thủ tục lưu trữ cho phép cho cả đầu vào và đầu ra.
  • Các khối bắt không thể được sử dụng trong UDF nhưng có thể được sử dụng trong thủ tục được lưu trữ.
  • Không có giao dịch nào được phép trong các chức năng trong UDF nhưng trong thủ tục lưu trữ thì chúng được phép.
  • Chỉ các biến bảng có thể được sử dụng trong UDF chứ không phải các bảng tạm thời.
  • Thủ tục lưu trữ cho phép cả hai biến bảng và bảng tạm thời.
  • UDF không cho phép các thủ tục được lưu trữ được gọi từ các hàm trong khi các thủ tục được lưu trữ cho phép gọi các hàm.
  • UDF được sử dụng trong mệnh đề nối trong khi các thủ tục được lưu trữ không thể được sử dụng trong mệnh đề nối.
  • Thủ tục lưu trữ sẽ luôn cho phép trở về không. Ngược lại, UDF có các giá trị phải quay trở lại điểm đã định trước.

1
  • Các hàm có thể được sử dụng trong một câu lệnh chọn trong khi các thủ tục không thể.

  • Thủ tục lưu trữ có cả tham số đầu vào và đầu ra nhưng Hàm chỉ lấy tham số đầu vào.

  • Các hàm không thể trả về các giá trị của văn bản loại, ntext, hình ảnh và dấu thời gian khi có thể làm thủ tục.

  • Các hàm có thể được sử dụng như các kiểu dữ liệu do người dùng định nghĩa trong bảng tạo nhưng các thủ tục không thể.

*** Ví dụ: -tạo table <tablename>(name varchar(10),salary getsal(name))

Ở đây gotal là một hàm do người dùng xác định trả về loại lương, khi bảng được tạo, không có lưu trữ nào được phân bổ cho loại lương và hàm getal cũng không được thực thi, nhưng khi chúng ta tìm nạp một số giá trị từ bảng này, hàm getal sẽ được thực thi và Kiểu trả về được trả về như tập kết quả.


1

Tôi nhận ra đây là một câu hỏi rất cũ, nhưng tôi không thấy một khía cạnh quan trọng nào được đề cập trong bất kỳ câu trả lời nào: đưa vào kế hoạch truy vấn.

Chức năng có thể ...

  1. Vô hướng:

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

  2. Bảng đa giá trị:

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

  3. Bảng nội tuyến có giá trị:

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

Loại thứ ba (giá trị bảng nội tuyến) được xử lý bởi trình tối ưu hóa truy vấn về cơ bản dưới dạng các khung nhìn (tham số hóa), có nghĩa là tham chiếu hàm từ truy vấn của bạn tương tự như dán cơ thể SQL của chức năng (không thực sự dán sao chép), dẫn đầu với những lợi ích sau:

  • Trình lập kế hoạch truy vấn có thể tối ưu hóa việc thực thi của hàm nội tuyến giống như bất kỳ truy vấn phụ nào khác (ví dụ: loại bỏ các cột không sử dụng, đẩy các vị từ xuống, chọn các chiến lược THAM GIA khác nhau, v.v.).
  • Kết hợp một số hàm nội tuyến không yêu cầu cụ thể hóa kết quả từ hàm đầu tiên trước khi đưa nó vào hàm tiếp theo.

Những điều trên có thể dẫn đến khả năng tiết kiệm hiệu suất đáng kể, đặc biệt là khi kết hợp nhiều cấp độ chức năng.


LƯU Ý: Có vẻ như SQL Server 2019 cũng sẽ giới thiệu một số dạng hàm vô hướng .


-2

Trong SQL Server, các hàm và thủ tục được lưu trữ là hai loại thực thể khác nhau.

Hàm: Trong cơ sở dữ liệu SQL Server, các hàm được sử dụng để thực hiện một số hành động và hành động trả về kết quả ngay lập tức. Chức năng có hai loại:

  1. Hệ thống xác định

  2. Đã xác định người dùng

Các thủ tục được lưu trữ: Trong SQL Server, các thủ tục được lưu trữ được lưu trữ trong máy chủ và nó có thể được trả về 0, một và nhiều giá trị. Thủ tục lưu trữ có hai loại:

  1. Thủ tục lưu trữ hệ thống
  2. Thủ tục do người dùng xác định
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.