2
votes

Comment appeler une procédure SQL Server avec des paramètres d'entrée et de sortie?

J'essaie d'écrire une procédure qui renvoie des valeurs sur la base d'un résultat de requête de sélection. Comme trouver l'ID d'un utilisateur, utilisez le prénom et le nom pour localiser un ID utilisateur et renvoyez l'ID en tant que paramètre OUTPUT. Si plus d'un ou aucun utilisateur n'est trouvé, définissez une valeur de retour de -1 et définissez le paramètre OUTPUT sur 0.

J'ai essayé le code suivant mais j'obtiens une erreur:

Doit déclarer la variable scalaire "@intValue"

J'ai effectué des recherches sur Internet mais aucun n'a résolu mon problème.

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');

J'utilise SQLfiddle [sqlfiddle.com] pour apprendre les concepts de SQL Server. Je suis assez nouveau dans la création de procédures dans SQL Server, donc toute aide serait appréciée.

EDIT 1: La version de SQL Server est 2017

EDIT 2: Schéma et exemples de données avec lesquels je travaille.

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;


11 commentaires

IF @@ rowcount == 1 doit être IF @@ rowcount = 1 . Je ne sais pas pourquoi vous avez l'erreur que vous avez.


merci @scsimon mais cela n'a pas encore résolu mon problème.


Votre @@ ROWCOUNT est remis à 0. Changez-le en un bloc else ... puis appelez-le correctement. Voir la démo ici . @@ ROWCOUNT peut être délicat. Voir ce blog sur une seule instance. De plus, utiliser PRINT le réinitialisera à 0.


J'ai essayé cela aussi mais pourquoi est-ce que je continue à avoir la même erreur Dois déclarer la variable scalaire "@intValue" même si elle est déclarée? @scsimon


Ce n'est pas reproductible avec le code que vous avez publié. Cela peut être vu dans la démo que j'ai publiée. Nous ne pouvons que supposer que vous avez un autre code au-dessus ou en dessous de cet extrait de code sur votre système.


@scsimon pouvez-vous essayer le code ci-dessus dans SQLfiddle que j'ai fourni dans ma question? Je posterai le schéma pour cela. (J'essaie juste de savoir si l'EDI a un problème ...)


La procédure que j'ai publiée fonctionne exactement comme vous le souhaitez.


Cela fonctionne @Diksha ... Voir la démo ici Je viens de changer le nom de la table dans le procédure. Notez que c'est avec les modifications que j'ai déjà suggérées dans mes commentaires précédents.


Oh, je parie que je sais quel est le problème ici. @Diksha l'instruction return est un animal très différent d'une variable de sortie. J'ai l'impression que vous vous attendez à voir la valeur de retour dans votre variable de sortie. Ce n'est pas ainsi que fonctionnent les procédures. Il a une valeur de retour qui doit être utilisée pour l'état de l'exécution, et non pour renvoyer des données. Ensuite, vous avez des paramètres de sortie qui sont complètement différents. Vous pouvez en avoir beaucoup et ils peuvent être de n'importe quel type de données. La valeur de retour est toujours un int.


D'accord, la valeur de retour est juste pour la tâche d'état et si nous voulons voir la sortie à l'écran, nous utilisons le paramètre de sortie. merci d'avoir effacé ce @SeanLange


@Diksha oui c'est correct.


3 Réponses :


1
votes

Essayez celui-ci

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


6 commentaires

J'ai essayé toujours d'obtenir la même erreur: Doit déclarer la variable scalaire "@intValue".


Essayez de supprimer le signe supplémentaire "=" sur la ligne. Donc, c'est la bonne façon IF @@ rowcount = 1


J'ai créé la table [Users] ainsi que votre procédure stockée. La procédure s'exécute sans aucune erreur. Savez-vous peut-être quelle version de SQL Server utilisez-vous? J'ai testé sur SQL Server 2008-2012


@DarkoMartinovic @@ ROWCOUNT est réinitialisé après le premier bloc IF. C'est pourquoi la deuxième condition est toujours fausse. Il s'exécutera sans erreur, mais ne retournera pas les résultats corrects.


@scsimon Comment l'erreur "Doit déclarer la variable scalaire" @intValue "" est-elle déclenchée?


Aucune idée ... pas du code que vous avez posté. Vous devriez avoir obtenu une erreur syntaxe incorrecte près de = . Une fois que vous avez supprimé cela, comme vous l'avez suggéré et je l'ai fait dans mes commentaires, il fonctionnerait sans erreur mais ne renverrait pas les résultats escomptés même lorsque l'utilisateur l'appelle correctement comme vous l'avez décrit dans votre message. Voir ceci ici . Cependant, la résolution du problème dans le processus comme je l'ai expliqué dans mes commentaires le résoudra. Voir ça ici



3
votes

Je simplifierais un peu cela. Pas besoin de renseigner plusieurs variables ici. Voyez si quelque chose d'un peu plus simple comme celui-ci fonctionne.

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;

Voici comment vous l'utiliseriez.

DECLARE @myretValue INT;

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

SELECT @myretValue;

--EDIT -

Avec vos nouveaux exemples de données, j'ai décidé d'utiliser le spécialiste des noms de table puisque vous avez publié deux noms différents. La procédure que j'ai publiée ici fonctionne parfaitement.

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


10 commentaires

Ouais cette course mais n'a retourné aucun résultat @Sean Lange


Veuillez consulter ma mise à jour. J'ai ajouté un exemple de code pour appeler cela.


@Sean Lange Le résultat n'est pas important. Je ne peux pas comprendre comment l'erreur "" Doit déclarer la variable scalaire "@intValue" "est soulevée?


Il n'y a aucune chance que vous ayez cette erreur en utilisant le code que je viens de publier. Ce nom de variable ne figure pas dans le code.


@Sean Lange D'accord avec vous à 100%.


@SeanLange J'ai appelé la procédure de la même manière que vous l'avez suggérée.


Avez-vous changé la procédure pour le code que j'ai également publié?


Vous n'avez aucune valeur dans la variable de sortie? Ce n'est tout simplement pas si difficile, mais vous ne fournissez pas d'informations ici. Vous devez indiquer ce qui se passe et non "J'ai eu une erreur" ou "il n'a pas retourné de résultat". Cette procédure est extrêmement simple et elle renverra une valeur ou lèvera une exception. Il n'y a tout simplement pas de terrain d'entente ici.


mon mauvais @SeanLange, aucun résultat renvoyé ne signifiait Record Count: 0; Temps d'exécution: 14ms


Voir ma dernière mise à jour. En utilisant vos exemples de données publiés, cela fonctionne très bien s'il y a une ou plusieurs lignes renvoyées. Il retournera NULL s'il n'y a aucune ligne trouvée qui soit cohérente avec votre code d'origine, bien que ce ne soit peut-être pas ce que vous voulez.