Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Tạo một hàm đa giá trị bảng sao kê (MSTVF) trong SQL Server

Bạn có thể tạo một hàm giá trị bảng nhiều câu lệnh (MSTVF) trong SQL Server bằng cách sử dụng T-SQL CREATE FUNCTION cú pháp.

Cú pháp

Đây là cú pháp chính thức cho TVF nhiều câu lệnh.

CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type   
    [ = default ] [READONLY] }   
    [ ,...n ]  
  ]  
)  
RETURNS @return_variable TABLE <table_type_definition>  
    [ WITH  [ ,...n ] ]  
    [ AS ]  
    BEGIN   
        function_body   
        RETURN  
    END  
[ ; ]

Ví dụ 1 - MSTVF cơ bản

Dưới đây là một ví dụ về hàm có giá trị trong bảng nhiều câu lệnh.

CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70))
    RETURNS @pets TABLE (
        PetId varchar(20),
        PetName varchar(70)
    )
AS
BEGIN
    INSERT INTO @pets
    SELECT 
        CONCAT('Cat', ' ', CatId),
        CatName
    FROM dbo.Cats
    WHERE CatName = @PetName;

    INSERT INTO @pets
    SELECT 
        CONCAT('Dog', ' ', DogId),
        DogName
    FROM dbo.Dogs
    WHERE DogName = @PetName;

    IF @@ROWCOUNT = 0
    BEGIN
        INSERT INTO @pets
        VALUES (
            '',
            'There are no pets of that name.'
            )
    END

    RETURN;
END;

GO

Cấu trúc của bảng trả về được xác định ngay từ đầu khi tôi chỉ định @pets Biến đổi. Kết quả truy vấn được chèn vào @pets biến.

Trong trường hợp này, hàm yêu cầu nhập tên vật nuôi làm đối số. Sau đó, nó sử dụng đối số này trong các truy vấn để trả về dữ liệu có liên quan. Là một đa -bảng câu lệnh có giá trị hàm, tôi có thể bao gồm nhiều câu lệnh trong định nghĩa của hàm.

Ví dụ 2 - Thêm liên kết giản đồ

Thông thường, một ý tưởng hay là lược đồ liên kết các chức năng của bạn bằng cách sử dụng SCHEMABINDING lý lẽ.

Làm điều này sẽ đảm bảo rằng các bảng bên dưới không thể bị thay đổi theo cách có thể ảnh hưởng đến chức năng của bạn.

Nếu không có liên kết lược đồ, các bảng bên dưới có thể được sửa đổi hoặc thậm chí bị xóa. Làm điều này có thể phá vỡ chức năng.

Đây là chức năng tương tự, nhưng lần này có liên kết giản đồ:

CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70))
    RETURNS @pets TABLE (
        PetId varchar(20),
        PetName varchar(70)
    )
    WITH SCHEMABINDING
AS
BEGIN
    INSERT INTO @pets
    SELECT 
        CONCAT('Cat', ' ', CatId),
        CatName
    FROM dbo.Cats
    WHERE CatName = @PetName;

    INSERT INTO @pets
    SELECT 
        CONCAT('Dog', ' ', DogId),
        DogName
    FROM dbo.Dogs
    WHERE DogName = @PetName;

    IF @@ROWCOUNT = 0
    BEGIN
        INSERT INTO @pets
        VALUES (
            '',
            'There are no pets of that name.'
            )
    END

    RETURN;
END;

GO

Lưu ý rằng tôi đã sử dụng tên gồm hai phần khi tham chiếu đến các bảng trong truy vấn của mình (tôi đã sử dụng dbo.Catsdbo.Dogs khi tham chiếu bảng, thay vì chỉ Cats hoặc Dogs ). Thực hiện điều này là một yêu cầu đối với lược đồ ràng buộc một đối tượng. Nếu bạn cố gắng liên kết lược đồ một đối tượng mà không sử dụng tên gồm hai phần, bạn sẽ gặp lỗi.

Bây giờ, lược đồ tôi đã ràng buộc hàm của mình, nếu tôi cố gắng bỏ bảng được tham chiếu trong định nghĩa của nó, tôi sẽ gặp lỗi:

DROP TABLE Dogs;

Kết quả:

Msg 3729, Level 16, State 1, Line 1
Cannot DROP TABLE 'Dogs' because it is being referenced by object 'udf_PetsByName_MSTVF'.

Nhân tiện, đây là điều sẽ xảy ra nếu tôi cố gắng tạo hàm mà không sử dụng đặt tên hai phần:

CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70))
    RETURNS @pets TABLE (
        PetId varchar(20),
        PetName varchar(70)
    )
    WITH SCHEMABINDING
AS
BEGIN
    INSERT INTO @pets
    SELECT 
        CONCAT('Cat', ' ', CatId),
        CatName
    FROM Cats
    WHERE CatName = @PetName;

    INSERT INTO @pets
    SELECT 
        CONCAT('Dog', ' ', DogId),
        DogName
    FROM Dogs
    WHERE DogName = @PetName;

    IF @@ROWCOUNT = 0
    BEGIN
        INSERT INTO @pets
        VALUES (
            '',
            'There are no pets of that name.'
            )
    END

    RETURN;
END;

GO

Kết quả:

Msg 4512, Level 16, State 3, Procedure udf_PetsByName_MSTVF, Line 10
Cannot schema bind table valued function 'dbo.udf_PetsByName_MSTVF' because name 'Cats' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.

Ví dụ 3 - Thêm mã hóa

Bạn cũng có thể mã hóa các chức năng của mình bằng cách sử dụng ENCRYPTION lý lẽ.

Dưới đây là một ví dụ về mã hóa hàm:

CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70))
    RETURNS @pets TABLE (
        PetId varchar(20),
        PetName varchar(70)
    )
    WITH SCHEMABINDING, ENCRYPTION
AS
BEGIN
    INSERT INTO @pets
    SELECT 
        CONCAT('Cat', ' ', CatId),
        CatName
    FROM dbo.Cats
    WHERE CatName = @PetName;

    INSERT INTO @pets
    SELECT 
        CONCAT('Dog', ' ', DogId),
        DogName
    FROM dbo.Dogs
    WHERE DogName = @PetName;

    IF @@ROWCOUNT = 0
    BEGIN
        INSERT INTO @pets
        VALUES (
            '',
            'There are no pets of that name.'
            )
    END

    RETURN;
END;

GO

Bây giờ tôi không thể xem định nghĩa của hàm.

SELECT definition 
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('udf_PetsByName_MSTVF');

Kết quả:

+--------------+
| definition   |
|--------------|
| NULL         |
+--------------+

Tôi cũng nhận được thông báo lỗi khi cố gắng tập lệnh cho định nghĩa của hàm qua Azure Data Studio:

No script was returned when scripting as Create on object UserDefinedFunction

Lưu ý rằng văn bản của hàm được mã hóa vẫn có sẵn cho người dùng có đặc quyền có thể truy cập các bảng hệ thống qua cổng DAC hoặc truy cập trực tiếp vào các tệp cơ sở dữ liệu. Ngoài ra, người dùng có thể đính kèm trình gỡ lỗi vào quy trình máy chủ có thể truy xuất quy trình ban đầu từ bộ nhớ trong thời gian chạy.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách tốt nhất để kiểm soát phiên bản các thủ tục được lưu trữ trên máy chủ SQL của tôi là gì?

  2. SQL Server - Khám phá nội bộ của sp_spaceused

  3. Cấp quyền cấp bảng trong SQL Server

  4. Sự khác biệt của hai ngày thời gian trong máy chủ sql

  5. Cách nhận tổng tích lũy