【问题标题】:SQL try-catch statement not handling error (SQL Server 2008)SQL try-catch 语句未处理错误 (SQL Server 2008)
【发布时间】:2011-09-02 16:43:55
【问题描述】:

我正在尝试使用 try-catch 捕获 SQL 查询(而不是存储过程)中的错误。

由于某种原因,这没有处理我的错误,我仍然得到:

消息 213,第 16 级,状态 1,第 29 行 列名或提供的值的数量与表定义不匹配。

有什么帮助吗?

begin try
create table #temp_hierarchy
    (temp_gl_number varchar(50)
    ,temp_store_location varchar(255)
    ,temp_store_key varchar(50)
    ,temp_serving_dc varchar(50)
    ,temp_exploris_db varchar(50)
    ,temp_dc_account varchar(50)
    ,temp_store_type varchar(50)
    ,temp_dvp_ops varchar(50)
    ,temp_rdo varchar(50)
    ,temp_team varchar(50)
    ,temp_dvp_sales varchar(50)
    ,temp_rds varchar(50)
    ,temp_closed varchar(50)
    ,temp_open_date varchar(50)
    ,temp_close_date varchar(50)
    ,temp_store_manager varchar(250)
    ,temp_sales_teammate varchar(250)
    ,temp_machine_shop varchar(50)
    ,temp_address varchar(250)
    ,temp_city varchar(50)
    ,temp_state varchar(50)
    ,temp_zip varchar(50)
    ,temp_phone varchar(50)
    ,temp_fax varchar(50))

insert into #temp_hierarchy
select * 
from OPENROWSET('Microsoft.ACE.OLEDB.12.0', 
    'Excel 12.0;Database=C:\SQL_DATA_REPORTING\8-31-11 Store Hierarchy.xlsx;HDR=YES', 
    'SELECT * FROM [Master List$]');

truncate table tbl_hierarchy

insert into tbl_hierarchy
select *
from #temp_hierarchy
where temp_gl_number is not null
    and temp_gl_number <> 'GLID'

select @@ROWCOUNT + ' Records sucessfully imported'

end try

begin catch
select 'ERROR: ' & ERROR_NUMBER() + '. Unable to import records, existing data was not lost.' 
end catch;
go

【问题讨论】:

  • 我的猜测是 tbl_hierarchy 和 #temp_hierarchy 有不同的列定义。
  • 您可以使用select * INTO T from OPENROWSET... 查看用于临时表的正确表定义。

标签: sql sql-server-2008 error-handling try-catch


【解决方案1】:

您有一个无法在 try-catch 中捕获的编译时错误。

BooksOnline:

编译和语句级重新编译错误

TRY…CATCH 不会处理两种类型的错误,如果 错误发生在与 TRY…CATCH 相同的执行级别 构造:

  1. 编译错误,例如阻止批处理的语法错误 正在执行。

  2. 语句级重新编译过程中发生的错误,例如对象 由于 deferred 导致编译后发生的名称解析错误 名称解析。

【讨论】:

  • 这是有道理的。那我怎么能捕获这个错误呢?
  • @ChandlerPelhams 在那篇 BOL 文章的后面,它提到使用动态 sql 或将查询包装在存储过程中。 try-catch 会捕获它。
【解决方案2】:

您不应该使用 SELECT * 插入 - 永远!这是一种不好的做法,它会导致您发布的错误。在您的选择和查询的 INSERT 部分中定义列。

【讨论】:

  • 我的问题是关于为什么错误没有被捕获,而不是错误发生的事实。
  • 我和@ChandlerPelhams 有同样的问题;我期待我的表定义发生变化,并且我希望我的 catch 块在发生这种情况时执行。当我第一次制作 SP 时,它起作用了。但是,一旦我的表定义的 TRY Block 版本被更改 - SP 甚至不会运行 b/c 的编译错误。
  • 永远不要说永远...errrr...或者永远。我目前正在研究一种方法来检测我们从中导入但不控制的源表的更改。我想知道何时添加列,但我们无法在远程服务器上查询 INFORMATION_SCHEMA。为了以一种全面的方式检测这些变化,我复制了我的目标表结构,然后使用INSERT INTO DestTable SELECT * FROM SourceTable 并捕获错误,以便我可以向正确的团队发送电子邮件通知。即使是最讨厌的语法也总有一个用例……即使是 *hard gulp* 可爱的 GOTO 关键字。 xD
【解决方案3】:

HLGEM - 我一直故意使用 insert dbo.mytable select*from dbo.mySrcTbl,我这样做是为了捕获架构更改,并捕获、记录、发送电子邮件。

我无法控制我的世界中的所有表格,而且数据沙皇经常在非工作时间睡觉。

【讨论】:

  • 100% 就在这里。正是出于这个原因,我找到了这篇文章的方法。有些人只想眼睁睁地看着世界燃烧,其中许多人显然成为了“数据沙皇”。 xD
【解决方案4】:

错误是由以下语句引起的

select @@ROWCOUNT + ' Records sucessfully imported' 

@@ROWCOUNT 是整数,所以先转换成字符串。

select convert(varchar(10),@@ROWCOUNT) + ' Records sucessfully imported' 

编辑:这是一个错误,但似乎这个错误会被捕获,所以你必须有另一个导致问题的编译时错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2023-03-21
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多