Thêm vào câu trả lời tuyệt vời của David Browne :
Tôi muốn tham chiếu cơ sở dữ liệu trong đó thủ tục được lưu trữ được lưu trữ, ngay cả khi nó được thực thi trong cơ sở dữ liệu khác.
Bạn rất may mắn vì đây là cách các quy trình được lưu trữ thường xuyên / vĩnh viễn, không có hệ thống đã hoạt động theo cách này và bạn thực sự cần phải thực hiện theo cách của mình để khiến các đối tượng hoạt động trong DB hiện tại. Đây là cách các chức năng hoạt động tốt, chỉ là với các thủ tục được lưu trữ, bạn có các tùy chọn - đánh dấu chúng là "thủ tục lưu trữ hệ thống" hoặc tạo các thủ tục được lưu trữ tạm thời - mà bạn không có chức năng / lượt xem / trình kích hoạt / v.v.
Do các hàm dựng sẵn hoạt động hơi khác so với SQL tĩnh trong các thủ tục được lưu trữ tạm thời, ví dụ sau sử dụng bảng không tạm thời để tham chiếu trong cả UDF và Inline-TVF. Đúng, ví dụ sau đây không thực sự kiểm tra các thủ tục được lưu trữ tạm thời, nhưng lý do tôi sử dụng bảng không tạm thời là vì chúng ta có một trường hợp khác nhau về hành vi, chúng ta cần đảm bảo rằng hành vi đó không xảy ra ở đây. Trong ví dụ sau, nếu một trong hai loại hàm đã biết về cơ sở dữ liệu "hiện tại", thì tham chiếu đến bảng không tạm thời sẽ gây ra lỗi.
THIẾT LẬP
USE [tempdb];
CREATE IF NOT EXISTS TABLE dbo.InTempDB (Col1 INT);
INSERT INTO dbo.InTempDB ([Col1]) VALUES (999);
GO
CREATE
OR ALTER -- comment out if using SQL Server < 2017
FUNCTION dbo.GetDbNameUDF()
RETURNS SYSNAME
AS
BEGIN
DECLARE @DoNothing INT;
SELECT @DoNothing = [Col1] FROM dbo.InTempDB;
RETURN DB_NAME();
END;
GO
CREATE
OR ALTER -- comment out if using SQL Server < 2017
FUNCTION dbo.GetDbNameITVF()
RETURNS TABLE
AS
RETURN
SELECT DB_NAME() AS [DbName],
tmp.[Col1]
FROM dbo.InTempDB tmp;
GO
KIỂM TRA
USE [model];
SELECT DB_NAME() AS [CurrentDB],
tempdb.dbo.GetDbNameUDF() AS [DbNameFromUDF];
-- CurrentDB DbNameFromUDF
-- model tempdb
SELECT DB_NAME() AS [CurrentDB],
*
FROM tempdb.dbo.GetDbNameITVF();
-- CurrentDB DbName Col1
-- model tempdb 999
/* -- clean-up
DROP TABLE dbo.InTempDB;
DROP FUNCTION dbo.GetDbNameUDF;
DROP FUNCTION dbo.GetDbNameITVF;
*/