SQL-Server中,TSQL,try-catch块(SQL-Server, TSQL, TRY-

2019-10-19 11:34发布

我在使用的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块中的错误?

谢谢你的帮助

Purclot

Answer 1:

您需要封装测试条件在EXEC得到待处理的错误作为运行时间的问题。 然后,您需要完全限定对象的袭击,可能不存在,这样就可以尽量避免使用语句的数据库查询。 对于功能,如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


Answer 2:

一些健谈的意见后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必须重新思考他如何能完成任务。



文章来源: SQL-Server, TSQL, TRY-CATCH block