2010-06-07 4 views
1

Je développe une application de site Web C# VS 2008/SQL Server. Je suis un débutant à ASP.NET. J'obtiens l'erreur de compilateur ci-dessus. Pouvez-vous me donner des conseils sur la façon de résoudre ce problème?Procédure ou fonction AppendDataCT a trop d'arguments spécifiés

extrait de code:

public static string AppendDataCT(DataTable dt, Dictionary<int, string> dic) 
    { 
     string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString; 
     string errorMsg; 

     try 
     { 
SqlConnection conn2 = new SqlConnection(connString); 
SqlCommand cmd = conn2.CreateCommand(); 
cmd.CommandText = "dbo.AppendDataCT"; 
cmd.CommandType = CommandType.StoredProcedure; 
cmd.Connection = conn2; 
SqlParameter p1, p2, p3; 
foreach (string s in dt.Rows[1].ItemArray) 
{ 
    DataRow dr = dt.Rows[1]; // second row 
    p1 = cmd.Parameters.AddWithValue((string)dic[0], (string)dr[0]); 
    p1.SqlDbType = SqlDbType.VarChar; 
    p2 = cmd.Parameters.AddWithValue((string)dic[1], (string)dr[1]); 
    p2.SqlDbType = SqlDbType.VarChar; 
    p3 = cmd.Parameters.AddWithValue((string)dic[2], (string)dr[2]); 
    p3.SqlDbType = SqlDbType.VarChar; 
} 

conn2.Open(); 
cmd.ExecuteNonQuery(); 

erreurs Il sur cette dernière ligne ici.

Et voici que SP:

ALTER PROCEDURE [dbo].[AppendDataCT] 
@col1 VARCHAR(50), 
@col2 VARCHAR(50), 
@col3 VARCHAR(50) 
AS 
BEGIN 
SET NOCOUNT ON; 
DECLARE @TEMP DATETIME 
SET @TEMP = (SELECT CONVERT (DATETIME, @col3)) 

INSERT INTO Person.ContactType (Name, ModifiedDate) 
VALUES(@col2, @TEMP) 
END 
+1

Eh bien, vous avez probablement le mauvais nombre d'arguments pour la procédure stockée.Vous n'avez pas montré cela, ni pourquoi vous êtes en boucle. –

+0

Merci Jon, je viens de mettre à jour ma description. – salvationishere

+0

Jon, pouvez-vous regarder ma réponse à la réponse de John ci-dessous? – salvationishere

Répondre

1

Si votre élément du tableau contient plus de 1 chaîne cela se produira parce que vous installerez un certain nombre de paramètres = 3 * No Strings dans le tableau de l'article.

De même, vous n'utilisez pas la chaîne que vous tirez dans votre boucle.

il semble y avoir eu une certaine évolution en cours ici.

vous devez vous asseoir et déterminer si vous voulez exécuter l'insertion plusieurs fois (en ce moment vous en exécutez seulement un) ou non.

Il existe d'autres façons de définir le type des paramètres, de sorte que vous n'avez pas besoin de vos variables p1,2,3 btw.

Je soupçonne que vous voulez faire quelque chose comme ce

public static string AppendDataCT(DataRow dr, Dictionary<int, string> dic) 
     { 


      string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString; 
      string errorMsg; 

      try 
      { 
       SqlConnection conn2 = new SqlConnection(connString); 
       SqlCommand cmd = conn2.CreateCommand(); 
       cmd.CommandText = "dbo.AppendDataCT"; 
       cmd.CommandType = CommandType.StoredProcedure; 
       cmd.Connection = conn2; 
       SqlParameter p1, p2, p3; 

        p1 = cmd.Parameters.AddWithValue((string) dic[0], (string) dr[0]); 
        p1.SqlDbType = SqlDbType.VarChar; 
        p2 = cmd.Parameters.AddWithValue((string) dic[1], (string) dr[1]); 
        p2.SqlDbType = SqlDbType.VarChar; 
        p3 = cmd.Parameters.AddWithValue((string) dic[2], (string) dr[2]); 
        p3.SqlDbType = SqlDbType.VarChar; 
        conn2.Open(); 
        cmd.ExecuteNonQuery(); 
        conn2.Close(); 

      } 

bien que cette ligne

foreach (string s in dt.Rows[1].ItemArray) 

m'a vraiment perplexe ... a je pense que vous êtes en train de faire quelque chose de mal ici - il dit moi rien de ce que vous essayez de faire et semble confus. Dans 6 mois, vous n'aurez aucune idée de comment cela fonctionne. De plus, l'appelant peut probablement se conduire de différentes manières, qui ne seront prises en compte qu'à l'exécution. Pourquoi ne pas simplement passer un int en disant combien de fois la boucle se produira?

L'ID effectue également un comptage sur le dictionnaire pour confirmer qu'il y a 3 et seulement 3 éléments, car peu importe le nombre de fois que vous bouclez, vous insérerez les mêmes 3 éléments. Pourquoi ne pas utiliser un dictionnaire et utiliser le nom de param comme index?

ou boucle dans la liste des clés en tant que chaînes et ajouter les paramètres de cette façon?

soemthing comme celui-ci

/// <summary> 
     /// 
     /// </summary> 
     /// <param name="dic">key = param name, val = param value</param> 
     /// <returns></returns> 
     public static string AppendDataCT(Dictionary<string, string> dic) 
    { 

     if (dic.Count !=3) 
      throw new ArgumentOutOfRangeException("dic can only have 3 parameters"); 

     string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString; 
     // you probably want to do a string.IsNullOrEmpty(connString) and throw a ConfigurationException here is true to quickly identify this annoying bug ... 


      using(SqlConnection conn2 = new SqlConnection(connString)) 
      { 
      using(SqlCommand cmd = conn2.CreateCommand()) 
      { 
      cmd.CommandText = "dbo.AppendDataCT"; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Connection = conn2; 

      foreach (string s in dic.Keys) 
      {      
       SqlParameter p = cmd.Parameters.AddWithValue(s, dic[s]); 
       p.SqlDbType = SqlDbType.VarChar; 
      } 

      conn2.Open(); 
      cmd.ExecuteNonQuery(); 
      conn2.Close(); 
      } 
      } 
     } 

que le code est loin d'être parfait, mais peut-être un peu ce que vous vouliez dire.

Si vous voulez faire plusieurs inserts alors peut-être envisager une list<dictionary<string,string>> ou mieux faire encore struct simple à maintenir les paramètres et une liste des struct et passer que. La raison de la struct/classe pour la args est qu'il peut valiate les données pour protéger votre méthode de toutes sortes de données désagréables provoquant l'explosion. Toujours sympa de faire en sorte que le code de quelqu'un d'autre se comporte plutôt que de faire face à toutes ses permutations bizzarre.

+0

Merci, John. Je veux parcourir la liste et récupérer des valeurs. Mais au début, j'essayais d'obtenir la première rangée de données. Une fois que cela a fonctionné, j'ai prévu de faire fonctionner les autres rangées. Je vais essayer votre code si! – salvationishere

+0

Est-ce que ce code crée 3 paramètres distincts que je peux charger? Il me ressemble le même nom de paramètre: p1 – salvationishere

+0

hmm .. J'imagine que AddWithValue construit un nouveau paramètre et ainsi même s'il n'y a pas p1 = new Parameter(); le paramètre que les références p1 seront différentes chaque fois que la boucle s'exécute. –

Questions connexes