Хранимая процедура T-SQL — определение, предоставляется ли параметр как ВЫХОД

Рассмотрим следующий фрагмент кода T-SQL:

CREATE PROC dbo.SquareNum(@i INT OUTPUT)
AS
BEGIN
    SET @i = @i * @i
    --SELECT @i
END
GO

DECLARE @a INT = 3, @b INT = 5
EXEC dbo.SquareNum @a OUTPUT
EXEC dbo.SquareNum @b
SELECT @a AS ASQUARE, @b AS BSQUARE
GO
DROP PROC dbo.SquareNum

Набор результатов:

ASQUARE     BSQUARE
----------- -----------
9           5

Как видно, @b не возведено в квадрат, т.к. оно не передавалось в качестве выходного параметра (при передаче в параметре нет квалификатора OUTPUT).

Я хотел бы знать, есть ли способ проверить в теле хранимой процедуры (в данном случае тело dbo.SquareNum), чтобы увидеть, действительно ли параметр был передан как параметр OUTPUT?


person M. Rashid    schedule 18.04.2016    source источник
comment
Я не думаю, что вы можете сделать это.   -  person Giorgi Nakeuri    schedule 18.04.2016
comment
Я согласен с Джорджи - не думайте, что вы можете проверить это во время выполнения. Если вы беспокоитесь о его применении, вы можете сделать это как скалярную функцию, которая возвращает новое значение вместо использования процедуры.   -  person David Godwin    schedule 26.04.2016
comment
Интересный вопрос. У меня нет ответа, но из любопытства, зачем вам это? Интересно, есть ли основная проблема, которую можно было бы решить по-другому.   -  person Joe Farrell    schedule 12.07.2016


Ответы (4)


На самом деле, есть очень простой способ!

Сделайте параметр необязательным, установив значение по умолчанию (@Qty AS Money = 0 Ниже)

Затем передайте значение, ДРУГОЕ, ЧЕМ ПО УМОЛЧАНИЮ, при вызове процедуры. Затем немедленно проверьте значение, и если оно отличается от значения по умолчанию, вы знаете, что переменная была передана.

Create Procedure MyProcedure(@PN AS NVarchar(50), @Rev AS NVarchar(5), @Qty AS Money = 0 OUTPUT) AS BEGIN DECLARE @QtyPassed AS Bit = 0 IF @Qty <> 0 SET @QtyPassed = 1

Конечно, это означает, что переменная не может использоваться ни для чего, кроме OUTPUT, если у вас нет значения по умолчанию, которое, как вы знаете, никогда не будет использоваться в качестве значения INPUT.

person KimM    schedule 13.08.2018
comment
Это позволяет вам определить, был ли передан параметр вообще, но не позволяет определить, был ли он передан, но не как OUTPUT - и это именно то, о чем беспокоился вопрос. Единственное спасение заключается в том, что в тех случаях, когда параметр только используется для OUTPUT (т. е. это не входной параметр), вызывающие абоненты, скорее всего, никогда не введут значение, что позволит вам проверить NULL. . К сожалению, вопрос касается параметра входа-выхода (хотя это могло быть просто для иллюстрации). - person Jeroen Mostert; 13.08.2018

Вы можете сделать это, запросив системные представления:

select 
    p.name as proc_name,
    par.name as parameter_name,
    par.is_output
from sys.procedures p
inner join sys.parameters par on par.object_id=p.object_id
where p.name = 'SquareNum'

или проверьте в Management Studio в дереве базы данных: [база данных] -> Программируемость -> Хранимые процедуры -> [процедура] -> Параметры

person Piotr Lasota    schedule 18.04.2016
comment
Я думаю, что вопрос в том, как определить, использовалось ли ключевое слово OUTPUT в коде, вызывающем хранимую процедуру, а не в определении хранимой процедуры. - person Ed Harper; 18.04.2016

Может быть, я ошибаюсь, но я не верю, что это возможно. OUTPUT является частью определения хранимой процедуры, поэтому вы должны знать, является ли параметр OUTPUT или нет. Нет возможности установить его динамически, поэтому я думаю, что бессмысленно определять по коду, когда параметр выводится или нет, потому что вы это уже знаете.

Если вы пытаетесь написать динамический код, ответ Петра Ласоты должен привести вас к правильному способу понимания, когда параметр является выходным.

person Frederico Almeida    schedule 12.07.2016

Используйте следующий запрос, чтобы получить имя всех параметров и проверить, является ли он выходным параметром:

select name, is_output from sys.parameters
person PrinceKayastha    schedule 12.06.2017