Auto-configuration des param. d'une StoredProcedure (possible ?)

Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
-
Bonjour,

Je cherche à utiliser une procédure stocké (SQL-Serveur) en C#.
Rien de bien passionnant quoi ^^

Mais je suis surpris par le fait de devoir configurer mes paramètres de ma procédure stocké à la main. Le but étant de pouvoir les modifier, par exemple passer un param. à 60 carac. car finalement 50 n'est plus suffisant, une fois l'appli en exploitation, sans avoir forcément a tout recompiler.

Je m'attendait à pouvoir interroger le serveur sur le nombre et la config de ces paramètre. (du style ".InitParameters()" )

Et je suis très étonner de ne pas trouver ça, j'utilise des objets Ms. avec une base Ms. et je doit tout déclarer des deux coté ?!?!

Aller un piti bout de code quand même :
Coté appli (ce que je voudrait mais la fonction JeVoudraitDemanderASQLServeurLesParametres n'existe pas ^^) :
                lock (VarGlobal.GConnexion)
                {

                    //Création & init de l'objet dédier à l'execution de la procédure stockée
                    System.Data.SqlClient.SqlCommand SP_Command = new System.Data.SqlClient.SqlCommand();
                    SP_Command.Connection = VarGlobal.GConnexion;
                    SP_Command.CommandType = System.Data.CommandType.StoredProcedure;
                    SP_Command.CommandText = "dbo.NomDeMaProc";
                    // !---------!
                    SP_Command.JeVoudraitDemanderASQLServeurLesParametres();
                    // !---------!
                    SP_Command.Parameters["@iParamUn"].Value = "12"; //ba oui faut bien une valeur ^^
                }

Coté serveur SQL (déclaration de la proc)
CREATE PROCEDURE ASVC_SFI_LOAD_TMP_TBL 
--ALTER PROCEDURE ASVC_SFI_LOAD_TMP_TBL 
      (@iParamUn varchar(50),
      @iParamDeux varchar(50),
      @ParamInt int,
      @iParamDate DATETIME,
      @iParamDate DATETIME,
      @oValRetour int OUT)

AS
SET NOCOUNT ON
BEGIN
-- Code de la proc
END


Donc bà je cherche la fonction JeVoudraitDemanderASQLServeurLesParametres ;)

Merci d'avance et bonne soirée :)

Amicalement
Afficher la suite 

5 réponses

Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
-_-

Je viens de récup un code qui fait ça (auto-config des paramètres).

Mais c'est avec ADO, je pense que mon problème viens de là (il me semblait bien aussi que j'avais déjà vue des paramètres se créer tout seuls).

Le code est en VBA, je le poste quand même :
Set cnnConnect = New ADODB.Connection
    cnnConnect.ConnectionString = "DSN=" & Dsn
    cnnConnect.Open
        
    ' Initialisation de l'objet
    Set cmdProc = New ADODB.Command
    cmdProc.ActiveConnection = cnnConnect
    cmdProc.CommandText = "dbo.ProcName"
    cmdProc.CommandType = adCmdStoredProc
    ' Affectation des paramètres
    cmdProc(1).Value = ParamUn
    cmdProc(2).Value = ParamDeux
    ...
    cmdProc(n).Value = ParamN
    ' Exécution
    Set rstRecordset = cmdProc.Execute()



Si qq'un sait faire la mm chose avec System.Data.SqlClient. je suis toujours preneur ;)
Commenter la réponse de Polack77
Messages postés
13980
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
319
0
Merci
Bonjour, je ne fais pas de BDD, mais une tour sur mon moteur de recherche m'a amené ici
http://www.developpez.net/forums/d187658/dotnet/acces-aux-donnees/csharp-r-cup-rer-retour-d-proc-dure-stock-e/#post1210786

Cela répond t il à ta question?
Commenter la réponse de Whismeril
Messages postés
1098
Date d'inscription
mercredi 22 mars 2006
Statut
Membre
Dernière intervention
22 octobre 2019
0
Merci
Merci pour ta réponse :)

Mais non ça ne répond pas à mon problème. (Qui est plus une exploration des possibilités de SqlClient plutôt qu'un "problème" à proprement parler).

Dans le lien que tu me donne :
Param = New SqlParameter(`@begin_date', sqldbtype.DateTime)

Soit la création du paramètre (je sais faire, en attendant j'ai fait un équivalent :
SP_Command.Parameters.Add(
                        new System.Data.SqlClient.SqlParameter("@begin_date",
                                                               System.Data.SqlDbType.DateTime));


Et dans les deux cas je déclare mon paramètre "as DateTime". Si je fait évoluer ma procédure stocké car finalement je veux un DateTime2, je vais devoir modifier mon code, et recompiler.

Ce que je cherche :
Que SqlClient interroge Ms.SqlServeur sur le type, la taille, ..., des paramètres.
En effet si je change le nom de mon paramètre, mon programme pourrait ne plus fonctionné (normal).
Mais si ça fonctionnait comme je veux(entre SqlClient et MsSqlServeur). Et que j'ajoutais un paramètre optionnel ("NULLABLE") à ma procédure, mon programme réagirais proprement (paramètre déclarer avec une valeur à NULL). Sans recompile ni rien (idem pour un changement de taille, ou même un changement de type vers un type très proche DateTime -> DateTime2; int -> long; ...)

En gros je cherche à faire en sorte que SqlClient réagisse comme les objets ADO du VBA. Et je suis pas certain que ça sois possible en fait :/
Whismeril
Messages postés
13980
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
319 -
Je ne sais pas, peut etre avec Linq et des types anonymes?
cgandco
Messages postés
219
Date d'inscription
mercredi 26 octobre 2011
Statut
Membre
Dernière intervention
22 juin 2017
8 -
Bonjour,

Je ne connais pas de méthode pour faire cela, mais c'est un beau projet de classe en analysant les tables system de sql server.

Mais attention, ce n'est pas logique de changer le type des données après le développement d'un programme.

cette classe peut être utile pour faciliter la programmation.

bonne journée
Commenter la réponse de Polack77
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
17
0
Merci
Salut,

d'une part le code VB que tu donnes ne configure pas les paramètres de manière automatique.
La seule chose qu'il fait est de ne pas "typer" le paramètre.

Il est tout a fait possible de le faire en C#, car SqlClient sait mapper les types de .net vers SQL.

D'autre part, la méthode de lecture d'une table ou d'une vue système "sys.procedures" pour en extraire les informations de paramètre n'est pas forcément une bonne solution. (performances)

Voici une méthode pour appeler des proc. stockées (il manque juste la gestion des paramètres OUPUT et ReturnValue)
Cette méthode permet aussi de renvoyer un resultset si necessaire.

La méthode :
On peut facilement passer cette méthode en statique et lui donner la connexion directement en paramètre (ici, c'est une méthode d'instance qui utilise une connexion déjà créée)

public DataTable ExecuteStoredProc(string sStoredProc, object[] oParams, bool bWithResultset)
{
 // m_conn et m_connectionStr sont définis ailleurs

    SqlDataAdapter adap = null;
    DataTable dt = (bWithResultset ? new DataTable() : null);
    try
    {
     if(m_conn == null) return null;
     if( m_conn.State != ConnectionState.Open )
         m_conn.Open();
        adap = new SqlDataAdapter(sStoredProc, m_connectionStr);
        adap.SelectCommand.CommandType = CommandType.StoredProcedure;
        adap.SelectCommand.CommandTimeout = 180;

        int i = 0;
        string typ = "";
        object val = null;
        string paramName = "";
        if (oParams != null && oParams.GetLength(0) > 0)
        {
            while (i < oParams.Length)
            {
                if (i % 3 == 0)
                    val = oParams[i];
                else
                {
                    typ = Convert.ToString(oParams[i]);
                    i++;
                    paramName = Convert.ToString(oParams[i]);
                    adap.SelectCommand.Parameters.AddWithValue(paramName, val);
                }
                i++;
            }
        }
        if (!bWithResultset)
            adap.SelectCommand.ExecuteNonQuery();
        else
            adap.Fill(dt); 
            
        return dt;
    }
    catch (Exception exc)
    {
        throw new Exception(exc.Message);
    }
    finally
    {
        // si on veut fermer la connexion ici
        if(m_conn == null)  m_conn.Close();
    }
}


Exemple d'appel :

// Les types SQL sont purement informatifs, SqlClient sait faire le mapping entre .net et SQL via Parameters.AddWithValue()

// exemple 1 : avec parametres et resultset en retour
object[] oParamsStoredProc = new object[]
{
    999,  "Decimal", "@id",
    "toto", "Varchar", "@str",
    0,  "Bit",  "@debug",
    Datetime.Now, "Datetime", "@date"
};
DataTable dt = ExecuteStoredProc("nomProcedure", oParamsStoredProc, false);


//exemple 2 : sans parametre et sans resultset
ExecuteStoredProc("nomProcedure", null, false);



bye...
Whismeril
Messages postés
13980
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
319 -
EDIT : Ajout du LANGAGE dans les balises de code.
Explications disponibles ICI

Merci d'y penser dans tes prochains messages.
yann_lo_san
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
17 > Whismeril
Messages postés
13980
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
-
oui merci Whismeril,

en fait j'ai fait ce post depuis le boulot (IE 7 et windows XP)
et la liste des langages n'apparait pas bizarrement.

bye....
Whismeril
Messages postés
13980
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 novembre 2019
319 > yann_lo_san
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
-
IE7.... il faut les taper à la main
Commenter la réponse de yann_lo_san
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
17
0
Merci
Petit bug dans le finally
il faut bien sur mettre : != null
finally    {    if(m_conn != null)  m_conn.Close();    }
Commenter la réponse de yann_lo_san