Avatar billede bilal_isa Nybegynder
07. august 2008 - 00:04 Der er 7 kommentarer og
1 løsning

C# og MySQL stored procedures

Hej,

Jeg har problemer med at afvikle MySQL stored procedure fra en C# applikation. Når jeg udfører en stored procedure rejser C# en OdbcException som siger at der er fejl i min MySQL syntaks, men jeg har testet proceduren gennem MySQL Query Browser og den virker som den skal.

Sådan ser min MySQL stored procedure ud:

CREATE PROCEDURE `tilfoej_ansat`(in in_ansat_id varchar(6),
                                in in_navn varchar(50),
                                in in_adresse varchar(100),
                                in in_telefon char(8),
                                in in_email varchar(50),
                                in in_dato_ansat date,
                                in in_adgangskode varchar(20),
                                in in_tilstand varchar(10))
BEGIN
INSERT INTO ansat(ansat_id, navn, adresse, telefon, email, dato_ansat, adgangskode, tilstand)
VALUES (in_ansat_id, in_navn, in_adresse, in_telefon, in_email, in_dato_ansat, in_adgangskode, in_tilstand);
END

Jeg bruger en MySQL ODBC 5.1 driver til at åbne en forbindelse til min MySQL db.

public class Adgang
    {
        #region "Konstanter"

        public const String FORBINDELSE_STRENG = "DRIVER={MySQL ODBC 5.1 Driver};" +
                                                "SERVER=localhost;" +
                                                "DATABASE=frisoer_db;" +
                                                "UID=root;" +
                                                "PASSWORD=;" +
                                                "OPTION=3" ;

        #endregion

        #region "Datamedlemmer"

        private OdbcConnection mOdbcForbindelse;

        private OdbcCommand mOdbcKommando;

        private OdbcDataReader mOdbcDataLaeser;

        #endregion

        #region "Egenskaber"

        public OdbcConnection OdbcForbindelse
        {
            get
            {
                return this.mOdbcForbindelse;
            }
            set
            {
                this.mOdbcForbindelse = value;
            }
        }

        public OdbcCommand OdbcKommando
        {
            get
            {
                return this.mOdbcKommando;
            }
            set
            {
                this.mOdbcKommando = value;
            }
        }

        public OdbcDataReader OdbcDataLaeser
        {
            get
            {
                return this.mOdbcDataLaeser;
            }
            set
            {
                this.mOdbcDataLaeser = value;
            }
        }


        #endregion

        #region "Konstruktører"

        public Adgang()
        {
            this.mOdbcForbindelse = new OdbcConnection();
            this.mOdbcKommando = new OdbcCommand();
        }

        #endregion

        #region "Medlemsfunktioner"

        public void aabenForbindelse()
        {
            this.OdbcForbindelse.ConnectionString = Adgang.FORBINDELSE_STRENG;
            this.OdbcForbindelse.Open();
        }

        public void lukForbindelse()
        {
            this.OdbcForbindelse.Close();
        }

        #endregion
    }

Så bruger jeg følgende funktion til at indsætte i MySQL database tabellen. Det lykkes at åbne en forbindelse til serveren men når jeg udfører linien Adgang.OdbcKommando.ExecuteNonQuery(); får jeg den ovennævnte excepttion.

static public void tilfoejAnsat(String ansatId, String navn, String adresse, String telefon, String email, DateTime datoAnsat, String adgangskode, String tilstand)
        {
            Adgang Adgang = new Adgang();

            try
            {
                Adgang.aabenForbindelse();
                Adgang.OdbcKommando.Connection = Adgang.OdbcForbindelse;
                Adgang.OdbcKommando.CommandText = "tilfoej_ansat";
                Adgang.OdbcKommando.CommandType = CommandType.StoredProcedure;

                Adgang.OdbcKommando.Parameters.Add("@in_ansat_id", OdbcType.NVarChar);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_ansat_id", ansatId);
                Adgang.OdbcKommando.Parameters["@in_ansat_id"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("@in_navn", OdbcType.NVarChar);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_navn", navn);
                Adgang.OdbcKommando.Parameters["@in_navn"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("@in_adresse", OdbcType.NVarChar);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_adresse", adresse);
                Adgang.OdbcKommando.Parameters["@in_adresse"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("@in_telefon", OdbcType.NVarChar);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_telefon", telefon);
                Adgang.OdbcKommando.Parameters["@in_telefon"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("@in_email", OdbcType.NVarChar);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_email", email);
                Adgang.OdbcKommando.Parameters["@in_email"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("@in_dato_ansat", OdbcType.Date);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_dato_ansat", datoAnsat.Date);
                Adgang.OdbcKommando.Parameters["@in_dato_ansat"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("@in_adgangskode", OdbcType.NVarChar);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_adgangskode", adgangskode);
                Adgang.OdbcKommando.Parameters["@in_adgangskode"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("@in_tilstand", OdbcType.NVarChar);
                Adgang.OdbcKommando.Parameters.AddWithValue("@in_tilstand", tilstand);
                Adgang.OdbcKommando.Parameters["@in_tilstand"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.ExecuteNonQuery();
            }
            catch (OdbcException e)
            {
                MessageBox.Show(e.Message.ToString());
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message.ToString());
            }
            finally
            {
                Adgang.lukForbindelse();
            }
        }

Er der nogen der kan hjælpe?

På forhånd tak.
Avatar billede arne_v Ekspert
07. august 2008 - 00:15 #1
Forslag:

brug ikke både Add og AddWithValue (jeg forslår Add og så tildel Value)

skift fra OdbcType.NVarChartil OdbcType.VarChar

angive længde af VARCHAR i Add
Avatar billede arne_v Ekspert
07. august 2008 - 00:16 #2
Muligvis skal der bruges ?xx og ikke @xx for parameter navne.
Avatar billede bilal_isa Nybegynder
07. august 2008 - 01:30 #3
Hej igen,

Jeg har rettet koden til:

static public void tilfoejAnsat(String ansatId, String navn, String adresse, String telefon, String email, DateTime datoAnsat, String adgangskode, String tilstand)
        {
            Adgang Adgang = new Adgang();

            try
            {
                Adgang.aabenForbindelse();
                Adgang.OdbcKommando.Connection = Adgang.OdbcForbindelse;
                Adgang.OdbcKommando.CommandText = "tilfoej_ansat";
                Adgang.OdbcKommando.CommandType = CommandType.StoredProcedure;

                Adgang.OdbcKommando.Parameters.Add("?in_ansat_id", OdbcType.VarChar, 6);
                Adgang.OdbcKommando.Parameters["?in_ansat_id"].Value = ansatId;               
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_ansat_id", ansatId);
                Adgang.OdbcKommando.Parameters["?in_ansat_id"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("?in_navn", OdbcType.VarChar, 50);
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_navn", navn);
                Adgang.OdbcKommando.Parameters["?in_navn"].Value = navn;
                Adgang.OdbcKommando.Parameters["?in_navn"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("?in_adresse", OdbcType.VarChar, 100);
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_adresse", adresse);
                Adgang.OdbcKommando.Parameters["?in_adresse"].Value = adresse;
                Adgang.OdbcKommando.Parameters["?in_adresse"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("?in_telefon", OdbcType.Char, 8);
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_telefon", telefon);
                Adgang.OdbcKommando.Parameters["?in_telefon"].Value = telefon;
                Adgang.OdbcKommando.Parameters["?in_telefon"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("?in_email", OdbcType.VarChar, 50);
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_email", email);
                Adgang.OdbcKommando.Parameters["?in_email"].Value = email;
                Adgang.OdbcKommando.Parameters["?in_email"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("?in_dato_ansat", OdbcType.Date);
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_dato_ansat", datoAnsat.Date);
                Adgang.OdbcKommando.Parameters["?in_dato_ansat"].Value = datoAnsat.Date;
                Adgang.OdbcKommando.Parameters["?in_dato_ansat"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("?in_adgangskode", OdbcType.VarChar, 10);
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_adgangskode", adgangskode);
                Adgang.OdbcKommando.Parameters["?in_adgangskode"].Value = adgangskode;
                Adgang.OdbcKommando.Parameters["?in_adgangskode"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.Parameters.Add("?in_tilstand", OdbcType.VarChar, 10);
                //Adgang.OdbcKommando.Parameters.AddWithValue("@in_tilstand", tilstand);
                Adgang.OdbcKommando.Parameters["?in_tilstand"].Value = tilstand;
                Adgang.OdbcKommando.Parameters["?in_tilstand"].Direction = ParameterDirection.Input;

                Adgang.OdbcKommando.ExecuteNonQuery();
            }
            catch (OdbcException e)
            {
                MessageBox.Show(e.Message.ToString());
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message.ToString());
            }
            finally
            {
                Adgang.lukForbindelse();
            }
        }

Jeg desværre den samme exception: +        e    {"ERROR [42000] [MySQL][ODBC 5.1 Driver][mysqld-5.0.51a-community-nt]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'tilfoej_ansat' at line 1"}    System.Data.Odbc.OdbcException

Har du flere forslag?
Avatar billede arne_v Ekspert
07. august 2008 - 04:36 #4
Dette her virker:

using System;
using System.Data;

using MySql.Data.MySqlClient;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using(MySqlConnection con = new MySqlConnection("Data Source=localhost;Database=Test;User Id=root;Password="))
            {
                con.Open();
                MySqlCommand cre = new MySqlCommand("CREATE PROCEDURE demosp(f1 INTEGER, f2 VARCHAR(50)) BEGIN END", con);
                cre.ExecuteNonQuery();
                MySqlCommand exe = new MySqlCommand();
                exe.Connection = con;
                exe.CommandText = "demosp";
                exe.CommandType = CommandType.StoredProcedure;
                exe.Parameters.Add("?f1", MySqlDbType.Int32);
                exe.Parameters.Add("?f2", MySqlDbType.VarChar, 50);
                exe.Parameters["?f1"].Value = 1234;
                exe.Parameters["?f2"].Value = "ABCD";
                exe.ExecuteNonQuery();
                MySqlCommand drp = new MySqlCommand("DROP PROCEDURE demosp", con);
                drp.ExecuteNonQuery();
            }
        }
    }
}
Avatar billede arne_v Ekspert
07. august 2008 - 04:36 #5
Det var så med MySQL connector. Jeg prøver lige med ODBC også.
Avatar billede arne_v Ekspert
07. august 2008 - 04:38 #6
Dette virker også:

using System;
using System.Data;
using System.Data.Odbc;

namespace E
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using(OdbcConnection con = new OdbcConnection("Data Source=localhost;Database=Test;User Id=root;Password="))
            {
                con.Open();
                OdbcCommand cre = new OdbcCommand("CREATE PROCEDURE demosp(f1 INTEGER, f2 VARCHAR(50)) BEGIN END", con);
                cre.ExecuteNonQuery();
                OdbcCommand exe = new OdbcCommand();
                exe.Connection = con;
                exe.CommandText = "demosp";
                exe.CommandType = CommandType.StoredProcedure;
                exe.Parameters.Add("?f1", OdbcType.Int);
                exe.Parameters.Add("?f2", OdbcType.VarChar, 50);
                exe.Parameters["?f1"].Value = 1234;
                exe.Parameters["?f2"].Value = "ABCD";
                exe.ExecuteNonQuery();
                OdbcCommand drp = new OdbcCommand("DROP PROCEDURE demosp", con);
                drp.ExecuteNonQuery();
            }
        }
    }
}
Avatar billede bilal_isa Nybegynder
07. august 2008 - 11:17 #7
Hej igen,

Problemet var tilsyneladende min Adgang.OdbcKommando.CommandText. Efter jeg har ændret den til følgende virker det.

                Adgang.OdbcKommando.CommandText = "call tilfoej_ansat(?, ?, ?, ?, ?, ?, ?, ?)";

Arne skriver du lige et svar så du kan få point?
Avatar billede arne_v Ekspert
07. august 2008 - 15:04 #8
OK
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester