Avatar billede Mads Larsen Nybegynder
20. november 2009 - 10:31 Der er 16 kommentarer og
1 løsning

Visual Basic og sdf database

Hej med jer.

Jeg har en funktion hvor der skal gemmes ca. 500-1000 linjer i en database.


Lige nu bruger jeg:

SQLStr = "bla bla osv.
SQLCmd.CommandText = SQLStr 'Sets the SQL String
SQLCmd.ExecuteNonQuery() 'Executes SQL Commands Non-Querys only

Det virker også meget fint, men mit spørgsmål er så, om man kan lave en masse ændringere i databasen før man executer, på den måde så måske få lidt mere hastighed? :)

Har ingen anelse om det kan lade sig gøre og om det overhovedet ville hjælpe noget. Men i mit hoved lyder det bare som om det ville være bedre at skulle gøre noget 1 gang istedet for 1000 gange.
Avatar billede mrbonus Novice
06. juli 2010 - 10:12 #1
Nu snakker jeg ud fra mdf istedet for sdf, men regner med at det er det samme.

Jeg gør dette ved at bare lave linje skift i sql sætningen, se nedenstående eksempel:

Dim sbSQL As New StringBuilder()
For count As Integer = 1 To 1000
    sbSQL.Append("DELETE * FROM tabel" & count & ControlChars.NewLine)
Next

(Jeg har brugt en stringbuilder istedet for en string, hvis man skal sammensætte så mange strenge, så er det noget hurtigere)
Avatar billede mrbonus Novice
06. juli 2010 - 10:14 #2
Og for lige at sammensætte det med dit eksempel:

SQLCmd.CommandText = sbSQL.ToString() 'Sets the SQL String
SQLCmd.ExecuteNonQuery() 'Executes SQL Commands Non-Querys only
Avatar billede Mads Larsen Nybegynder
06. juli 2010 - 10:59 #3
Hej mrbonus

jeg har lige prøvet at lave en lille hurtig test.

koden ser således ud:

        Dim connStr As New SqlCeConnection("Data Source=" & Application.StartupPath & "\Database3.sdf")
        Dim SQLCmd As New SqlCeCommand() 'The SQL Command
        Dim SQLStr As New StringBuilder

        connStr.Open()

        For i As Integer = 0 To 100 Step 1
            SQLStr.Append("INSERT into MassInsert(Tal) VALUES('" & i & "')" & vbCrLf)
        Next

        SQLCmd.Connection = connStr 'Sets the Connection to use with the SQL Command
        SQLCmd.CommandText = SQLStr.ToString 'Sets the SQL String
        SQLCmd.ExecuteNonQuery() 'Executes SQL Commands Non-Querys only

        connStr.Close()



Jeg får en fejl, når den vil til at executenonquery.

"There was an error parsing the query. [ Token line number = 2,Token line offset = 1,Token in error = INSERT ]"

Giver det nogen mening for dig ? :-)
Avatar billede mrbonus Novice
06. juli 2010 - 11:05 #4
Ja, det betyder at den ikke forstår sammensætningen af sql sætningerne, prøv at sætte et semikolon ind efter sætningerne:

For i As Integer = 0 To 100 Step 1
  SQLStr.Append("INSERT into MassInsert(Tal) VALUES('" & i & "');" & vbCrLf)
Next

Det virker også med mdf
Avatar billede Mads Larsen Nybegynder
06. juli 2010 - 11:14 #5
Giver samme problem med semikolon :/


en mdf database kører på en "rigtig" sql server ikke?

eller har jeg misforstået noget ? :)
Avatar billede mrbonus Novice
06. juli 2010 - 11:19 #6
Jo, en rigtig MSSQL server, i alle varianter, også den gratis version, SQLExpress.

du kunne eventuelt lave en mellemting, så du holder connection'en åben, og laver en del nonqueries imod den. dette vil også optimere en del.

For i As Integer = 0 To 100 Step 1
  SQLCmd.CommandText = "INSERT into MassInsert(Tal) VALUES('" & i & "')" 'Sets the SQL String
  SQLCmd.ExecuteNonQuery() 'Executes SQL Commands Non-Querys only
Next
Avatar billede Mads Larsen Nybegynder
06. juli 2010 - 11:24 #7
Okay:)

Har du nogen anelse om, om det vil gøre det hurtigere at indsætte en masse linjer, hvis de kom som 1 fremfor 1000 ?

Sådan som det er nu, så bliver de også sat ind mens forbindelsen holdes åben :)
Avatar billede mrbonus Novice
06. juli 2010 - 12:03 #8
du kan da prøve at teste, jeg har sat et lille eksempel op du kan benytte, Så kan du sammenligne de 4 ticks der er blevet oprettet

'all queries in one connection
Dim connStr As New SqlCeConnection("Data Source=" & Application.StartupPath & "\Database3.sdf")
Dim SQLCmd As New SqlCeCommand() 'The SQL Command
Dim SQLStr As New StringBuilder
connStr.Open()
Dim startTicks As Long = DateTime.Now.Ticks
For i As Integer = 0 To 100 Step 1
    SQLStr.Append("INSERT into MassInsert(Tal) VALUES('" & i & "')" & vbCrLf)
Next
Dim endTicks As Long = DateTime.Now.Ticks
SQLCmd.Connection = connStr    'Sets the Connection to use with the SQL Command
SQLCmd.CommandText = SQLStr.ToString 'Sets the SQL String
SQLCmd.ExecuteNonQuery() 'Executes SQL Commands Non-Querys only
connStr.Close()

'all queries in seperate connections
Dim startTicks2 As Long = DateTime.Now.Ticks
For i As Integer = 0 To 100 Step 1
    Dim connStr2 As New SqlCeConnection("Data Source=" & Application.StartupPath & "\Database3.sdf")
    Dim SQLCmd2 As New SqlCeCommand() 'The SQL Command
    Dim SQLStr2 As New StringBuilder
    connStr2.Open()
    SQLStr2.Append("INSERT into MassInsert(Tal) VALUES('" & i & "')" & vbCrLf)
    SQLCmd2.Connection = connStr    'Sets the Connection to use with the SQL Command
    SQLCmd2.CommandText = SQLStr.ToString 'Sets the SQL String
    SQLCmd2.ExecuteNonQuery() 'Executes SQL Commands Non-Querys only
    connStr2.Close()
Next
Dim endTicks2 As Long = DateTime.Now.Ticks
Avatar billede mrbonus Novice
06. juli 2010 - 12:05 #9
Men hvis du sammenligner med queries på en åben connection, vs sende alle ind i 1 queri, så tror jeg ikke at det er så meget du sparer.
Jeg ved at det ovenstående eksempel har kæmpe størrelses forskel på en access database, hvorimod ved en mdf database er der ikke super stor forskel, selvfølgelig er det langsomere hele tiden at åbne connections.
Avatar billede mrbonus Novice
06. juli 2010 - 12:08 #10
Jo forresten, prøv med nedenstående loop, sådan sætter microsofts MSSQL værktøj det op for en, kan være at det virker i sdf.

For i As Integer = 0 To 100 Step 1
  SQLStr.Append("INSERT into MassInsert(Tal) VALUES('" & i & "')" & vbCrLf & "GO" & vbCrLf)
Next
Avatar billede Mads Larsen Nybegynder
06. juli 2010 - 12:30 #11
Giver desværre samme problem ;-/
Tror desværre man må erkende at det muligvis ikke kan lade sig gøre med en sdf database..

Men ja hvis du siger, at der muligvis ikke er det helt store at hente ved, at de bliver samlet som en stor. Så gør det heller ikke så meget :)

Nu er det så heller ikke flere tusind linjer der skal indsættes.

Men ja det med at det er hurtigere, at lave kald når forbindelsen er åben konstant, kan man godt mærke, synes nu også det er mere overskueligt når man evt. har nogen andre funktioner indover som også skal bruge forbindelsen :)
så man ikke skal tænke på om den er åben eller lukket hele tiden.
Avatar billede mrbonus Novice
06. juli 2010 - 12:51 #12
:) det eneste du skal huske på er at den muligvis er låst for andre programmer og brugere, så længe du har den åben, kommer lidt an på løsningsmekanismen i sdf.
Men hvis du kan leve med det, og sørger for at lukke den under programmet nedlukning, så er det en fin løsning at have en enkelt instans af connection'en.
Avatar billede Mads Larsen Nybegynder
06. juli 2010 - 12:59 #13
Det har også givet lidt problemer i starten ;-P
Det er heller ikke meningen at der skal være 2 brugere igang på samme tid :) den tjekker i en anden sdf database, om der er "fri bane". Nok ikke det mest prof. :p men det virker indtil videre :)
Avatar billede mrbonus Novice
06. juli 2010 - 13:01 #14
:)
Avatar billede Mads Larsen Nybegynder
06. juli 2010 - 13:12 #15
Men tak for alle de fine forsøg :-)
Fik da lært at bruge stringbuilder ;)
Avatar billede mrbonus Novice
06. juli 2010 - 13:15 #16
var skam så lidt
Avatar billede Mads Larsen Nybegynder
18. august 2010 - 13:49 #17
Fandt ud af at den kun kørte rigtig sløv når programmet kørte i debug mode.

Fandt ingen måde at køre dem allesammen af på en gang

Derfor lukker jeg og slukker tråden :)
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
Kurser inden for grundlæggende programmering

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