TRY...CATCH 似乎不起作用
TRY...CATCH doesn't seem to work
我有以下代码,只是为了确保临时 table 不存在。如果 table 存在,我想截断它。
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
我想要它做什么:
- 临时table已创建
- 再次尝试创建
- 错误让我们陷入困境
- table 被截断,一切照常进行
会发生什么:
错误:数据库中已经有一个名为“#LookupLinks”的对象。
我做错了什么?
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
这是因为 SQL 服务器解析并验证整个批次。所以在解析第二个 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 服务器解析并验证了整个批次。 GO
语句会将语句放入它们自己的批次中,因此错误现在不会发生。
即使是 CeOnSql 的 也能正常工作。
我认为你真正想要实现的是:
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL --Table already exists
BEGIN
TRUNCATE TABLE #LookupLinks
PRINT N'#LookupLinks already existed and was truncated.';
END
ELSE
BEGIN
CREATE TABLE #LookupLinks(
[SyncID] uniqueidentifier,
[Name] nvarchar(50),
[SQLTable] nvarchar(50)
)
END
我有以下代码,只是为了确保临时 table 不存在。如果 table 存在,我想截断它。
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
我想要它做什么:
- 临时table已创建
- 再次尝试创建
- 错误让我们陷入困境
- table 被截断,一切照常进行
会发生什么:
错误:数据库中已经有一个名为“#LookupLinks”的对象。
我做错了什么?
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
这是因为 SQL 服务器解析并验证整个批次。所以在解析第二个 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 服务器解析并验证了整个批次。 GO
语句会将语句放入它们自己的批次中,因此错误现在不会发生。
即使是 CeOnSql 的
我认为你真正想要实现的是:
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL --Table already exists
BEGIN
TRUNCATE TABLE #LookupLinks
PRINT N'#LookupLinks already existed and was truncated.';
END
ELSE
BEGIN
CREATE TABLE #LookupLinks(
[SyncID] uniqueidentifier,
[Name] nvarchar(50),
[SQLTable] nvarchar(50)
)
END