【问题标题】:Is there a way to make SELECT that fails not throw inside a TRY/CATCH?有没有办法让失败的 SELECT 不会扔到 TRY/CATCH 中?
【发布时间】:2012-07-17 21:07:54
【问题描述】:

例如:

CREATE PROCEDURE dbo.MyProc
AS
BEGIN
  SET NOCOUNT ON;
  BEGIN TRY
    ...
    DECLARE @Id INT;

    -- I don't want the following line to throw and abort processing. 
    -- I just want @Id to remain NULL. I can add a nested TRY/CATCH, but is there
    -- a better way?
    SET @Id=(SELECT Id FROM MyTable WHERE ...); 
    ...
  END TRY
  BEGIN CATCH
    ...
  END CATCH;
END;

更新:澄清一下,如果返回多行,我希望 @Id 保持 NULL。

【问题讨论】:

  • 您希望该选择出现什么类型的错误?你能避免前 1 名的预期错误吗?如果没有匹配项,@ID 将保持为空。
  • 如果返回多个 Id,我希望 @Id 保持 NULL,根据 Jose 的第二个答案...

标签: sql-server-2008 tsql sql-server-2008-r2


【解决方案1】:

我会做这样的事情来避免多行错误:

SELECT top 1 @Id = Id FROM MyTable WHERE ...

或者这个

SELECT @Id = Id FROM MyTable WHERE ...
if @@rowcount > 1
   set @id = null

当有多行时,最后一部分会将@Id 设置为空。

【讨论】:

  • 但听起来如果有多行,OP希望它为空,而不仅仅是其中一个值
  • 我认为第二个查询是 OP 正在寻找的。第一个不符合他的要求“我只是想让@Id 保持为NULL。”
  • 何塞,你的 +1 更容易理解,通常哪个更重要!
【解决方案2】:

试试这个:

select @id = (select max(id) from MyTable Where <YOUR CONDITION> Having count(1) = 1)

这将返回单行,如果有多个匹配则不返回任何行。

【讨论】:

  • 我认为 Ben 的解决方案非常优雅,其性能类似于 if @@rowcount。
【解决方案3】:

很确定这不会抛出:

SELECT @Id = Id FROM MyTable WHERE ...

【讨论】:

  • 但这只会存储最后一个值,我认为这不是 OP 想要的
  • @RGI - 你在说什么? @ Stefan H - 存储最后一个值?
  • @RGI 如果子查询返回多个结果,OP 帖子会抛出错误,而这个不会
  • 我认为 OP 担心他们的查询会返回多个结果,因此会在他们拥有的代码中引发错误。如果是这种情况,您的 sql 将只存储最后一个值,而不是让 OP 知道返回了多个结果(这是他们希望它为空的时候)
  • 我明白了,我不明白这是他想要的(他没有说明)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-29
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
相关资源
最近更新 更多