Avatar billede hald. Nybegynder
17. oktober 2004 - 20:34 Der er 36 kommentarer og
1 løsning

angive en Int-værdi i oprettelsen af en SQL command-parameter ?

Hej godtfolk,

Hvordan kan jeg angive en parameters Int-værdi i oprettelsen af en command-objekt? F.eks. i nedenstående insert-metode:

------- KLIP ---------

public int insert(string name, string description, int open, string password, int player_id)
{
    // vi opretter en forbindelse til DBen
    MySqlConnection oConn        = GetConnection();
    MySqlDataAdapter oAdapter    = new MySqlDataAdapter();
    MySqlCommand oCommand;
           
    try
    {
        // åbner forbindelsen til DB'en:
        oConn.Open();
       
        // Vi brygge vores INSERT query sammen:
        oCommand = new MySqlCommand("INSERT INTO league(name, description, is_open, password)VALUES (@name, @description, @open, @password)", oConn);

oCommand.Parameters.Add(@name,MySqlDbType.VarChar, 100, "name");
oCommand.Parameters.Add(@description, MySqlDbType.String, 5000, "description");
oCommand.Parameters.Add(@open, MySqlDbType.Int, 1, "open");
...
------- KLIP ---------

Men den kan ikke lide:

oCommand.Parameters.Add(@open, MySqlDbType.Int, 1, "open");

...pga. at <open> er en int ???

Har også prøvet med:
oCommand.Parameters.Add(@open.ToString(), MySqlDbType.Int, 1, "open");

...men så får jeg bare fejlen runtime (Specified cast is not valid.)


Jeg går ud fra at det er meget simpelt, men jeg har ikke rigtig kunne finde løsningen.
Avatar billede arne_v Ekspert
17. oktober 2004 - 20:39 #1
Skal det ikke være:

oCommand.Parameters.Add("@name",MySqlDbType.VarChar, 100, "name");
oCommand.Parameters.Add("@description", MySqlDbType.String, 5000, "description");
oCommand.Parameters.Add("@open", MySqlDbType.Int, 1, "open");

?
Avatar billede arne_v Ekspert
17. oktober 2004 - 20:39 #2
altså "" omkring @xxxx
Avatar billede hald. Nybegynder
17. oktober 2004 - 20:45 #3
det kunne jo MEGET vel tænkes ;-) ....men jeg får desværre stadig en "Specified cast is not valid." når jeg prøver at indsætte. :-(
Avatar billede arne_v Ekspert
17. oktober 2004 - 20:48 #4
Hvordan giver du parameterne værdier ?
Avatar billede hald. Nybegynder
17. oktober 2004 - 20:51 #5
jeg foretager selve kaldet i mit presentationslag:

------ KLIP ---------

private void butCreateLeague_Click(object sender, System.EventArgs e)
{
    //    Her skal der noget automatisk validation på i stedet !!!
    string name        = txtLeagueName.Text;
    string description    = txtLeagueDescription.Text;
    string password1    = txtLeaguePassword.Text;
    string password2    = txtLeaguePasswordConfirm.Text;
    int open = 1;

    if(radClose.Checked)
        open = 0;
               
    try
    {

        if(password1.Equals(password2))
        {           
            BLLeague oBLLeague = new BLLeague();
            int id = oBLLeague.insert(name, description, open, password1);
            Label1.Text = "GENERERET ID: "+id.ToString();
        }
        else
            Label1.Text = "PASSWORD STEMMER IKKE ENS !";
    }
    catch (Exception oException)
    {
        //Label1.Text = ""+oException.Message +": <br>";
        //Label1.Text += ""+oException;
        throw oException;
    }

}

------ KLIP ---------
Avatar billede arne_v Ekspert
17. oktober 2004 - 20:55 #6
Jeg mener har du:

oCommand.Parameters["@name"] = name;
oCommand.Parameters["@description"] = description;
oCommand.Parameters["@open"] = open;

nedenunder at du Add'er parameterne ?
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:02 #7
ahh.... 2 min, Arne. Prøver lige at se om det ikke løser problemet
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:09 #8
Den vil sgu ikke rigtig lade mig tildele dem på den måde.

Du kan lige se hele min insert-metode. Selve parameterne bliver så parameteroverført når metoden kaldes i præsentationslaget:

----- KLIP -----

public int insert(string name, string description, int open, string password, int player_id)
{
    // vi opretter en forbindelse til DBen
    MySqlConnection oConn        = GetConnection();
    MySqlDataAdapter oAdapter    = new MySqlDataAdapter();
    MySqlCommand oCommand;
   
    try
    {
        // åbner forbindelsen til DB'en:
        oConn.Open();

        // Vi begynder at brygge vores INSERT query sammen i form af en MySqlCommand-objekt:
        oCommand = new MySqlCommand("INSERT INTO league(name, description, is_open, password)"+
                                    "VALUES (@name, @description, @open, @password)", oConn);

        //    Her opretter vi de forskellige parametre (med angivelse af selve datatypen),
        //    som vi tilføjer til vores MySqlCommand-objekt - der reelt er vores SQL query:
        oCommand.Parameters.Add("@name",        MySqlDbType.VarChar    , 100    , "name");
        oCommand.Parameters.Add("@description",    MySqlDbType.String    , 5000    , "description");
        oCommand.Parameters.Add("@open",        MySqlDbType.Int        ,1        , "open");
        oCommand.Parameters.Add("@password",    MySqlDbType.VarChar    , 100    , "password");


        oCommand.Parameters["@name"]        = name;
        oCommand.Parameters["@description"] = description;
        oCommand.Parameters["@open"]        = open;
        oCommand.Parameters["@password"]    = password;

        //    Fortæller adapter at vi vil udføre en INSERT query, og sætter den til at
        //    være lig vores ovenstående og nyopbyggede MySqlCommand-objekt:
        oAdapter.InsertCommand = oCommand;
       
       
        oCommand = new MySqlCommand("SELECT @@IDENTITY", oConn);
        int id = (int)oCommand.ExecuteScalar();

        return id;
    }
    catch (Exception oException)
    {
        throw oException;
    }
    finally
    {
        // forbindelsen til DBen lukkes
        oConn.Close();
    }       
}//insert

----- KLIP -----
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:10 #9
du skal ikke tage dig af at den sidste paramter ikke anvendes.
Avatar billede arne_v Ekspert
17. oktober 2004 - 21:10 #10
Det er mig som er en spade.

        oCommand.Parameters["@name"].Value        = name;
        oCommand.Parameters["@description"].Value = description;
        oCommand.Parameters["@open"].Value        = open;
        oCommand.Parameters["@password"].Value    = password;
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:16 #11
Hehe... eller også er det bare mig der er våd bag ørene - den bør jeg selv have fanget.

MEN,...jeg får stadig den skod-fejl:
Exception Details: System.InvalidCastException: Specified cast is not valid.
Avatar billede arne_v Ekspert
17. oktober 2004 - 21:19 #12
Jeg tror eventiuelt at fejlen ligger et helt andet sted:

int id = (int)oCommand.ExecuteScalar();

Prøv f.eks.:

object o = oCommand.ExecuteScalar();
Console.WriteLine(o.ToString() + " " + o.GetType());
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:20 #13
kan det ikke være der hvor jeg trække mit ID ud, og sender det retur ???
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:21 #14
så ikke lige dit indlæg - prøver lige lykken :-)
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:25 #15
Prøvede med:

        //oCommand = new MySqlCommand("SELECT @@IDENTITY", oConn);
    int id = 10; //(int)oCommand.ExecuteScalar();

    object o = oCommand.ExecuteScalar();
    Console.WriteLine(o.ToString() + " " + o.GetType());


    return id;
}


men får så bare en:

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:26 #16
lige et spørgsmål til:
---> Console.WriteLine(o.ToString()...

jeg har jo ikke nogen konsol (som man f.eks. har i Netbeans), hvor jeg kan se sådan et output - ...eller har jeg ???
Avatar billede arne_v Ekspert
17. oktober 2004 - 21:28 #17
oCommand = new MySqlCommand("SELECT @@IDENTITY", oConn);
    int id = 10; //(int)oCommand.ExecuteScalar();

    object o = oCommand.ExecuteScalar();
    Console.WriteLine(o.ToString() + " " + o.GetType());
Avatar billede arne_v Ekspert
17. oktober 2004 - 21:30 #18
Hvis det er en GUI app så:

MessageBox.Show(o.ToString() + " " + o.GetType());
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:30 #19
det er HELT sikkert der fejlen ligger. For den indsætter fint, når jeg bare returnerer værdien 10.

prøver lige det forslag
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:32 #20
Det er en ASP.NET app... Der er da ikke nogen mulighed for at se konsol output eller lignende, er der? Det ville gøre livet en del lettere
Avatar billede arne_v Ekspert
17. oktober 2004 - 21:38 #21
Der er mulighed for noget "Trace".
Avatar billede arne_v Ekspert
17. oktober 2004 - 21:39 #22
Men prøv evt. med:

int id = (int)(decimal)oCommand.ExecuteScalar();

eller

int id = int.Parse(oCommand.ExecuteScalar().ToString());
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:40 #23
Hvordan får jeg så parset indsættelsens generede id, så jeg kan smide det retur ?

oCommand = new MySqlCommand("SELECT @@IDENTITY", oConn);
id = (int)oCommand.ExecuteScalar(); <-- det er jo her at min casting fejler
Avatar billede hald. Nybegynder
17. oktober 2004 - 21:56 #24
ved ikke lige hvad der sker for mig, men nu vil indsætter den ikke igen. Og derfor returnerer "int id = int.Parse(oCommand.ExecuteScalar().ToString());" bare værdien 0 !

Men umiddelbar lader det jo til at virke
Avatar billede arne_v Ekspert
17. oktober 2004 - 22:11 #25
Jeg har før haft problemer med at der blev returneret en anden type end man
umiddelbart troede.

Og int.Parse(o.ToString()) er ret "type usikker sikker".
Avatar billede hald. Nybegynder
17. oktober 2004 - 22:21 #26
Cool udtryk :-)

Kender du det, man føler lige at man reelt HAR løst sit problem, og så fucker den skide kode med en alligevel (Grrr...) ;-) Nok mest fordi man er lidt blank !

Men kan du greje hvorfor fan... den ikke indsætter:

---- KLIP ----

public int insert(string name, string description, int open, string password, int player_id)
{
    // vi opretter en forbindelse til DBen
    MySqlConnection oConn        = GetConnection();
    MySqlDataAdapter oAdapter    = new MySqlDataAdapter();
    MySqlCommand oCommand;
   
    try
    {
        // åbner forbindelsen til DB'en:
        oConn.Open();

        // Vi begynder at brygge vores INSERT query sammen i form af en MySqlCommand-objekt:
        oCommand = new MySqlCommand("INSERT INTO league(name, description, password)"+
                                    "VALUES (@name, @description, @open, @password)", oConn);

        //    Her opretter vi de forskellige parametre (med angivelse af selve datatypen),
        //    som vi tilføjer til vores MySqlCommand-objekt - der reelt er vores SQL query:
        oCommand.Parameters.Add("@name",        MySqlDbType.VarChar    , 100    , "name");
        oCommand.Parameters.Add("@description",    MySqlDbType.String    , 5000    , "description");
        oCommand.Parameters.Add("@open",        MySqlDbType.Int        ,1        , "open");
        oCommand.Parameters.Add("@password",    MySqlDbType.VarChar    , 100    , "password");


        oCommand.Parameters["@name"].Value            = name;
        oCommand.Parameters["@description"].Value    = description;
        oCommand.Parameters["@open"].Value            = open;
        oCommand.Parameters["@password"].Value        = password;

        //    Fortæller adapter at vi vil udføre en INSERT query, og sætter den til at
        //    være lig vores ovenstående og nyopbyggede MySqlCommand-objekt:
        oAdapter.InsertCommand = oCommand;
       
       
        oCommand = new MySqlCommand("SELECT @@IDENTITY", oConn);
        int id = int.Parse(oCommand.ExecuteScalar().ToString());

        return id;
    }
    catch (Exception oException)
    {
        throw oException;
    }
    finally
    {
        // forbindelsen til DBen lukkes
        oConn.Close();
    }       
}//insert

---- KLIP ----

Jeg tror godt at jeg vil smide en 50'er på at jeg har overset en eller anden meget tydelig fejl - tjaa... det må næsten være pengene lige ned i foret ;-)



og bortset fra det - er det den "rigtige" måde jeg trække mit ID ud på. Regnede lidt med at der fandtes en metode alá noget i stil med "getInsertedRowID()".
Avatar billede arne_v Ekspert
17. oktober 2004 - 22:23 #27
oCommand = new MySqlCommand("INSERT INTO league(name, description, password)"+
                                    "VALUES (@name, @description, @open, @password)", oConn);

Jeg tæller 3 feltnavne og 4 værdier !?!?
Avatar billede arne_v Ekspert
17. oktober 2004 - 22:24 #28
Jeg har aldrig set en getInsertedRowID(), så ...
Avatar billede hald. Nybegynder
17. oktober 2004 - 22:31 #29
yes... den er nu rettet, men det hjalp alligevel ikke det store. Men nu får vi da alle data ind i databasen,...når det engang lykkes.

oCommand = new MySqlCommand("INSERT INTO league(name, description, open, password)"+
            "VALUES (@name, @description, @open, @password)", oConn);


hmm.... arbejder lidt videre
Avatar billede arne_v Ekspert
17. oktober 2004 - 22:33 #30
Noget helt andet.

Mangler du ikke at udføre INSERT ?

Altså:
  oCommand.ExecuteNonQuery();
Avatar billede hald. Nybegynder
17. oktober 2004 - 22:40 #31
det var jo det jeg gjorde, du skønne, flinke og yderst kompetente Arne ;-)

1000-tak for hjælpen. Lig et svar og få et par velfortjente point..
Avatar billede arne_v Ekspert
17. oktober 2004 - 22:42 #32
svar
Avatar billede hald. Nybegynder
17. oktober 2004 - 23:02 #33
Lige et hurtigt spørgsmpl, Arne

Hvad opnår man - eller er der en fordel - ved, manuelt at angive parameterne? Jeg ved at man kan lave en direkte query ala:
oCommand = new MySqlCommand("INSERT INTO league(name, description, open, password)"+
            "VALUES "+ name +","+ description +", "+ open +", "+password +")", oConn);

men er der en specifik grund til at gøre det ?
Avatar billede arne_v Ekspert
17. oktober 2004 - 23:04 #34
Ovenstående med direkte konkatanering af SQL streng er helt fint til demo brug.

Til seriøs brug skal du bruge parameters.

Hvis ikke vil det ikke tage nogle hackere lang tid at opdage de kan
lave SQL injection på din web site.
Avatar billede hald. Nybegynder
17. oktober 2004 - 23:08 #35
ok,...så det reelle argument er "sikkerhed" - har det !!

endnu engang tak, Arne
Avatar billede arne_v Ekspert
17. oktober 2004 - 23:11 #36
Primært sikkerhed.

Men også lidt convenience.

O'Brian er sådan er irriterende navn at putte ind i SQL.

Parameters håndterer single quotes i input ikke bare fra ondsindede hackere
men også fra "normal brug" af disse.
Avatar billede hald. Nybegynder
17. oktober 2004 - 23:26 #37
ok,...det er jo rart at vide "hvorfor" man gør det ene frem for det andet.
tak
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