2009-11-04 7 views
0

J'utilise la procédure stockée suivante de mon SQL Server base de données 2008 pour renvoyer une valeur à mon C# -ProgrammeSQL Server 2008 stocké Proc retourne soudainement -1

ALTER PROCEDURE [dbo].[getArticleBelongsToCatsCount] 
@id int 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @result int; 

    set @result = (SELECT COUNT(*) FROM art_in_cat WHERE child_id = @id); 
    return @result; 
END 

J'utilise un SQLCommand-Object pour appeler cette Stored Procédure

public int ExecuteNonQuery() 
{ 
    try 
    { 
    return _command.ExecuteNonQuery(); 
    } 
    catch (Exception e) 
    { 
    Logger.instance.ErrorRoutine(e, "Text: " + _command.CommandText); 
    return -1; 
    } 
} 

Jusqu'à récemment, tout fonctionne correctement. Tout à coup, la procédure stockée est retournée -1. Au début, je soupçonnais, que l'ExecuteNonQuery-Command aurait causé et Exception, mais en passant par la fonction, il montre qu'aucune exception n'est levée et la valeur de retour vient directement de retour _command.ExecuteNonQuery();

j'ai vérifié les paramètres suivants et ils étaient comme prévu: - objet de connexion a été défini sur la base de données correcte avec des valeurs d'accès correct - le paramètre pour la SP était là et contenait le type, la direction et la valeur

Puis j'ai vérifié le SP via SQLManager, j'ai utilisé la même valeur pour le paramètre comme celui pour lequel mon C# apporte -1 comme résultat (btw.J'ai vérifié d'autres valeurs de paramètres dans mon programme C 'et ils ont retourné -1) mais dans le gestionnaire, le SP renvoie la valeur correcte.

Il ressemble à l'appel de mon C# prog est buggé en quelque sorte, mais je ne reçois pas d'erreur (il est juste le de la SP -1), je ne sais pas où chercher une solution.

Répondre

5

ExecuteNonQuery retourne le nombre de lignes affectées par une instruction INSERT, UPDATE ou DELETE, pas la valeur de retour d'une procédure stockée. Si cela fonctionnait dans le passé, y a-t-il une possibilité que les données soient modifiées par votre requête?

Pour obtenir la valeur de retour d'une procédure stockée, ajoutez un paramètre à votre commande avec ParameterDirection.ReturnValue. Après avoir appelé ExecuteNonQuery(), ce paramètre sera rempli avec la valeur de retour de la procédure stockée. ExecuteNonQuery renvoie la valeur -1 pour les commandes qui n'affectent aucune ligne.

+0

Je suppose qu'il veut 'ExecuteReader'? – Kezzer

+0

Je ne pense pas. Sa procédure stockée ne retourne pas un resultset, donc ExecuteNonQuery devrait toujours être approprié sauf si quelque chose me manque. –

+0

Basé sur le SP, il devrait utiliser 'ExecuteScalar'. –

1

Il semble que vous renvoyez l'état de l'exécution de la requête Count lorsque vous voulez vraiment la valeur COUNT (*).

Je pense qu'il devrait être comme ceci:

ALTER PROCEDURE [dbo].[getArticleBelongsToCatsCount] 
@id int, 
@NumberOfRows int OUTPUT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT @NumberOfRows = COUNT(*) FROM art_in_cat WHERE child_id = @id; 

END 
+0

Les deux commandes ne sont-elles pas égales? Nous utilisons les deux et je n'ai pas remarqué de différence. –

+0

réponse corrigée pour afficher @NumberOfRows en tant que variable OUTPUT. –

+0

OUtput variable est certainement la bonne façon de procéder, le retour ne devrait jamais être utilisé, sauf pour dire si le proc a réussi ou non. – HLGEM

1

De MSDN ExecuteNonQuery:

Vous pouvez utiliser le ExecuteNonQuery pour effectuer des opérations de catalogue (pour exemple, l'interrogation de la structure d'une base de données ou créer des objets de base de données tels que des tables), ou pour modifier les données dans une base de données sans utiliser un DataSet by exec UT UPDATE, INSERT ou DELETE instructions.

Bien que le ExecuteNonQuery retourne aucune ligne, tous les paramètres de sortie ou valeurs de retour sont mis en correspondance avec les paramètres avec des données.

Pour les instructions UPDATE, INSERT et DELETE déclarations, la valeur de retour est le nombre de lignes affectées par la commande . Lorsqu'un déclencheur existe sur une table étant inséré ou mis à jour, la valeur de retour comprend le nombre de lignes affectées par fois l'insert ou opération de mise à jour et le nombre de lignes affectées par la gâchette ou déclencheurs. Pour tous les autres types d'instructions , la valeur de retour est -1. Si une annulation se produit, la valeur de retour est également -1.

ExecuteScalar est probablement ce que vous voulez.

Votre SP pourrait alors ceci:

ALTER PROCEDURE [dbo].[getArticleBelongsToCatsCount] 
@id int 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT COUNT(*) FROM art_in_cat WHERE child_id = @id 
END 
0

Voir la documentation au MSDN. Vous devez vérifier la valeur du paramètre de sortie @result.

1

return _command.ExecuteNonQuery();

devrait être

retour _command.ExecuteScalar();

Raison étant que c'est une requête que vous exécutez, une requête qui renvoie une seule valeur. ExecuteNonQuery() suppose que rien n'est renvoyé (comme exécuter une requête UPDATE).

+0

ExecuteScalar renvoie le premier enregistrement de la première ligne du jeu de résultats que vous exécutez, PAS la valeur de retour d'une procédure stockée. ExecuteNonQuery() est l'appel approprié, mais vous devez ajouter un paramètre pour stocker la valeur de retour. –

Questions connexes