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