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

Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 - Modifié par Polack77 le 7/10/2015 à 18:20
Whismeril Messages postés 17818 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 2 octobre 2022 - 14 oct. 2015 à 20:57
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

5 réponses

Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
8 oct. 2015 à 09:32
-_-

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 ;)
0
Whismeril Messages postés 17818 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 2 octobre 2022 618
8 oct. 2015 à 10:08
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?
0
Polack77 Messages postés 1098 Date d'inscription mercredi 22 mars 2006 Statut Membre Dernière intervention 22 octobre 2019 1
8 oct. 2015 à 13:21
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 :/
0
Whismeril Messages postés 17818 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 2 octobre 2022 618
8 oct. 2015 à 13:30
Je ne sais pas, peut etre avec Linq et des types anonymes?
0
cgandco Messages postés 219 Date d'inscription mercredi 26 octobre 2011 Statut Membre Dernière intervention 22 juin 2017 9
14 oct. 2015 à 09:25
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
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 23
Modifié par Whismeril le 14/10/2015 à 19:01
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...
0
Whismeril Messages postés 17818 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 2 octobre 2022 618
14 oct. 2015 à 19:01
EDIT : Ajout du LANGAGE dans les balises de code.
Explications disponibles ICI

Merci d'y penser dans tes prochains messages.
0
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 23 > Whismeril Messages postés 17818 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 2 octobre 2022
14 oct. 2015 à 20:34
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....
0
Whismeril Messages postés 17818 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 2 octobre 2022 618 > yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016
14 oct. 2015 à 20:57
IE7.... il faut les taper à la main
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
yann_lo_san Messages postés 1137 Date d'inscription lundi 17 novembre 2003 Statut Membre Dernière intervention 23 janvier 2016 23
14 oct. 2015 à 13:57
Petit bug dans le finally
il faut bien sur mettre : != null
finally    {    if(m_conn != null)  m_conn.Close();    }
0