2011-10-14 3 views
6

Je suis novice dans l'écriture de procédure stockée. J'ai donc écrit un avec les paramètres de sortie et je veux accéder à la valeur de sortie, chaud pour le faire.Comment utiliser le paramètre OUTPUT dans la procédure stockée

Ma procédure stockée:

ALTER PROCEDURE selQuery 
    (
     @id int, @code varchar(50) OUTPUT 
    ) 
AS 
    SELECT RecItemCode = @code, RecUsername from Receipt where RecTransaction = @id 
    RETURN @code 

Si vous essayez de définir « code @ = RecItemCode » obtenir erreur: « Une instruction SELECT qui attribue une valeur à une variable ne doit pas être associée à des opérations de données de récupération. »

Et j'utilise la procédure stockée comme:

con.Open(); 
cmd.Parameters.AddWithValue("@id", textBox1.Text); 
SqlParameter code = new SqlParameter("@code", SqlDbType.Int); 
code.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(code); 
SqlDataReader sdr = cmd.ExecuteReader(); 
MessageBox.Show(cmd.Parameters["@code"].Value.ToString()); // getting error 
con.Close(); 

Erreur: « Référence d'objet non définie à une instance d'un objet. » Je veux obtenir la valeur du paramètre de sortie. Comment l'obtenir?

Merci.

Répondre

7

Le code SQL de votre SP est erroné. Vous voulez probablement

Select @code = RecItemCode from Receipt where RecTransaction = @id 

Dans votre déclaration, vous ne définissez pas @code, vous essayez de l'utiliser pour la valeur de RecItemCode. Cela expliquerait votre NullReferenceException lorsque vous essayez d'utiliser le paramètre de sortie, car une valeur ne lui est jamais affectée et vous obtenez une valeur par défaut nulle.

L'autre problème est que l'instruction SQL si réécrite comme

Select @code = RecItemCode, RecUsername from Receipt where RecTransaction = @id 

Il est le mélange de l'affectation des variables et la récupération des données. Cela met en évidence quelques points. Si vous avez besoin des données qui pilotent @code en plus des autres parties des données, oubliez le paramètre de sortie et sélectionnez simplement les données.

Select RecItemCode, RecUsername from Receipt where RecTransaction = @id 

Si vous avez juste besoin du code, utilisez la première instruction SQL que je vous ai montrée.Sur la chance désinvolture dont vous avez besoin en fait la sortie et les données, utilisez deux déclarations différentes

Select @code = RecItemCode from Receipt where RecTransaction = @id 
Select RecItemCode, RecUsername from Receipt where RecTransaction = @id 

Cela devrait affecter votre valeur au paramètre de sortie ainsi que le retour de deux colonnes de données dans une rangée. Cependant, cela me semble terriblement redondant.

Si vous écrivez votre SP comme je l'ai montré tout en haut, appelez simplement cmd.ExecuteNonQuery();, puis lisez la valeur du paramètre de sortie.


Un autre problème avec votre SP et votre code. Dans votre SP, vous avez déclaré @code comme varchar. Dans votre code, vous spécifiez le type de paramètre Int. Changez votre SP ou votre code pour rendre les types cohérents.


Notez également: Si tout ce que vous faites est de retour une valeur unique, il y a une autre façon de le faire qui ne comporte pas de paramètres de sortie du tout. Vous pouvez écrire

Select RecItemCode from Receipt where RecTransaction = @id 

Et puis utilisez object obj = cmd.ExecuteScalar(); pour obtenir le résultat, pas besoin d'un paramètre de sortie dans la SP ou dans votre code.

+0

merci anthony, ça a beaucoup aidé .... merci beaucoup – Sandy

+0

Merci et +1. 'object obj = cmd.ExecuteScalar();' travaillé parfaitement. J'ai été capable d'accomplir ce dont j'avais besoin dans deux lignes de code C#, la seconde étant 'myString = obj.ToString();'. – FumblesWithCode

24

Il y a plusieurs choses que vous devez répondre pour le faire fonctionner

  1. Le nom est erroné de son pas @ouput son @code
  2. Vous devez définir la direction du paramètre de sortie.
  3. N'utilisez pas AddWithValue car il n'est pas supposé avoir une valeur juste Add.
  4. Utilisez ExecuteNonQuery si vous n'êtes pas des lignes de retour

Essayez

SqlParameter output = new SqlParameter("@code", SqlDbType.Int); 
output.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(output); 
cmd.ExecuteNonQuery(); 
MessageBox.Show(output.Value.ToString()); 
+0

bien, mais comment obtenir la valeur du paramètre de sortie ?? output.Value.ToString() donnant une erreur en tant que "Référence d'objet non définie sur une instance d'un objet". – Sandy

+0

et ne dites pas "vous avez oublié" parce que je n'ai pas oublié, en fait je ne sais pas :-( – Sandy

+0

@rapsalands, * après * vous exécutez la requête, récupérez la valeur du paramètre. 'Cmd.ExecuteNonQuery(); int value = (int) output.Value; ' –

1

Vous devez définir le paramètre de sortie en tant que paramètre de sortie dans le code avec l'énumération ParameterDirection.Output. Il existe de nombreux exemples de cela, mais voici un sur MSDN.

1
SqlCommand yourCommand = new SqlCommand(); 
yourCommand.Connection = yourSqlConn; 
yourCommand.Parameters.Add("@yourParam"); 
yourCommand.Parameters["@yourParam"].Direction = ParameterDirection.Output; 

// execute your query successfully 

int yourResult = yourCommand.Parameters["@yourParam"].Value; 
+0

Je reçois une erreur. Voir edit post ... merci – Sandy

+0

@rapsalands Vous ne pouvez pas exécuter le code. Ce n'est pas un bloc de code autonome. Cette erreur indique que vous n'avez pas instancié un objet (c'est-à-dire en créer une nouvelle).C'était juste pour vous donner l'idée générale de la façon d'obtenir une valeur à partir d'un paramètre de sortie d'un proc stocké. –

+0

En fait, j'essaie d'apprendre le SP et je ne l'ai jamais fait auparavant. Ce sera génial si vous pouvez dire ce qui ne va pas avec mon code. Je veux dire où je dois créer l'instance ?? – Sandy

0

Vous devez fermer la connexion avant de pouvoir utiliser les paramètres de sortie. Quelque chose comme ça

con.Close(); 
MessageBox.Show(cmd.Parameters["@code"].Value.ToString()); 
Questions connexes