sql - TRY...CATCH 似乎不起作用

标签 sql sql-server error-handling sql-server-2012 try-catch

我有以下代码只是为了确保临时表不存在。如果表存在,我想截断它。

CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    ) --I create this just to test my try-catch

BEGIN TRY
    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    )
END TRY
BEGIN CATCH
    PRINT N'#LookupLinks already existed and was truncated.';
    TRUNCATE TABLE #LookupLinks
END CATCH

我想要这样做:

  1. 临时表已创建
  2. 尝试重新创建它
  3. 错误让我们陷入困境
  4. 表格被截断,一切照常进行

会发生什么:

错误:数据库中已经有一个名为“#LookupLinks”的对象。

我在这里做错了什么?

最佳答案

这是因为 SQL Server 会解析并验证整个批处理。因此,在解析第二个 CREATE TABLE 语句时,它会出错:

There is already an object named '#LookupLinks' in the database.

看这个例子:

IF 1 = 1 BEGIN
    CREATE TABLE #temp(col INT)
END
ELSE BEGIN
    CREATE TABLE #temp(col INT)
END

它会产生一个错误:

There is already an object named '#temp' in the database.

解决方法是使用Dynamic SQL

-- CREATE the table for testing
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL 
    DROP TABLE #LookupLinks 
CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    ) 


-- Final query
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL BEGIN
    TRUNCATE TABLE #LookupLinks
    PRINT N'#LookupLinks already existed and was truncated.'
END
ELSE BEGIN
    DECLARE @sql NVARCHAR(MAX) = ''
    SELECT @sql = '
        CREATE TABLE #LookupLinks(
            [SyncID] uniqueidentifier,
            [Name] nvarchar(50),
            [SQLTable] nvarchar(50)
        )'
    EXEC sp_executesql @sql
    PRINT N'#LookupLinks was created.'
END

如果您没有第一个 CREATE TABLE 语句,您的查询将正常工作。或者,如果您在 BEGIN TRY 之前放置一个 GO

IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL 
    DROP TABLE #LookupLinks -- DROP FIRST

CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    ) --I create this just to test my try-catch
GO
BEGIN TRY
    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    )
END TRY
BEGIN CATCH
    PRINT N'#LookupLinks already existed and was truncated.';
    TRUNCATE TABLE #LookupLinks
END CATCH

仍然是因为 SQL Server 解析并验证了整个批处理。 GO 语句会将语句放入它们自己的批处理中,因此现在不会发生错误。

甚至 CeOnSql 的 answer会正常工作的。

关于sql - TRY...CATCH 似乎不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31020467/

相关文章:

excel - Application.WorksheetFunction.VLookup 无匹配错误

error-handling - 字符串 io::Errors 是如何创建的

php - 你如何使 codeigniter 加入?

sql - 使用查询创建新列

mysql - SQL:Group By 记录不匹配

javascript - Node.js 如何从 MS Sql 服务器数据类型的 varbinary 转换为图像

c# - 无法将 DateTime 隐式转换为 Timespan

c# - 如何解决 Microsoft SQL Server。错误 233。提供商 : SSL Provider

sql - rails ActiveRecord find_by_sql 调用结果的列顺序

php - Joomla后端禁用我的组件中的错误报告