Daha ileri çağrı yığınından DB_ID içeriği


11

SQL Server'da, DB_IDbağlamdan çağrı yığınına kadar yukarıdan almak mümkün müdür ?

Amacım, dev sandbox veritabanında kısa veya parçalanmış adları verilen nesnelerin tam adlarını almayı kolay ve özlü hale getiren ve ayrıca aynı kısa adı kullanarak nesneleri silmeyi sağlayan bazı kullanışlı (ve kuşkusuz hacky) yardımcı işlevler oluşturmaktır. . Bu yardımcı program işlevleri tek bir yardımcı program veritabanında yer alır, ancak aynı sunucudaki diğer veritabanlarından çağrılır.

Testten görebildiğim kadarıyla:

  • ORIGINAL_DB_NAME()amaçlandığı gibi, bağlantı dizesinde ne varsa döndürür, geçerli bağlamı değil (ile ayarlanır USE [dbname]).
  • Bir işlevde çağrıldığında, o işlevin tanımlandığıDB_NAME() veritabanının adını döndürür . Bunu söylemenin başka bir yolu, bir işlev veya saklı yordam içindeki bağlamın tanımlandığı veritabanının

Motor arama yığını yukarı ve aşağı her veritabanı bağlamlarını izler biliyorum (kanıt için aşağıya bakın). Peki bu bilgilere erişmenin herhangi bir yolu var mı?

Ben yürütme kodu aynı veritabanında olmasa bile, bulmak ve arayan veritabanı bağlamında nesneler üzerinde çalışabilmek istiyorum. Örneğin:

use SomeDB
EXEC util.dbo.frobulate_table 'my_table'

Sadece yapabileceğimi biliyorum

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

Ancak, çağrı yığınını bu şekilde sorgulamanın mümkün olup olmadığını gerçekten merak ediyorum.

Güncelleme / not

Kodu Gabriel McAdams'ın blogundan okudum ve indirdim . Bu, yordam yukarı ve aşağı çağıran yordam kimliğinin bir kaydını sağlar, ancak yine de her şeyin aynı veritabanında olduğunu varsayar.

Kanıt SQL Server DB bağlamı yukarı ve aşağı çağrı yığını hatırlıyor

Örnek: TestDB1 ve TestDB2 veritabanlarına sahip bir geliştirici sunucusunda

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 proc yazdırır:

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

Bu, genişletilmiş olaylar yoluyla mümkün olabilir, ancak gerçekten bir yenilik olarak. Ciddi üretim kullanımı için bir şey değil. Veritabanı adını biliyor olsanız bile nasıl kullanırsınız? Her şeyden önce dinamik sql'de var mı USE xyz;?
Martin Smith

Dürüst olmak gerekirse, bunun neden gerekli olabileceğine dair sağlam bir vakam olduğunu söyleyemem . Çok ilginç buldum ve eğer yapmak rakam dışarı benim sandbox dev veritabanında kullanan iki kullanışlı küçük procs koyacağız: (örneğin olduğu gibi ismin en kısa tanınabilir parçasını verilen bir nesnenin tam adını alır One sorudaki ilk örneğim) ve tam adı almak için diğer işlevi kullanarak nesneleri öldüren ve ayrıca bir DROPifade oluşturmak için tanımlanmış nesnenin türünü kullanan başka bir örneğim).
Joshua Honig

@SQLKiwi Soru buna göre güncellendi. Diğer cevap için de teşekkürler. Zaten string manipülasyon için CLR fonksiyonları çeşitli var, bu yüzden bu benim için doğal bir sonraki adım olmalıdır.
Joshua Honig

Yanıtlar:


4

Bunu bir yardımcı program veritabanındaki işlevlerle gerçekleştiremezsiniz. Ancak ana veritabanında yardımcı program yordamları oluşturabilir, bunları sistem nesneleri olarak işaretleyebilir ve bunları sisteminizdeki herhangi bir veritabanının bağlamından çağırabilirsiniz. İyi bir örneği olan bir makale bu konumda bulunabilir .


Bu yeni ama biraz tehlikeli. Farklı ortamlara (örn. Yeni sunucu veya SQL Server'ın yeni sürümü) geçiş yaparken, bu gibi özel sunucu yapılandırmalarını izlemek kolaydır.
Riley Major
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.