Avatar billede popnizzen Nybegynder
09. maj 2009 - 19:46 Der er 8 kommentarer og
1 løsning

Problemer med at INSERT igennem en Stored Procedure i MSsql

Hej

Jeg er ved at være møg træt af det her "lille" problem.

Jeg har en del data der er placeret i en arraylist. Det er grupperet sådan det der ligger på placering [0], [1], [2] er en tupel nede i databasen. Det er et kodeord, et brugernavn og et evalueringsnavn.
Det er meget forskelligt hvor mange gange de her klumper optræder i min arraylist. Nogen gange kan jeg have en klump andre gange kan jeg have 30 klumper.

Når jeg prøver at tilgå min SQL server igennem den oprettede Stored Procedure, får jeg følgende fejl:

Procedure or function Gem_Password has too many arguments specified.

Koden fra applikationen ser sådan her ud:
public void GemPassword(ArrayList al)
    {
        Connect();
       
        SqlCommand dCmd = new SqlCommand("Gem_Password", conn); //SP navn
        dCmd.CommandType = CommandType.StoredProcedure; //Type af kald
        try
        {
            for (int i = 0; i < al.Count; i++)
            {
                dCmd.Parameters.AddWithValue("@PassID", al[i]); //Variabler der bruges i SP
                dCmd.Parameters.AddWithValue("@Brugernavn", al[i + 1]);
                dCmd.Parameters.AddWithValue("@Eva_Navn", al[i + 2]);
                dCmd.ExecuteNonQuery();
            }
        }
        catch
        {
            throw;
        }
        finally
        {
            dCmd.Dispose();
            conn.Close();
            conn.Dispose();
        }
    }

Min stored Procedure ser således ud:

ALTER PROCEDURE [dbo].[Gem_Password]
    -- Add the parameters for the stored procedure here
    @PassID varchar(50),
    @Brugernavn varchar(20),
    @Eva_Navn varchar(50)
AS
BEGIN
    --SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    BEGIN TRY
    if exists( SELECT *
              FROM dbo.Logon
              WHERE PassID = @PassID AND Brugernavn = @Brugernavn)
    Raiserror('Password eksisterer allerede', 11, 1)
   
    --hvis reglerne opfyldes, så indsæt password
        INSERT INTO dbo.Logon([PassID],[Brugernavn], [Eva_Navn])
        VALUES
            (@PassID, @Brugernavn, @Eva_Navn)
    END TRY
   
    BEGIN CATCH
        declare @txt varchar(50)
        set @txt = error_message()
        raiserror(@txt, 11, 1)
    END CATCH
END
Avatar billede softspot Forsker
09. maj 2009 - 19:58 #1
Prøv lige denne version i stedet (den tilføjer kun parametrene én gang og sætter derefter værdierne i de eksisterende parametre):

public void GemPassword(ArrayList al)
    {
        Connect();
       
        SqlCommand dCmd = new SqlCommand("Gem_Password", conn); //SP navn
        dCmd.CommandType = CommandType.StoredProcedure; //Type af kald

        dCmd.Parameters.Add("@PassID"); //Variabler der bruges i SP
        dCmd.Parameters.Add("@Brugernavn");
        dCmd.Parameters.Add("@Eva_Navn");
        try
        {
            for (int i = 0; i < al.Count; i++)
            {
                dCmd.Parameters["@PassID"].Value = al[i];
                dCmd.Parameters["@Brugernavn"].Value = al[i + 1];
                dCmd.Parameters["@Eva_Navn"].Value = al[i + 2];
                dCmd.ExecuteNonQuery();
            }
        }
        catch
        {
            throw;
        }
        finally
        {
            dCmd.Dispose();
            conn.Close();
            conn.Dispose();
        }
    }
Avatar billede Syska Mester
09. maj 2009 - 20:01 #2
Måske der skulle value type med når parameter bliver added ... ved ikke om det har noget at sige i sidste ende ... men måske ... :-)

// ouT
Avatar billede popnizzen Nybegynder
09. maj 2009 - 20:48 #3
Hej tak for de hurtige svar

@Softspot
Når jeg forsøger din tilgang får jeg følgende fejl:
SqlParameterCollection accepterer kun objekter af typen SqlParameter, der ikke er null, ikke String-objekter.
Denne opstå ved dCmd.Parameters.Add("@PassID"); //Variabler der bruges i SP

@buzzzz
Hm, jeg kan ikke umiddelbart se hvorfor der skulle value type med, men jeg er åbent for alt for at få løst det her problem :) Hvordan skulle jeg sætte det op med value type?
Avatar billede Syska Mester
09. maj 2009 - 20:53 #4
cmd.Parameters.Add("@PassID", SqlDbType.VarChar, 50);

Jeg kan ikke lige se din value type, men nok varchar 50 eller string/text ...

Men overstående burde løse dit problem.

// ouT
Avatar billede popnizzen Nybegynder
09. maj 2009 - 21:07 #5
@Buzzzz
Ja det er en varchar(50)
Men jeg tror endelig jeg har fundet en løsning på problemet.
Jeg blev nødt til at lave følgende:
dCmd.Parameters.Clear();
Til sidst i løkken for at clear parametrene. Underligt men det virkede
Avatar billede Syska Mester
09. maj 2009 - 22:34 #6
Hej,

Det kommer jo an på hvordan du har lavet det ... som default er der ingen parameter på et SqlCommand object ... og du burde kunne tilføje dem på den måde jeg viste ... og så bruge "softspot" eksemple men at indsætte nye værdier for de 3 parameters.

Det skal virke ... det andet ville jeg i hvert fald ikke se mig tilfreds med ... det er et mærkeligt work around for noget mere simplet som burde virke.
Avatar billede arne_v Ekspert
10. maj 2009 - 04:33 #7
Hvi sman tilføjer Parameters inde i for løkken, så skal man kalde Clear. Men det er ikke nogen god løsning.
Avatar billede popnizzen Nybegynder
10. maj 2009 - 10:12 #8
Hej igen

Nu har jeg prøvet mig lidt frem og tiulbage og endt ud med din løsning buzzzz. Hvorfor er det helt specifikt bedre end den løsning med clear inde i løkken?

Hvordan er det man afgiver pointene?
Avatar billede Syska Mester
10. maj 2009 - 12:26 #9
Du afgiver point når en af os smider et svar ... og her kommer mit.

Min første tanke er at det giver dårlig performance at hele tiden af angive parameters.

Måske også noget med MSSQL serveren hvis de ændre sig skal der compiles en ny execution plan ...

// ouT
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