2014-03-05 59 views
1

我遇到了try/catch錯誤處理問題。 讓我們在我的(簡單)的代碼來看看:SQL-Server,TSQL,TRY-CATCH塊

BEGIN TRY 
print 'important' 
use myDB1; -- no problem, the myDB1 is in place... 
select * from dbo.Tab1; 
use myDB2; 
--here error, the myDB2 is not there, 
--but error handling doesn't jump into catch-block 

select * from dbo.Tab2; 
END TRY 
BEGIN CATCH 
    print 'myDB2 is not there' 
END CATCH 

我知道,我可以說:

select * from myDB2.dbo.Tab2而不改變爲MYDB2,但是當我需要檢查(例如..)如果表有一個標識

(((SELECT OBJECTPROPERTY(OBJECT_ID('myDB2.dbo.'+ @TableName), 'TableHasIdentity'))= 1) 

我必須從MYDB2運行它,否則我會得到一個錯誤的結果。 那麼如何捕捉catch-block中的錯誤呢?

感謝您的幫助

Purclot

+0

您是否試圖使用完全限定的名稱而不是更改數據庫上下文,如select * from myDB2.dbo.Tab2? – jean

+0

順便說一句,如果你想檢查數據庫和對象是否存在,爲什麼不從sys.sysdatabases和sys.sysobjects中選擇? – jean

+0

嗨,讓我, 正如我所說:我需要改變到數據庫(所以它不是一個解決方案:select * from myDB2.dbo.Tab2 ...)。 當我使用:if(存在(從master.dbo.sysdatabase選擇其中[名稱] ='myDB2')1使用myDB2,我會得到一個錯誤 – Purclot

回答

4

您需要將測試條件封裝在EXEC中才能將錯誤視爲運行時問題。然後,您需要完全限定那些遇到可能不存在的數據庫的查詢的對象,以便避免使用USE語句。對於需要本地上下文的函數(如OBJECTPROPERTY),可以使用sp_executesql在不同的數據庫上下文中運行查詢並返回可用的結果。

DECLARE @TableName SYSNAME, 
     @SQL NVARCHAR(MAX), 
     @Result BIT 

BEGIN TRY 

    USE [master]; 
    SELECT TOP 1 * FROM sys.objects 

    SET @TableName = N'sysjobhistory' 
    SET @Result = 0 
    SET @SQL = N'USE [msdb]; DECLARE @Result BIT; 
       SET @TempResult = OBJECTPROPERTY(OBJECT_ID(N''' + @TableName + 
       N'''), ''TableHasIdentity'')' 

    EXEC sp_executesql @SQL, 
         N'@TempResult BIT OUTPUT', 
         @TempResult = @Result OUTPUT 

    SELECT @Result AS [ResultThatCanBeUsedLocally] 

    EXEC('USE [NotHere];') 

    SELECT TOP 1 * FROM NotHere.sys.objects 

END TRY 
BEGIN CATCH 

    PRINT 'Error!!' 
    PRINT ERROR_MESSAGE() 

END CATCH 
+0

謝謝,這就是我一直在尋找的答案! 謝謝,Purclot – Purclot

1

一些健談的意見OP後只需要知道,如果表中有一個身份。 您可以在之後給定數據庫

SELECT TABLE_NAME 
FROM MyDB2.INFORMATION_SCHEMA.TABLES 
WHERE Table_NAME NOT IN (
    SELECT c.TABLE_NAME 
    FROM MyDB2.INFORMATION_SCHEMA.COLUMNS c 
    INNER JOIN MyDB2.sys.identity_columns ic ON c.COLUMN_NAME = ic.NAME 
) 
AND TABLE_TYPE = 'BASE TABLE' 

編輯

用它列出的表沒有身份證一些聊天和挖掘,我發現OP真的想切換DB一個try catch塊內。但是這個對象的存在是在分析時檢查的,而且只有在運行時錯誤的情況下才會嘗試工作。 另外對象缺失錯誤似乎沒有得到必要的嚴重程度被try catch塊捕獲(甚至使用完全合格的名稱生病不行)

OP必須重新考慮他如何完成任務。

+0

嗨,讓, 恐怕我們只是偏離主要問題的優點: 如何獲得catch-block的工作方式,當我只想切換到一個不存在的數據庫時 - 出於何種原因。 HasIdentity屬性的問題僅僅是一個例子。 Purclot – Purclot

+0

對不起,我的觀點是避免在try catch內切換上下文。起初,我找不到有關該特定情況的任何信息。如果你真的想去,讓我們多挖一點 – jean

+0

我想我發現了這個問題。當我嘗試解析你的代碼時會引發錯誤。這意味着數據庫不存在不適合在解析時處理,而不是試圖捕獲的運行時。 – jean