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

时间:2015-06-24 07:34:57

标签: 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. 错误将我们发送到catch
  4. 表被截断,一切都正常继续
  5. 会发生什么:

    错误:已经有一个名为'#LookupLinks'在数据库中。

    我在这里做错了什么?

3 个答案:

答案 0 :(得分:3)

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

  

已经有一个名为'#LookupLinks'在数据库中。

见这个例子:

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

它产生错误说:

  

已经有一个名为'#temp'在数据库中。

解决方法是使用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语句,那么您的查询就可以正常运行。或者,如果您在GO之前添加BEGIN TRY

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服务器解析并验证整个批处理。 GO语句会将语句放入自己的批处理中,因此错误现在不会发生。

即使是CeOnSql的answer也能正常工作。

答案 1 :(得分:3)

我认为你真正想要实现的是:

queue

enter image description here

答案 2 :(得分:2)

TRY CATCH用于运行时错误。你得到的是编译时错误。在您的陈述之前添加PRINT 1,您将看到没有任何内容被执行。

print 1

    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    );
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