набор результатов на основе успеха или неудачи

У меня есть хранимая процедура, которая возвращает два набора результатов в зависимости от успеха или неудачи.

Набор результатов успешного выполнения SP: name, id ,error, desc
Набор результатов сбоя SP: error, desc

Я использую следующий запрос, чтобы получить результат хранимой процедуры. Он возвращает 0 в случае успеха и -1 в случае неудачи.

declare @ret int

DECLARE @tmp TABLE (
     name  char(70),
     id    int,
     error char(2),
     desc  varchar(30)
)

insert into @tmp
EXEC @ret  = sptest '100','King'

select @ret

select * from @tmp

Если SP выполнен успешно, четыре поля вставляются во временную таблицу, поскольку столбец совпадает. Но в случае сбоя набор результатов sp имеет только ошибку и описание, которые не совпадают ни с одним из столбцов в таблице temp.... Я не могу изменить Sp, поэтому мне нужно что-то сделать (не уверен) в временную таблицу для обработки как неудач, так и успехов.


person Community    schedule 12.04.2009    source источник


Ответы (4)


Вы не можете вернуть 2 разных набора записей и загрузить одну и ту же временную таблицу. Ни один из них не может попытаться заполнить 2 разных таблицы.

Есть 2 варианта.

  1. Измените сохраненный процесс

    • All 4 columns are returned in all conditions
    • Столбцы 1-й пары (имя, идентификатор) имеют значение NULL при ошибке
    • 2-я пара (ошибка, описание) равна NULL в случае успеха
  2. Если вы используете SQL Server 2005, используйте TRY/CATCH, чтобы разделить пути успешного и неудачного выполнения кода. Приведенный ниже код основан на использовании новой обработки ошибок для передачи обратно набора результатов ошибки через exception/RAISERROR.

Пример:

CREATE PROC sptest
AS
DECLARE @errmsg varchar(2000)

BEGIN TRY
   do stuff
   SELECT col1, col2, col3, col4 FROM table etc
   --do more stuff
END TRY
BEGIN CATCH
   SELECT @errmsg = ERROR_MESSAGE()
   RAISERROR ('Oops! %s', 16, 1, @errmsg)
END CATCH
GO

DECLARE @tmp TABLE ( name CHAR(70), id INT, error char(2), desc varchar(30)

BEGIN TRY
    insert into @tmp
    EXEC sptest '100','King'
    select * from @tmp
END TRY
BEGIN CATCH
   PRINT ERROR_MESSAGE()
END CATCH
person gbn    schedule 12.04.2009

Моя вина!! Был слишком быстр в ответе. Вам нужно только ориентироваться на возвращаемое значение, поэтому построение логики против него намного лучше.

Если вы все еще хотите использовать временную таблицу, то вызов sptest дважды может быть способом справиться с этим (хотя и не оптимальным), один раз, чтобы получить возвращаемое значение и на его основе иметь 2 разные временные таблицы, которые вы заполняете (один будет с 4 полями, другой только с 2 полями).

declare @ret int

DECLARE @tmp TABLE (name CHAR(70), id INT, error char(2), desc varchar(30))
DECLARE @tmperror TABLE (error char(2), desc varchar(30))


EXEC @ret = sptest '100','King'

IF @ret != 0
BEGIN
  INSERT INTO @tmperror
  EXEC sptest '100','King';
  SELECT * FROM @tmperror;
END
ELSE
BEGIN
  INSERT INTO @tmp
  EXEC sptest '100','King';
  SELECT * FROM @tmp;
END

Имейте в виду, что это решение не является оптимальным.

person Dimi Takis    schedule 12.04.2009

Попробуйте изменить определение таблицы, чтобы первые два столбца были нулевыми:

DECLARE @tmp TABLE (
 name  char(70) null,
 id    int null,
 error char(2),
 desc  varchar(30)

)

Надеюсь это поможет,

Билл

person V'rasana Oannes    schedule 23.05.2009

Вы не можете сделать это одним звонком. Вам нужно будет вызвать его один раз, либо получив статус возврата, а затем переходя в зависимости от статуса к команде INSERT..EXEC, которая будет работать для количества столбцов, которые будут возвращены, или вызвать ее один раз, при условии успеха, с помощью TRY. .CATCH, а затем в Catch снова вызовите его, предполагая, что он не сработает (именно так он попал в CATCH).

Еще лучше было бы либо переписать хранимую процедуру так, чтобы она возвращала согласованный набор столбцов, либо написать собственную хранимую процедуру, функцию с табличным значением или запрос, извлекая код из этой хранимой процедуры и адаптируя его для вашего использования. . Это правильный ответ в SQL.

person RBarryYoung    schedule 28.05.2009