Как вызвать процедуру SQL Server с параметрами ввода и вывода? - PullRequest
3 голосов
/ 21 мая 2019

Я пытаюсь написать процедуру, которая возвращает значения на основе результата запроса select. Например, найти идентификатор пользователя, использовать имя и фамилию, чтобы найти идентификатор пользователя, и вернуть идентификатор в качестве параметра OUTPUT. Если найдено более одного пользователя или нет, установите значение возврата -1 и установите для параметра OUTPUT значение 0.

Я попробовал следующий код, но получаю сообщение об ошибке:

Необходимо объявить скалярную переменную "@intValue"

Я искал по интернету, но никто не решил мою проблему.

CREATE PROCEDURE GetIdOfUser
    (@f_name VARCHAR(50), 
     @l_name VARCHAR(50),
     @outValue INT OUTPUT)
AS
    DECLARE @intValue INT;

    SELECT @intValue = userID 
    FROM users
    WHERE firstName = @f_name AND lastName = @l_name

    IF @@rowcount > 1 -- more than one user?
    BEGIN
        SET @outValue = 0
        RETURN -1;
    END

    IF @@rowcount == 1
    BEGIN
        SET @outValue = @intValue;
    END



DECLARE @myretValue INT;

EXEC GetIdOfUser 'raj', 'ahuja', @myretValue;

SELECT @myretValue;

Я использую SQLfiddle [sqlfiddle.com] для изучения концепций SQL Server. Я совершенно новичок в создании процедур в SQL Server, поэтому любая помощь будет принята.

РЕДАКТИРОВАТЬ 1: Версия SQL Server 2017

РЕДАКТИРОВАТЬ 2: Схема и примеры данных, с которыми я работаю.

create table users
(
    userID int,
    firstName varchar(50),
    lastName varchar(50),
    title varchar(50)
);

insert into users(userID, firstName, lastName, title) 
values(501, 'natasha', 'ghosh', 'title1'),
      (502, 'raj', 'ahuja', 'title2'),
      (503, 'katy', 'perry', 'title3'),
      (504, 'john', 'cyrus', 'title4'),
      (505, 'anindita', 'pal', 'title5');

Ответы [ 3 ]

3 голосов
/ 21 мая 2019

Я бы немного упростил это.Нет необходимости заполнять несколько переменных здесь.Посмотрите, работает ли что-то немного проще, как это.

CREATE PROCEDURE GetIdOfUser
(
    @f_name VARCHAR(50), 
    @l_name VARCHAR(50),
    @outValue INT OUTPUT
)
AS
    SELECT @outValue = userID 
    FROM users
    WHERE firstName = @f_name 
        AND lastName = @l_name

    if @@rowcount > 1
        set @outValue = -1

GO

Вот как вы бы это использовали.

DECLARE @myretValue INT;

EXEC GetIdOfUser 'raj', 'ahuja', @myretValue OUTPUT;

SELECT @myretValue;

- РЕДАКТИРОВАТЬ -

С вашими новыми примерами данных я решил использовать специалиста по именам таблиц, поскольку вы опубликовали два разных имени.Процедура, которую я разместил здесь, работает отлично.

create table specialist(
userID int,
firstName varchar(50),
lastName varchar(50),
title varchar(50)
);
insert into specialist(userID, firstName, lastName, title) values(501, 'natasha', 'ghosh', 'title1');
insert into specialist(userID, firstName, lastName, title) values(502, 'raj', 'ahuja', 'title2');
insert into specialist(userID, firstName, lastName, title) values(503, 'katy', 'perry', 'title3');
insert into specialist(userID, firstName, lastName, title) values(504, 'john', 'cyrus', 'title4');
insert into specialist(userID, firstName, lastName, title) values(505, 'anindita', 'pal', 'title5');

GO

CREATE PROCEDURE GetIdOfUser
(
    @f_name VARCHAR(50), 
    @l_name VARCHAR(50),
    @outValue INT OUTPUT
)
AS
    SELECT @outValue = userID 
    FROM specialist
    WHERE firstName = @f_name 
        AND lastName = @l_name

    if @@rowcount > 1
        set @outValue = -1

GO

DECLARE @myretValue INT;

EXEC GetIdOfUser 'raj', 'ahuja', @myretValue OUTPUT;

SELECT @myretValue;
1 голос
/ 22 мая 2019

У вас есть несколько проблем, я бы попытался заставить их работать с минимальными изменениями.

CREATE PROCEDURE GetIdOfUser
    (@f_name VARCHAR(50), 
     @l_name VARCHAR(50),
     @outValue INT OUTPUT)
AS
    DECLARE @intValue INT

По умолчанию sql fiddle использует ; для завершения пакета, измените его на GO или удалите ;

    SELECT @intValue = userID 
    FROM users
    WHERE firstName = @f_name AND lastName = @l_name

    SET @outValue = CASE WHEN @@rowcount = 1 THEN @intValue ELSE 0 END

Упрощено это с помощью оператора case, вам не нужно использовать несколько операторов if здесь.Кроме того, ваша первоначальная проверка была больше и равна, не меньше (если строки не найдены) и в этом случае вернула бы 0.Это обрабатывает все случаи.

GO

Завершение партии или приведенный ниже код также становится частью процедуры.Я считаю, что размещение всей логики процедуры внутри BEGIN ... END также будет работать.

DECLARE @myretValue INT

EXEC GetIdOfUser 'raj', 'ahuja', @myretValue OUTPUT

При вызове процедуры необходимо определить выходную переменную как OUTPUT, чтобы она действительно работала, иначе sql не установит значениепеременной.

SELECT @myretValue

Используя приведенный выше код, все работает хорошо, и я получаю ответ 502, ссылка на скрипку - http://sqlfiddle.com/#!18/ddb50/47

1 голос
/ 21 мая 2019

Попробуйте это

DECLARE @myretValue int
EXEC GetIdOfUser 'raj', 'ahuja', @myretValue output
select @myretValue;
...