2013-04-12 5 views
5

У меня есть несколько различных баз данных на одном SQL Server 2008 R2. Для аргументов давайте назовем их DB_A, DB_B и DB_C. Меня попросили разработать как хранимую процедуру, которая будет работать на DB_A. Этот сохраненный proc будет использоваться для удаления и создания индексов, а также для хранения дополнительной информации об индексе в таблице на DB_A. Когда этот хранимый proc вызывается из DB_C или DB_C, он сможет отбрасывать и создавать индексы в вызывающей базе данных, но хранить дополнительную информацию об индексе в таблице на DB_A.Как вернуть имя удаленной базы данных, которое вызывает хранимую процедуру в другой базе данных?

Вот что я хотел бы сделать: я хотел бы, чтобы хранимая процедура имела возможность получить имя вызывающей базы данных БЕЗ необходимости запрашивать имя базы данных в качестве параметра.

Вот простой пример:

USE [DB_A] 

CREATE PROC sp_WhatDatabaseAmICallingFrom 
AS 
BEGIN 
     DECLARE @calling_db NVARCHAR(128) 
     SET @calling_db = DB_NAME() 
     PRINT 'calling database: ' + @calling_db 
END 

Когда я выполнить хранимую процедуру в DB_A ...

EXEC sp_WhatDatabaseAmICallingFrom 

... он возвращает: "призывающие базы данных: DB_A"

Когда я выполняю хранимую процедуру в DB_B ...

USE DB_B 
GO 

EXEC DB_A.dbo.sp_WhatDatabaseAmICallingFrom 

... он возвращает: «вызов базы данных: DB_A».

После ознакомления с различными функциями метаданных SQL Server это именно то, что он должен делать. Но я хотел бы изменить код так, чтобы он задавал @calling_db имя вызывающей базы данных, так что мой пример хранимой процедуры будет печатать: «вызывающая база данных: DB_B».

К сожалению, я не могу найти никаких функций метаданных, которые могут это сделать. Любые идеи о том, как это можно сделать?

+0

Очень интересный вопрос.Из любопытства есть причина, по которой вы не хотите, чтобы процесс, вызывающий sproc, указывал dbname как параметр (кроме необходимости поддерживать параметр и предоставлять его)? Одна мысль, если нет прямого способа сделать это, заключается в том, чтобы сделать параметр необязательным @CallingDB NVARCHAR (128) = NULL и проверить, имеет ли значение значение null. Если это так, по умолчанию используется DB_NAME(). Конечно, это означает, что вызов из других баз данных должен будет содержать имя ... –

+0

Единственная реальная причина, по которой я не хочу использовать параметр, я думаю, что должен быть способ сделать это, и я ненавижу ходить прочь от такой задачи, не найдя решения. –

+0

FYI, тот же вопрос был [задан на сайте DBA] (http://dba.stackexchange.com/questions/30310/db-id-context-from-farther-up-call-stack), хотя он hasn ' ответили. Предложенные предложения состояли в том, чтобы использовать расширенные события, SQL CLR или поддерживать собственный стек вызовов, используя ['CONTEXT_INFO'] (http://msdn.microsoft.com/en-us/library/ms187768.aspx). – Pondlife

ответ

4

Чтобы сделать запуск SP в контексте текущего соединения, вам необходимо создать свой SP на базе masterи сделать его системным объектом.

USE MASTER 
GO 

CREATE PROC sp_WhatDatabaseAmICallingFrom 
AS 
BEGIN 
     DECLARE @calling_db NVARCHAR(128) 
     SET @calling_db = DB_NAME() 
     PRINT 'calling database: ' + @calling_db 
END 
GO 

EXEC sp_ms_marksystemobject 'sp_WhatDatabaseAmICallingFrom' 
GO 

Проверьте, как это работает:

USE [DB_A] 
GO 

EXEC sp_WhatDatabaseAmICallingFrom 
GO 
3

Я знаю, что эта нить довольно старый, но я нашел то, что, по крайней мере мне помогли.

Если вы используете DB_A и вызове хранимой процедуры в DB_B как:

USE DB_A 
EXEC db_b.dbo.sproc 

Единственный способ, который я нашел, чтобы получить «вызова базы данных» идентификатор для запуска отборное против sys.dm_tran_locks внутри хранимую процедуру. request_session_id должен быть вашим spid, resource_type должен быть DATABASE, а request_owner_type должен быть SHARED_TRANSACTION_WORKSPACE. Такая совместная блокировка всегда существует в базе данных для каждого подключенного сеанса. Запрос будет что-то вроде:

SELECT resource_database_id FROM sys.dm_tran_locks WHERE request_session_id = @@SPID and resource_type = 'DATABASE' and request_owner_type = 'SHARED_TRANSACTION_WORKSPACE' 

Хотя это требует выполняющего пользователя должны иметь по крайней мере разрешение на просмотр SERVER STATE на сервере. В моем случае это не было проблемой, хотя ..

 Смежные вопросы

  • Нет связанных вопросов^_^