Bối cảnh DB_ID từ xa hơn ngăn xếp cuộc gọi


11

Trong SQL Server, có thể lấy DB_IDtừ ngữ cảnh từ xa hơn ngăn xếp cuộc gọi không?

Mục tiêu của tôi là tạo ra một số chức năng tiện ích (và được thừa nhận là hacky) trong cơ sở dữ liệu dev sandbox giúp dễ dàng và ngắn gọn để có được tên đầy đủ của các đối tượng được đặt tên ngắn hoặc phân mảnh và thêm vào đó để xóa các đối tượng sử dụng cùng tên ngắn . Các chức năng tiện ích này sẽ nằm trong một cơ sở dữ liệu tiện ích duy nhất nhưng được gọi từ các cơ sở dữ liệu khác trên cùng một máy chủ.

Từ những gì tôi có thể thấy từ thử nghiệm:

  • ORIGINAL_DB_NAME()như dự định trả về bất cứ thứ gì có trong chuỗi kết nối, không phải bối cảnh hiện tại (được đặt bởi USE [dbname]).
  • Khi được gọi trong một hàm DB_NAME()trả về tên của cơ sở dữ liệu nơi hàm đó được xác định . Một cách khác để nói điều này là bối cảnh bên trong một hàm hoặc thủ tục được lưu trữ là của cơ sở dữ liệu được xác định

Tôi biết công cụ theo dõi từng bối cảnh cơ sở dữ liệu lên và xuống ngăn xếp cuộc gọi (xem bên dưới để chứng minh). Vì vậy, có cách nào để truy cập thông tin này?

Tôi muốn có thể tìm và vận hành trên các đối tượng trong ngữ cảnh của cơ sở dữ liệu của người gọi, mặc dù mã thực thi không nằm trong cùng một cơ sở dữ liệu. Ví dụ:

use SomeDB
EXEC util.dbo.frobulate_table 'my_table'

Tôi biết tôi có thể làm

EXEC util.dbo.frobulate_table 'SomeDB.dbo.my_table'

Nhưng tôi thực sự tò mò nếu có thể truy vấn ngăn xếp cuộc gọi theo cách này.

Cập nhật / ghi chú

Tôi đã đọc và tải mã từ blog của Gabriel McAdams . Điều này cung cấp một bản ghi ID thủ tục gọi lên và xuống ngăn xếp nhưng vẫn cho rằng mọi thứ đều nằm trong cùng một cơ sở dữ liệu.

Bằng chứng SQL Server ghi nhớ bối cảnh DB lên và xuống ngăn xếp cuộc gọi

Ví dụ: Trên máy chủ dev có cơ sở dữ liệu TestDB1 và ​​TestDB2

use TestDB1
GO
CREATE FUNCTION dbo.ECHO_DB_NAME() RETURNS nvarchar(128) BEGIN RETURN DB_NAME() END
GO

use TestDB2
GO
CREATE PROCEDURE dbo.ECHO_STACK AS 
BEGIN
    DECLARE @name nvarchar(128)
    SET @name = DB_NAME()
    PRINT 'Before, DB_NAME inside dbo.ECHO_STACK : ' + @name
    SET @name = TestDB1.dbo.ECHO_DB_NAME()        
    PRINT 'TestDB1.dbo.ECHO_DB_NAME returned     : ' + @name
    SET @name = DB_NAME()
    PRINT 'After, DB_NAME inside dbo.ECHO_STACK  : ' + @name
END
GO

use master
SELECT DB_NAME()  -- Returns 'master'
EXEC TestDB2.dbo.ECHO_STACK 

Bản in ECHO_STACK Proc:

Before, DB_NAME inside dbo.ECHO_STACK : TestDB2
TestDB1.dbo.ECHO_DB_NAME returned     : TestDB1
After, DB_NAME inside dbo.ECHO_STACK  : TestDB2

Nó có thể thông qua các sự kiện mở rộng nhưng chỉ là một sự mới lạ thực sự. Không phải cái gì cho sử dụng sản xuất nghiêm trọng. Ngay cả khi bạn biết tên cơ sở dữ liệu, bạn sẽ sử dụng nó như thế nào? Có tất cả mọi thứ trong sql năng động với một USE xyz;trước nó?
Martin Smith

Thành thật mà nói tôi không thể nói rằng tôi có một trường hợp vững chắc về lý do tại sao điều này lại cần thiết . Tôi thấy nó rất thú vị và nếu tôi làm con số nó ra, tôi sẽ đặt nó trong hai procs ít tiện dụng tôi sử dụng trong cơ sở dữ liệu sandbox dev của tôi: Một mà được tên đầy đủ của một đối tượng nhất định đoạn nhận ngắn của tên (ví dụ như trong ví dụ đầu tiên của tôi trong câu hỏi) và một ví dụ khác giết chết các đối tượng bằng cách sử dụng hàm khác để lấy tên đầy đủ và cũng sử dụng loại đối tượng được xác định để tạo DROPcâu lệnh.
Joshua Honig

@QueryKiwi Câu hỏi cập nhật tương ứng. Cảm ơn câu trả lời khác, quá. Tôi đã có một loạt các hàm CLR để thao tác chuỗi, vì vậy đây sẽ là bước tiếp theo tự nhiên đối với tôi.
Joshua Honig

Câu trả lời:


4

Bạn không thể thực hiện điều này với các chức năng trong cơ sở dữ liệu tiện ích. Tuy nhiên, bạn có thể tạo các thủ tục tiện ích trong cơ sở dữ liệu chủ, đánh dấu chúng là các đối tượng hệ thống và gọi chúng từ ngữ cảnh của bất kỳ cơ sở dữ liệu nào trên hệ thống của bạn. Một bài viết với một ví dụ tốt có thể được tìm thấy tại vị trí này .


Đây là tiểu thuyết nhưng hơi nguy hiểm. Thật dễ dàng để mất theo dõi các cấu hình máy chủ tùy chỉnh như thế này khi bạn di chuyển sang các môi trường khác nhau (ví dụ: máy chủ mới hoặc phiên bản SQL Server mới).
Riley Major
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.