web-dev-qa-db-fra.com

Procédure ou fonction stockée attend un paramètre qui n'est pas fourni

J'essaie d'insérer des données dans une base de données SQL Server en appelant une procédure stockée, mais le message d'erreur s'affiche.

La procédure ou la fonction 'SHOWuser' attend le paramètre '@userID', qui n'a pas été fourni.

Ma procédure stockée s'appelle SHOWuser. Je l'ai vérifié à fond et il ne manque aucun paramètre.

Mon code est:

public void SHOWuser(string userName, string password, string emailAddress, List<int> preferences)
{
        SqlConnection dbcon = new SqlConnection(conn);

        try
        { 
            SqlCommand cmd = new SqlCommand();

            cmd.Connection = dbcon;
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.CommandText = "SHOWuser";

            cmd.Parameters.AddWithValue("@userName", userName);
            cmd.Parameters.AddWithValue("@password", password);
            cmd.Parameters.AddWithValue("@emailAddress", emailAddress);

            dbcon.Open();

            int i = Convert.ToInt32(cmd.ExecuteScalar());

            cmd.Parameters.Clear();
            cmd.CommandText = "tbl_pref";

            foreach (int preference in preferences)
            {
                cmd.Parameters.Clear();
                cmd.Parameters.AddWithValue("@userID", Convert.ToInt32(i));
                cmd.Parameters.AddWithValue("@preferenceID", Convert.ToInt32(preference));

                cmd.ExecuteNonQuery();
            }
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            dbcon.Close();
        }

et la procédure stockée est:

ALTER PROCEDURE [dbo].[SHOWuser]
(
    @userName varchar(50),
    @password nvarchar(50),
    @emailAddress nvarchar(50)
)
AS
BEGIN
    INSERT INTO tbl_user(userName, password, emailAddress) 
    VALUES (@userName, @password, @emailAddress)

    SELECT
        tbl_user.userID, tbl_user.userName,
        tbl_user.password, tbl_user.emailAddress, 
        STUFF((SELECT ',' + preferenceName 
               FROM tbl_pref_master
               INNER JOIN tbl_preferences ON tbl_pref_master.preferenceID = tbl_preferences.preferenceID
               WHERE tbl_preferences.userID = tbl_user.userID
               FOR XML PATH ('')), 1, 1, ' ' ) AS Preferences
    FROM
        tbl_user

    SELECT SCOPE_IDENTITY();
END

Ceci est la deuxième procédure stockée tbl_pref qui est utilisé dans la même fonction:

ALTER PROCEDURE [dbo].[tbl_pref]
    @userID int,
    @preferenceID int
AS
BEGIN
    INSERT INTO tbl_preferences(userID, preferenceID) 
    VALUES (@userID, @preferenceID)
END
33
user2920046

Votre procédure stockée attend 5 paramètres en entrée

@userID int, 
@userName varchar(50), 
@password nvarchar(50), 
@emailAddress nvarchar(50), 
@preferenceName varchar(20) 

Donc, vous devriez ajouter les 5 paramètres à cet appel SP appelez:

    cmd.CommandText = "SHOWuser";
    cmd.Parameters.AddWithValue("@userID",userID);
    cmd.Parameters.AddWithValue("@userName", userName);
    cmd.Parameters.AddWithValue("@password", password);
    cmd.Parameters.AddWithValue("@emailAddress", emailAddress);
    cmd.Parameters.AddWithValue("@preferenceName", preferences);
    dbcon.Open();

PS: On ne sait pas à quoi servent ces paramètres. Vous n'utilisez pas ces paramètres dans votre corps SP), votre SP devrait donc ressembler à ceci:

ALTER PROCEDURE [dbo].[SHOWuser] AS BEGIN ..... END
11
valex

Dans mon cas, j'ai reçu cette exception même lorsque toutes les valeurs de paramètre ont été correctement fournies mais que le type de commande n'a pas été spécifié:

cmd.CommandType = System.Data.CommandType.StoredProcedure;

Ce n’est évidemment pas le cas dans la question ci-dessus, mais la description de l’exception n’est pas très claire dans ce cas, j’ai donc décidé de le préciser.

151
Alex Krotnyi

J'ai rencontré ce problème hier, mais aucune des solutions proposées ne fonctionnait exactement, mais elles m'ont orienté dans la bonne direction.

Notre application est un outil de flux de travail écrit en C # et, simplifié à l'extrême, ayant plusieurs procédures stockées dans la base de données, ainsi qu'un tableau de métadonnées sur chaque paramètre utilisé par chaque procédure stockée (nom, ordre, type de données, taille, etc.), nous permettant de créer autant de nouvelles procédures stockées que nous avons besoin sans avoir à changer le C #.

L'analyse du problème a montré que notre code définissait tous les paramètres corrects sur l'objet SqlCommand. Cependant, une fois exécuté, il renvoyait la même erreur que celle obtenue par l'OP.

Une analyse plus poussée a révélé que certains paramètres avaient une valeur de null. Je dois donc en conclure que les objets SqlCommand ignorent tout objet SqlParameter dans leur .Parameters collection avec une valeur de null.

J'ai trouvé deux solutions à ce problème.

  1. Dans nos procédures stockées, donnez une valeur par défaut à chaque paramètre, donc de @Parameter int à @Parameter int = NULL (ou une autre valeur par défaut si nécessaire).

  2. Dans notre code, qui génère les objets individuels SqlParameter, attribue DBNull.Value au lieu de null où la valeur prévue est un SQL NULL fait l'affaire.

Le codeur d'origine a évolué et le code a été écrit à l'origine avec la solution 1 à l'esprit. Après avoir pesé les avantages des deux, je pense que je vais m'en tenir à la solution 1. Il est beaucoup plus facile de spécifier une valeur par défaut pour une procédure stockée spécifique. lors de l'écriture, plutôt que d'être toujours NULL tel que défini dans le code.

J'espère que ça aide quelqu'un.

35
ubercam

Dans mon cas, j'ai eu l'erreur sur le paramètre de sortie même si je l'avais réglée correctement sur le côté C #, mais j'ai oublié de donner une valeur par défaut au paramètre de sortie dans la procédure stockée.

ALTER PROCEDURE [dbo].[test]
(
                @UserID int,
                @ReturnValue int = 0 output --Previously I had @ReturnValue int output
)
4
Vbp

Dans mon cas, il renvoyait un paramètre de sortie et ne renvoyait aucune valeur.
Ainsi changé en

param.Direction = ParameterDirection.Output;
command.ExecuteScalar();

et puis il jetait une erreur de taille. donc dû définir la taille aussi

SqlParameter param = new SqlParameter("@Name",SqlDbType.NVarChar);
param.Size = 10;
3
Dev