더 멀리있는 호출 스택의 DB_ID 컨텍스트


11

SQL Server DB_ID에서 더 많은 호출 스택에서 컨텍스트 를 가져올 수 있습니까?

저의 목표는 dev 샌드 박스 데이터베이스에 편리한 (그리고 명백하게 해키 된) 유틸리티 함수를 만들어서 짧거나 조각난 이름이 주어진 객체의 정규화 된 이름을 쉽고 간결하게 얻고 동일한 짧은 이름을 사용하여 객체를 삭제하는 것입니다. . 이러한 유틸리티 기능은 단일 유틸리티 데이터베이스에 있지만 동일한 서버의 다른 데이터베이스에서 호출됩니다.

테스트에서 볼 수있는 것에서 :

  • ORIGINAL_DB_NAME()의도 한대로 현재 컨텍스트가 아닌 연결 문자열에있는 모든 것을 반환합니다 (로 설정 USE [dbname]).
  • 함수에서 호출되면 해당 함수가 정의 된DB_NAME() 데이터베이스의 이름이 반환 됩니다 . 이것을 말하는 또 다른 방법은 함수 또는 저장 프로 시저 내부의 컨텍스트는 그것이 정의 된 데이터베이스의 컨텍스트라는 것입니다.

엔진이 각 데이터베이스 컨텍스트를 추적하고 호출 스택을 위아래로 추적한다는 것을 알고 있습니다 (아래 증거 참조). 이 정보에 액세스 할 수있는 방법이 있습니까?

실행 코드가 동일한 데이터베이스에 있지 않더라도 호출자의 데이터베이스 컨텍스트에서 객체를 찾고 조작 할 수 있기를 원합니다. 예를 들면 다음과 같습니다.

use SomeDB
EXEC util.dbo.frobulate_table 'my_table'

난 그냥 할 수 있다는 걸 알아

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

그러나이 방법으로 호출 스택을 쿼리 할 수 ​​있는지 궁금합니다.

업데이트 / 참고

Gabriel McAdams의 블로그 에서 코드를 읽고 다운로드했습니다 . 이것은 호출 프로 시저 ID의 스택 위아래로 레코드를 제공하지만 모든 것이 동일한 데이터베이스에 있다고 가정합니다.

SQL Server는 DB 컨텍스트 업 / 다운 콜 스택을 기억합니다.

예 : 데이터베이스가 TestDB1 및 TestDB2 인 dev 서버

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 

ECHO_STACK 프로세스는 다음을 인쇄합니다.

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

확장 된 이벤트를 통해 가능하지만 참신한 것만 가능합니다. 심각한 프로덕션 용도로는 사용할 수 없습니다. 데이터베이스 이름을 알고 있더라도 어떻게 사용하겠습니까? 동적 SQL의 모든 것이 USE xyz;앞에 있습니까?
Martin Smith

솔직히 나는 이것이 필요한 이유에 대한 확실한 사례가 있다고 말할 수 없다 . 나는 그것이 매우 흥미로운 발견하고 나는 경우 어떻게 그림 그것을 밖으로 난 내 샌드 박스 dev에 데이터베이스에 사용이 편리한 작은 발동에 넣어합니다 (예에서와 같이 이름의 짧은 인식 단편 주어진 객체의 전체 이름을 가져옵니다 하나 질문의 첫 번째 예)와 다른 함수를 사용하여 전체 이름을 가져 와서 객체를 죽이고 식별 된 객체의 유형을 사용하여 DROP명령문 을 생성하는 다른 객체도 있습니다.
Joshua Honig

@SQLKiwi 질문에 따라 업데이트되었습니다. 다른 답변도 감사합니다. 문자열 조작을위한 다양한 CLR 함수가 이미 있으므로이 단계는 당연히 다음 단계입니다.
Joshua Honig

답변:


4

유틸리티 데이터베이스의 기능으로는이를 수행 할 수 없습니다. 그러나 마스터 데이터베이스에서 유틸리티 프로 시저를 작성하고이를 시스템 오브젝트로 표시 한 후 시스템의 모든 데이터베이스 컨텍스트에서 호출 할 수 있습니다. 이 위치에서 좋은 예를 가진 기사를 찾을 수 있습니다 .


이것은 참신하지만 조금 위험합니다. 다른 환경 (예 : 새 서버 또는 새 버전의 SQL Server)으로 마이그레이션 할 때 이와 같은 사용자 지정 서버 구성을 쉽게 잃을 수 있습니다.
라일리 메이저
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.