所以,在這一點上的小故事:如何將1個包含特定表的數據庫名稱設置爲變量?
我有一個冗長的查詢,我經常使用我的作業,利用sp_MSForEachDB存儲過程。該查詢創建一個臨時表,然後通過並搜索sys.tables,並且如果數據庫有一個名爲T_Study
的表,它將運行查詢並將這些結果拖到臨時表中。
我現在試圖做的是從另一個數據庫中加入另一個表,並且此數據庫是不同的類型。這些數據庫全部由存在T_BatchStores
區分。所有具有T_BatchStores
表的數據庫也將有一個表dbo.T_TSyntax
,這是我需要加入的表。基本上,我試圖建立一個通用查詢,我可以在任何包含這個軟件的服務器上運行,並且我有這幾個通用表,但數據庫本身的名稱會有所不同。
所以我想要做的是什麼,我的查詢填充我的臨時表,添加以下內容:我開始和結束中
JOIN '[email protected]+'.dbo.T_TSyntax
,然後我的條款等。請記住,這個連接發生子句和那sp_MSforEachDb
將在此上運行。
我想@MEDDB
只是一個隨機選擇的SQL實例上的任何數據庫的名稱,其中包含一個T_BatchStores
表 - 無所謂名稱 - 我只是不想在每次運行時修改查詢它。
如何使用我的DECLARE @MEDDB
和SET/SELECT @MEDDB
來滿足這些要求?
此外,在一些閱讀中,我讀到應該使用SYSNAME
作爲數據類型,但我也知道NVARCHAR
可以工作 - 但我只想給出一個理想的提示。
我曾嘗試以下:
DECLARE @MEDDB SYSNAME
SET @MEDDB = (SELECT TOP 1 name FROM sys.databases WHERE EXISTS (SELECT name FROM sys.tables WHERE name = '''T_BATCHSTORES'''))
SELECT @MEDDB
但這返回1行與NULL
值。我非常喜歡SQL,所以任何幫助將不勝感激!
注意:我目前只使用Microsoft SQL Server 2008和2012。
謝謝!
好的,在大量修改查詢後,這些名稱實際上與我們實際的表結構並不完全相同,下面是我正在使用的查詢的細化版本,以便您能夠看到我要去爲:
/* Add or change variables as needed and comment back in WHERE statements in Insert section as needed.
You do not need to delete any variables in this section, even if you do not need them.
Simply comment in or out relevant data in the WHERE clause in Section 4. */
/* Section 1: Declaring variables. */
DECLARE @STUID NVARCHAR (65)
DECLARE @IMUID NVARCHAR (200)
DECLARE @ACCN NVARCHAR (100)
DECLARE @MEDDB NVARCHAR (255)
/* Section 2: Assigning values to variables such as an Image file's UID. */
SET @STUID = 'enterSTUID'
SET @IMUID = 'enterIMUIDhere'
SET @ACCN = 'enterACCNhere'
SET @MEDDB = (SELECT TOP 1 name FROM sys.databases WHERE [name] LIKE '%med%'
AND [name] NOT LIKE '%audit%')
/* Section 3: Creating our temporary table to dump our results. */
IF OBJECT_ID('tempdb.dbo.#tempBatchResultsD6') IS NULL
BEGIN
CREATE TABLE #tempBatchResultsD6
(
Database_Name VARCHAR (200),
THING1 VARCHAR(100) NOT NULL,
THING2 VARCHAR(200) NOT NULL,
THING3 DATETIME NOT NULL,
TSyntaxUID VARCHAR (66) NOT NULL,
TSyntaxDesc VARCHAR (128) NOT NULL
)
END
TRUNCATE TABLE #tempBatchResultsD6
/* Section 4: Query that will be used to populate the contents of the temporary table created above.
Utilizing the stored procedure "sp_MSForEachDb," this will search every database on the SQL instance.
Here, we are limiting our results to only searching specific databases by only returning results from databases that have a "T_Studies" table. */
DECLARE @Command NVARCHAR(MAX)
SET @Command = N'USE [?];
IF EXISTS (SELECT * FROM sys.tables WHERE [name] = ''T_Studies'')
BEGIN
INSERT #tempBatchResultsD6
SELECT
DB_Name() as Database_Name,
THING1,
THING2,
THING3,
TS.TSyntaxUID,
TS.TSyntaxDesc
FROM T_Studies ST WITH (nolock)
JOIN T_Patients PT WITH (nolock) ON ST.ST_PT_FOLDERID = PT.PT_FOLDERID
JOIN T_Series SE WITH (nolock) ON ST.ST_FOLDERID = SE.SE_ST_FOLDERID
JOIN T_Images IM WITH (nolock) ON SE.SE_FOLDERID = IM.IM_SE_FOLDERID
JOIN '[email protected]+'.dbo.T_TSyntaxes TS WITH (nolock) on IM.IM_TSyntaxID = TS.TSyntaxUID
WHERE ST.STUID = '''[email protected]+'''
--WHERE IM.IM_UID = '''[email protected]+'''
--WHERE ST.ST_ACCNNO = '''[email protected]+'''
END'
EXEC sp_MSForEachDb @Command
/* Section 5: Querying our temporary table to get our results. */
SELECT
Database_Name,
THING1,
THING2,
THING3,
TSyntaxUID,
TSyntaxDesc
FROM #tempBatchResultsD6
ORDER BY Database_Name
因此,大家可以看到,這是一個巨大的臨時表,將拉離,在他們有一個T_Studies表中的所有數據庫。它的實際形式非常龐大,但是這個比例顯着下降。
問題出現在第2節中,如果名稱包含單詞「Med」而不是「audit」,則使用@MEDDB選擇一個隨機數據庫名稱。這是有問題的,因爲它假定所有網站都有一致的命名 - 雖然建議這些名稱,但它們從來不是保證。
爲了保證一致性,我試圖用包含T_BatchStores表而不是WHERE [name]類似部分的系統上任何數據庫的名稱填充@MEDDB變量。
任何意見這個新的信息將不勝感激!
您不能使用變量作爲源表名稱。但是你可以使用IF-ELSE邏輯或者你可以使用動態SQL ... – Shnugo
你能澄清嗎?我可以使用SELECT @MEDDB =(SELECT name FROM sys.databases WHERE [name] LIKE'%med%' AND [name] NOT LIKE'%audit%')將我的變量設置爲替代,然後加入作品: JOIN'[email protected]+'.dbo.T_TSyntax ... 無法弄清楚爲什麼這是如此不同。 –