TabParam est défini comme ceci en tant que variable globale.
SqlParameter[] TabParam= new SqlParameter[50];
je voudrait pouvoir "vider" ma table pour quelle soit comme a l'origine mais je n'ai pas trouvé un moyen de la détruire puis de la re-déclarer globale
(déja la détruire je ne sais pas )
1) tu peux remplacer
this.Tabstring.RemoveRange(0, nb_string);
par
this.Tabstring.Clear();
2) Pour réinitialiser ta variable "TabParam" tu peux écrire :
TabParam= new SqlParameter[50];
L'erreur que tu obtiens "La requête paramétré 'blabla' attend le paramètre @Parameter1, qui n'a pas été fourni" indique que tu n'as pas réaffecter les paramètres utilisés par ta requête...
Assures toi d'avoir bien écrit TabParam[ 0 ] = new SqlParameter(...);
avant l'exécution de ta requête !
Je te propose le code suivant, il permet d'exécuter la requête après avoir extrait les SqlParameter ainsi que les valeurs des variables associées :
private void ExecuteQuery( string query )
{
// Remplace les caractères '?' par le caractère '@'
query = query.Replace( '?', '@' );
// Affecte la requête à l'objet SqlCommand
command.CommandText = query;
// Récupère le nom des variables
ArrayList variableNames = ExtractVariableNames( query );
// Affecte la liste de SqlParameters à l'objet SqlCommand
command.Parameters.Clear();
command.Parameters.AddRange( ExtractSqlParameters( variableNames ) );
// Exécute la requête
command.CommandText = query;
SqlDataReader reader = command.ExecuteReader();
}
// Extrait le nom des variables contenu dans la requête
private ArrayList ExtractVariableNames( string test )
{
// Initialise le tableau de noms de variables
ArrayList variableNames = new ArrayList();
// Parcourt la requête à exécuter
for( int charIndex = 0; charIndex < test.Length; charIndex++ )
{
if( test[ charIndex ] == '@' )
{
// Début de nom de variable
int startIndex = charIndex + 1;
// Recherche la fin du nom de variable
charIndex++;
while( charIndex < test.Length && test[ charIndex ] != ',' && test[ charIndex ] != ' ' && test[ charIndex ] != ')' )
charIndex++;
// Ajoute le nom de la variable dans le tableau
string variableName = test.Substring( startIndex, charIndex - startIndex );
if( !variableNames.Contains( variableName ) )
variableNames.Add( variableName );
}
}
// Retourne le tableau
return variableNames;
}
// Extrait les valeurs des variables passées en paramètre et retourne une liste des SqlParamaters associés
private SqlParameter[] ExtractSqlParameters( ArrayList variableNames )
{
// Initialise le tableau de SqlParameters
SqlParameter[] sqlParameters = new SqlParameter[ variableNames.Count ];
// Parcourt les noms de variables
for( int varIndex = 0; varIndex < variableNames.Count; varIndex++ )
{
// Extrait le SqlParameter associé
sqlParameters[ varIndex ] = GetParameter( variableNames[ varIndex ].ToString() );
}
// Retourne le tableau
return sqlParameters;
}
// Retourne un SqlParameter affecté de la valeur d'une variable d'après son nom
private SqlParameter GetParameter( string varName )
{
FieldInfo field = typeof( Program ).GetField( varName, BindingFlags.NonPublic | BindingFlags.Static );
if( field == null )
throw new ArgumentException( "La variable '" + varName + "' n'est pas définie dans la classe Program" );
SqlDbType dbType;
switch( field.FieldType.FullName )
{
case ("System.String"):
dbType = SqlDbType.VarChar;
break;
case ("System.Int32"):
dbType = SqlDbType.Int;
break;
case ("System.Double"):
dbType = SqlDbType.Float;
break;
case ("System.DateTime"):
dbType = SqlDbType.DateTime;
break;
default:
throw new ArgumentException( "Une variable de type '" + field.FieldType.FullName + "' ne peut pas être converti en SqlDbType" );
}
SqlParameter parameter = new SqlParameter( varName, dbType );
parameter.Value = field.GetValue( null );
return parameter;
}
J'ai trouvé d'où venait le fait que la seconde requête plante :
Tu n'as pas vider la liste "TableDefini" dans ton RAZ; du coup dans la méthode
Execution, il positionne le booléen "trouve" à true est ajoute un paramètre vide...
Il faut donc ajouter TableDefini.Clear(); dans ta méthode RAZ()
Autre chose, toujours dans la méthode Execution(), il faut vider la liste
de paramètres de l'objet SqlCommand juste avant ou après l'appel à
parser( XExec );
donc : command.Parameters.Clear();
Je pense que ça suffira, mais je continu les investigations ;)
1) Comme je te l'avais proposé dans un des post précédents, remplacer les '?' par les '@' en faisant : toto = toto.Replace( '?', '@' );
2) Remplacer ta méthode private bool existe( string varName ) par TableDefini.Contains( varName );
3) Idem pour public bool existestring( string varName ) à remplacer par Tabstring.Contains( varName );
4) Je pense d'ailleur que tu peux te débarrasser des tableaux TabString, TabParam et TableDefini... Il n'y a aucun mal à ré-instancier tes SqlParameter à chaque requête !
N'hésites pas si tu as d'autres question.
En attendant, bonne continuation !!
J'ai vu deux erreurs dans "btn_select_Click" !
1) Tu n'insères pas " AND " entre les deux paramètres
2) Tu affectes textBox1 au deux champs Etendu et Action (je pense que pour Action c'est textBox2)
Si cela ne change rien envois moi ton projet par mail : ludinski91@Gmail.com
Ce sera plus facile de t'aider comme ça...
J'ai trouvé... je t'ai envoyé un mail en retour !
Tu effaces trop vite la liste de SqlParameter de l'objet SqlCommand
qui est utilisé juste après par SqlDataAdapter...
public string Cible = "";
public string CSecteur = "";
public byte EtatVal = 0;
public Boolean Found = false;
public string From = "";
public string GroupBy = "";
public string Into = "";
public string IntoDbf = "";
public uint NbErrTransac = 0;
public int NbLigne = 0;
public int NomConnection = 0; // a transformer en pointeur
public string OrderBy = "";
public uint ResConnect = 0;
public string Select = "";
public string SourceDbf = "";
public string Type = "";
public string Values = "";
public string Where = "";
public string XExec = "";
public string XInto = "";
public string XSet = "";
public string XVarVal="";
public string XValues ="";
public string XVar="";
public string XVal="";
ArrayList Tabstring = new ArrayList();
string[] Tabmot;
char[] tonTableaudeChar;
SqlConnection connection ;
SqlCommand command;
SqlTransaction transaction;
DataSet Dataset = new DataSet();
Boolean trouve = false;
SqlParameter[] TabParam= new SqlParameter[50];
int nb_param = 0;
int nb_string = 0;
la table de param doit se vider entre chaque requêtes (car elles comportent pas forcement le même nombre de paramètres ^^)
je confirme pour clear() et new ^^
mais j'ai toujours le souci :s je ne sais pas vraiment d'où il peu venir
voici en entier ma procédure d’exécution :
public void Execution(string XExec)
{
try
{
for (int z = 0; XExec.Length > z; z++)
{
if (XExec[z] == '?')
{
tonTableaudeChar = XExec.ToCharArray();
tonTableaudeChar[z] = '@';
XExec = new String(tonTableaudeChar);
}
}
Console.Write("\n\nCommande : " + XExec + " \n\n");
//-------------------------------TEST - solution 1 - TEST ----------------------------------
parser(XExec); // choppe toutes mes variables ? quelquechose dans un Tabstring sans le ?
for (int i = 0; i < nb_string; i++) // créé les parametres
{
Console.Write("\n\nDebut du test d'existence du paramètre "+Tabstring[i]+" dans TableDefini");
trouve = existe(Tabstring[i].ToString());
if (!trouve)
{
Console.Write("\nParamètre " + Tabstring[i] + " non trouvé, début de la phase de construction du paramètre");
TabParam[i] = GetParameter(Tabstring[i].ToString()); // créé le param
command.Parameters.Add(ChercheParam(Tabstring[i].ToString())); // ajoute le parametre a la commande
TableDefini.Add(Tabstring[i].ToString());
Console.Write("\nCréation de : " + TabParam[i].ToString());
}
else
{
command.Parameters.Add(ChercheParam(Tabstring[i].ToString())); // ajoute le parametre a la commande
Console.Write("\nLe paramètre " + Tabstring[i] + " existe, valeur éditée!");
}
}
//------------------------------ FIN TEST - solution 1 - FIN TEST --------------------------
command.CommandText = XExec;
Console.Write("\n\ncommandetext : " + command.CommandText);
Console.Write("\n\nAffectation des parametres a la commande .... execution");
SqlDataReader reader = command.ExecuteReader();
this.Found =reader.HasRows;
reader.Close();
if (this.Type == "SELECT")
{
Dataset = RecupDataSet(command);
Console.Write("test => SELECT");
for (int i = 0; i <= Dataset.Tables[0].Rows.Count - 1; i++)
{
MessageBox.Show(Dataset.Tables[0].Rows[i].ItemArray[0] + " -- " + Dataset.Tables[0].Rows[i].ItemArray[1]);
}
}
else if (this.Type == "COUNT")
{
Dataset = RecupDataSet(command);
Console.Write("test => SELECT");
this.NbLigne = (int)Dataset.Tables[0].Rows[0][0];
}
Console.Write("\n\nCommande executée, appuyez sur une touche pour continuer...\n");
Console.ReadKey();
}
catch (Exception e)
{
this.NbErrTransac++;
MessageBox.Show(e.ToString());
}
}
public void parser(string BOOM)
{
string chaine;
string chainetmp;
string mot;
int position,k,save=0;
chaine = BOOM;
mot = "";
position 0; k 0;
Console.Write("\n\nDebut du parser ....");
for (int z = 0; chaine.Length > z; z++)
{
if (chaine[z] == '?')
{
tonTableaudeChar = chaine.ToCharArray();
tonTableaudeChar[z] = '@';
chaine = new String(tonTableaudeChar);
}
}
for (int i = 0; chaine.Length > i; i++)
{
if (chaine[i] == '@')
{
position = i;
chainetmp = chaine.Substring(position + 1);
for (int j = 0; chainetmp.Length > j; j++)
{
if (chainetmp[j] != ',' && chainetmp[j] != ' ' && chainetmp[j] != ')')
{
mot = mot + chainetmp[j];
k++;
}
else
{
save = k;
k = 0;
break;
}
}
Console.Write("\n\nVariable découverte : " + mot.Trim() + ", test d'existence dans Tabstring");
if (!(existestring(mot.Trim())))
{
Console.Write("\nParser : "+ mot.Trim()+" stocké dans Tabstring");
Tabstring.Add(mot.Trim());
mot = "";
save = 0;
this.nb_string++;
}
else
{
Console.Write("\nParser : mot existant dans Tabstring, non stocké");
mot = "";
save=0;
}
}
}
Console.Write("\n\nFin du parser ....");
}
private SqlParameter ChercheParam(string varName)
{
SqlParameter param = new SqlParameter();
FieldInfo field = typeof(Program).GetField(varName, BindingFlags.NonPublic | BindingFlags.Static);
if (field == null)
throw new ArgumentException("La variable '" + varName + "' n'est pas définie dans la classe Program");
Console.Write("\n\nDebut de la recuperation de @" + varName + " dans TabParam ...");
for (int i = 0; nb_param> i; i++)
{
Console.Write("\nrecherche de : @" + varName + " dans TabParam : " +TabParam[i]);
if (TabParam[i].ParameterName == '@'+varName)
{
Console.Write("\nrecherche : parametre trouve : @" + varName+" .. récuperation...");
param = TabParam[i];
param.Value = field.GetValue(varName);
}
}
return param;
}
private Boolean existe(string varName)
{
Boolean hum=false;
Console.Write("\n\nRecherche du parametre : @" + varName + " dans TableDefini ...");
for (int i = 0; TableDefini.Count > i; i++)
if (varName == TableDefini[i].ToString())
{
Console.Write("\nParametre " + varName + " déja existant : "+TableDefini[i].ToString() );
hum = true;
break;
}
else
{
hum = false;
Console.Write("\nParametre " + varName + " non trouvé : " + TableDefini[i].ToString() );
}
Console.Write("\nFin recherche");
if (TableDefini.Count == 0)
Console.Write(" : aucun element dans TableDefini !");
return hum;
}
public Boolean existestring(string varName)
{
Boolean hum = false;
Console.Write("\n\nRecherche de la chaine : " + varName + " dans la Tabstring");
for (int i = 0; Tabstring.Count > i; i++)
if (varName == Tabstring[i].ToString())
{
Console.Write("\nChaine" + varName + " déja existante : " + Tabstring[i].ToString() );
hum = true;
break;
}
else
{
hum = false;
Console.Write("\nChaine " + varName + " non trouvée : " + Tabstring[i].ToString() );
}
Console.Write("\nFin recherche");
if (Tabstring.Count == 0)
Console.Write(" : aucun element dans Tabstring !");
return hum;
}
Voila grosso-modo ce que ça donne ça fait gros pavé et une soupe de code inutile mais bon
J'ai rajouté pas mal de Console.Write pour débuger le truc ^^, tout s’exécute parfaitement(enfin dans le bon ordre, avec les bonnes recherches)
La première requête marche sans problème, et toutes les suivantes donnent le même problème :(
Si j'ai bien compris le but de ton code;
Tu es sensé pouvoir exécuter une requête du genre :
SELECT var1, var2, var3 FROM [TableTruc] WHERE ChampToto = @var4
donc avant d'exécuter la requête tu dois affecter la liste de SqlParameter avec les valeurs des champs. donc si ta variable 'var4' contient la valeur "bidule" tu exécutera la requête suivante :
SELECT var1, var2, var3 FROM [TableTruc] WHERE ChampToto = "bidule"
et ensuite tu devras affecter les valeurs de retour à tes autres variables.
Donc la variable var1 contiendra la valeur de la colonne var1 issue de la base, idem pour var2 et var3...
donnera cette requete : SELECT * FROM maTable, unautretable
Classe.RAZ;
Classe.connect();
Classe.type="DELETE";
Classe.from="maTable, uneautretable";
Classe.where="attribut=?var_attribut AND truc=?truc" // je doit respecter le '?' je fait une conversion de //tout les ? en @
Classe.execute()
Classe.disconnect();
donnera : DELETE FROM maTable, uneautretable WHERE attribut=?var_attribut AND truc=?truc
ensuite a léxecution avec un executereader et les parametres ?var_attribut et ?truc (qui donnerons d'ici la
@var_attribut et @truc pour que ca marche en C#)
donne sur le serveur lui meme sera executé DELETE FROM maTable, uneautretable WHERE attribut=3 AND truc="truc"
par exemple
je te passe tout le code des que j'ai fini d'installer visual C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
private static int G_Etendue = 7;
private static string G_CAction = "toto";
private static int SQL_DEbAph = 1;
private static int SQL_DebApMin = 1;
private static int SQL_ApH = 1;
private static int SQL_ApMin = 1;
Console.Write(" Nombre de ligne : " + L_LANGAGE2SQL.NbLigne);
//--------------------------------------------------------------------------
Console.Write("\n count résolu, attente ...\n");
Console.ReadKey();
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
namespace ConsoleApplication1
{
class LANGAGE2SQL
{
public string Cible = "";
public string CSecteur = "";
public byte EtatVal = 0;
public Boolean Found = false;
public string From = "";
public string GroupBy = "";
public string Into = "";
public string IntoDbf = "";
public uint NbErrTransac = 0;
public int NbLigne = 0;
public int NomConnection = 0; // a transformer en pointeur
public string OrderBy = "";
public uint ResConnect = 0;
public string Select = "";
public string SourceDbf = "";
public string Type = "";
public string Values = "";
public string Where = "";
public string XExec = "";
public string XInto = "";
public string XSet = "";
public string XVarVal="";
public string XValues ="";
public string XVar="";
public string XVal="";
ArrayList Tabstring = new ArrayList();
string[] Tabmot;
char[] tonTableaudeChar;
SqlConnection connection ;
SqlCommand command;
SqlTransaction transaction;
DataSet Dataset = new DataSet();
Boolean trouve = false;
SqlParameter[] TabParam= new SqlParameter[50];
int nb_param = 0;
int nb_string = 0;
ArrayList TableDefini = new ArrayList();
// Affecte la valeur issue de la base de données à une variable de la classe Program
private void SetValue(string varName, DataRow dataRow)
{
FieldInfo field = typeof(Program).GetField(varName, BindingFlags.NonPublic | BindingFlags.Static);
if (field == null)
throw new ArgumentException("La variable '" + varName + "' n'est pas définie dans la classe Program");
field.SetValue(null, dataRow[varName]);
}
//cherche le nom du parametre dans la tableDefini, renvoie true si trouvé
private Boolean existe(string varName)
{
Boolean hum=false;
Console.Write("\n\nRecherche du parametre : @" + varName + " dans TableDefini ...");
for (int i = 0; TableDefini.Count > i; i++)
if (varName == TableDefini[i].ToString())
{
Console.Write("\nParametre " + varName + " déja existant : "+TableDefini[i].ToString() );
hum = true;
break;
}
else
{
hum = false;
Console.Write("\nParametre " + varName + " non trouvé : " + TableDefini[i].ToString() );
}
Console.Write("\nFin recherche");
if (TableDefini.Count == 0)
Console.Write(" : aucun element dans TableDefini !");
return hum;
}
public Boolean existestring(string varName)
{
Boolean hum = false;
Console.Write("\n\nRecherche de la chaine : " + varName + " dans la Tabstring");
for (int i = 0; Tabstring.Count > i; i++)
if (varName == Tabstring[i].ToString())
{
Console.Write("\nChaine" + varName + " déja existante : " + Tabstring[i].ToString() );
hum = true;
break;
}
else
{
hum = false;
Console.Write("\nChaine " + varName + " non trouvée : " + Tabstring[i].ToString() );
}
Console.Write("\nFin recherche");
if (Tabstring.Count == 0)
Console.Write(" : aucun element dans Tabstring !");
return hum;
}
// Retourne un SqlParameter affecté de la valeur d'une variable d'après son nom
private SqlParameter GetParameter(string varName)
{
FieldInfo field = typeof(Program).GetField(varName, BindingFlags.NonPublic | BindingFlags.Static);
if (field == null)
throw new ArgumentException("La variable '" + varName + "' n'est pas définie dans la classe Program");
public void DisConnect()
{
try
{
Console.Write("\nDeconnexion !\n");
if (this.NbErrTransac == 0)
{
transaction.Commit();
Console.Write("C'est tout bon ! Commit !\n");
}
else
{
transaction.Rollback();
Console.Write("Il y a eu une erreur ! Rollback !\n");
}
public void parser(string BOOM)
{
string chaine;
string chainetmp;
string mot;
int position,k,save=0;
chaine = BOOM;
mot = "";
position 0; k 0;
Console.Write("\n\nDebut du parser ....");
for (int z = 0; chaine.Length > z; z++)
{
if (chaine[z] == '?')
{
tonTableaudeChar = chaine.ToCharArray();
tonTableaudeChar[z] = '@';
chaine = new String(tonTableaudeChar);
}
}
for (int i = 0; chaine.Length > i; i++)
{
if (chaine[i] == '@')
{
position = i;
chainetmp = chaine.Substring(position + 1);
for (int j = 0; chainetmp.Length > j; j++)
{
if (chainetmp[j] != ',' && chainetmp[j] != ' ' && chainetmp[j] != ')')
{
mot = mot + chainetmp[j];
k++;
}
else
{
save = k;
k = 0;
break;
}
}
Console.Write("\n\nVariable découverte : " + mot.Trim() + ", test d'existence dans Tabstring");
if (!(existestring(mot.Trim())))
{
Console.Write("\nParser : "+ mot.Trim()+" stocké dans Tabstring");
Tabstring.Add(mot.Trim());
mot = "";
save = 0;
this.nb_string++;
}
else
{
Console.Write("\nParser : mot existant dans Tabstring, non stocké");
mot = "";
save=0;
}
public void P_selectSQL()
{
try
{
// Seulement si Select, From et Into sont définis!!!
if (!(this.Select "") && !(this.From "") && !(this.IntoDbf == ""))
{
// Select
XExec = "SELECT " + this.Select;
// From
XExec = XExec + " FROM " + this.From;
// Where
string Xwhere = "";
string XN4CSecteur;
int XBlanc;
if (!(this.Where == ""))
{
Xwhere = "(" + this.Where + ")";
}
if (!(this.CSecteur == ""))
{
XN4CSecteur = "CSecteur";
public void P_InsertSQL()
{
try
{
// Seulement si Cible, Into et Values sont définis!!!
if (!(this.Cible "") && !(this.Into "") && !(this.Values == ""))
{
// Cible
XExec = "INSERT " + this.Cible;
// Into
XExec = XExec + " (" + this.Into + ")";
// Values
if (this.Values.Substring(0, 1) == "(")
{
public void P_UpdateSQL()
{
// Seulement si Cible, Into et Values sont définis!!!
if (!(this.Cible "") && !(this.Into "") && !(this.Values == ""))
{
// Cible
XExec="UPDATE "+this.Cible;
// Création de la clause SET
string[] TabInto;
string[] TabValues;
XInto=this.Into;
XValues=this.Values;
XSet="";
XVarVal="";
string yahou="";
//-------------------------------TEST - solution 1 - TEST ----------------------------------
parser(XExec); // choppe toutes mes variables ? quelquechose dans un Tabstring sans le ?
for (int i = 0; i < nb_string; i++) // créé les parametres
{
Console.Write("\n\nDebut du test d'existence du paramètre "+Tabstring[i]+" dans TableDefini");
trouve = existe(Tabstring[i].ToString());
if (!trouve)
{
Console.Write("\nParamètre " + Tabstring[i] + " non trouvé, début de la phase de construction du paramètre");
TabParam[i] = GetParameter(Tabstring[i].ToString()); // créé le param
command.Parameters.Add(ChercheParam(Tabstring[i].ToString())); // ajoute le parametre a la commande
TableDefini.Add(Tabstring[i].ToString());
Console.Write("\nCréation de : " + TabParam[i].ToString());
}
else
{
command.Parameters.Add(ChercheParam(Tabstring[i].ToString())); // ajoute le parametre a la commande
Console.Write("\nLe paramètre " + Tabstring[i] + " existe, valeur éditée!");
}
}
//------------------------------ FIN TEST - solution 1 - FIN TEST --------------------------
command.CommandText = XExec;
Console.Write("\n\ncommandetext : " + command.CommandText);
Console.Write("\n\nAffectation des parametres a la commande .... execution");
SqlDataReader reader = command.ExecuteReader();
this.Found =reader.HasRows;
reader.Close();
if (this.Type == "SELECT")
{
Dataset = RecupDataSet(command);
Console.Write("test => SELECT");
for (int i = 0; i
En fait j'avais justement créé tabledefini pour que entre les requêtes je garde une liste de tout les paramètres existants, uniques dans la table (d’où un petit test d'unicité pour les ajouts) car on peut éditer les paramètres et du coup on ne les recréé pas (j'avais eu une erreur : paramètre déjà déclaré, alors je me suis dit je vais les stocker et plus les déclarer )
Après c'est le premier code que je fais dans ce langage donc effectivement j'ai peut être fait une soupe pour des choses très simples
Vérifie qu'avant d'exécuter la commande SQL tu ais bien mis command.CommandType = CommandType.Text;
C'est peut être qu'il pense exécuter une procédure stockée...
Autrement je vois pas !