Avatar billede razser Nybegynder
27. januar 2005 - 17:50 Der er 32 kommentarer og
1 løsning

Arrays og SQL HJÆLP

Jeg skal have indsat data fra en txt-fil, som jeg læser via FSO og lægger i et array. Jeg skal lave et check på 2 ting før jeg læser det ind i en database:

1) Om de enkelte poster findes eller ikke findes.
2) Om de skal opdateres, oprettes eller slettes via en kommando, der står i txt-filen, som det første ord.

Jeg har nedenfor et array, hvor jeg fjerner alle semikolon'er fra txt-filen:

Do While not f.AtEndOfStream
arrM = Split(f.ReadLine,";")
'Response.write arrM(0)
'Response.write arrM(1)
'Response.write arrM(2)
'Response.write arrM(3)
'Response.write arrM(4)

' her vil jeg tjekke om det første ord er UPDATE eller DELETE.

Do while not rs.EOF
strFelt1 = arrM(0)
if instr(strFelt1, "UPDATE") Then
    Response.write "Lav et script, der opdaterer felterne i databasen, hvis de findes ellers opret dem"
ELSE
    Response.write "Lav et script, der sletter poster i databasen, hvis de findes"

    rs.movenext
  loop
End if

Conn.Close
Set Conn = Nothing

Loop
f.Close


Jeg er gået kold i opgaven, så hvis der er en hjælpsom sjæl og ekspert på området, hører jeg meget gerne derfra. Hjælpen er uvurderlig!
Avatar billede hooh Nybegynder
27. januar 2005 - 18:53 #1
Du kan ikke ha' din rs.movenext inde i if-statementet.

Den skal være udenfor, ellers kan du risikere at køre i loop
Avatar billede hooh Nybegynder
27. januar 2005 - 18:54 #2
(oops trykkede lidt for hurtigt)

Skal nok være:

if instr(strFelt1, "UPDATE")>0 Then
    Response.write "Lav et script, der opdaterer felterne i databasen, hvis de findes ellers opret dem"
ELSE
    Response.write "Lav et script, der sletter poster i databasen, hvis de findes"
End if

    rs.movenext
  loop
Avatar billede razser Nybegynder
27. januar 2005 - 19:22 #3
Du har ret med det med loopen, men nu får jeg desværre fejlen:

Fejltype:
ADODB.Recordset (0x800A0E78)
Handlingen er ikke tilladt, mens objektet er lukket.

Der henvises til linien med: Do while not rs.EOF ?

Koden ser nu sådan ud:

<%
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "DBQ=" & Server.Mappath("Branche.mdb") & ";Driver={Microsoft Access Driver (*.mdb)};"
Set rs = Server.CreateObject("ADODB.RecordSet")

Dim fso, f, filespec
Set fso = CreateObject("Scripting.FileSystemObject")
filespec = Server.Mappath("/Import/Branche.txt")
Set f = fso.OpenTextFile(filespec,1)
Do While not f.AtEndOfStream
arrM = Split(f.ReadLine,";")

Do while not rs.EOF
strFelt1 = arrM(0)
if instr(strFelt1, "UPDATE")>0 Then
    Response.write "Lav et script, der opdaterer felterne i databasen, hvis de findes ellers opret dem"
ELSE
    Response.write "Lav et script, der sletter poster i databasen, hvis de findes"
End if
    rs.movenext
Loop

Conn.Close
Set Conn = Nothing

Loop
f.Close
%>

Hvis jeg tømmer databasen, indsættes værdierne fint med sætningen:

strSQL = "Insert into Branche (Felt1, Felt2, Felt3, Felt4) values(" & arrM(1) & ", '" & arrM(2) & "','" & arrM(3) & "','" & arrM(4) & "')"

Men der er lidt vej endnu...  da, der jo skal tjekkes på en del.  Jeg giver gerne flere points, hvis du kan hjælpe, da jeg er noget presset lige nu...
Avatar billede hooh Nybegynder
27. januar 2005 - 19:30 #4
Du skal ´flytte :
Conn.Close
Set Conn = Nothing

efter den sidste loop

for når den looper igennem anden gang så har du lukket din connection
Avatar billede razser Nybegynder
27. januar 2005 - 19:36 #5
Nu har jeg fjernet sætningerne:

Do while not rs.EOF

samt

rs.movenext
Loop

Da det jo allerede ligger i en loop...og det synes at virke...

Til info er Felt4 primærnøgle; Felt1, Felt2 er tal, og Felt3 er et tekst-felt i databasen. Der skal også tages højde for, at nogle felter kan være tommme...
(Men jeg ved dog ikke om du har tid og lyst til at hjælpe med SQL-sætningerne)?
Avatar billede razser Nybegynder
27. januar 2005 - 19:41 #6
Jeg har nu også flyttet lukningen af connectionen ned under Loop'en...
Avatar billede hooh Nybegynder
27. januar 2005 - 19:52 #7
Opdaterer felterne i databasen, hvis de findes ellers opret dem:

strSql = "Select * from tabel where Felt4 = xxx"
set rs = Conn.execute(strSql)

if rs.eof then
  'Findes ikke
  StrSql = "INSERT into tabelnavn..."
else
  'Findes
  StrSql = "UPDATE...."
end if



jeg har ikke så meget tid idag. Jeg sidder og venter på nogle gæster.
Er her indtil de ikke kommer. Hvis du ikke får det løst kan vi se på det imorgen
Avatar billede razser Nybegynder
27. januar 2005 - 20:02 #8
Det lyder godt, jeg kæmper videre....
Avatar billede hooh Nybegynder
28. januar 2005 - 09:23 #9
har du fået løst det??
Avatar billede razser Nybegynder
28. januar 2005 - 10:03 #10
Ikke helt... Scriptet udfører ikke handlingerne: DELETE og UPDATE?? Men det indskriver nye poster, som det skal. Og så er der lige det med de tomme felter (;;), der også skal tages højde for...

Scriptet ser nu sådan ud:

<%
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "DBQ=" & Server.Mappath("Branche.mdb") & ";Driver={Microsoft Access Driver (*.mdb)};"
Set rs = Server.CreateObject("ADODB.RecordSet")

Dim fso, f, filespec
Set fso = CreateObject("Scripting.FileSystemObject")
filespec = Server.Mappath("/Import/Branche.txt")
Set f = fso.OpenTextFile(filespec,1)
'Emp = replace((f.ReadLine), ";;", ";0")
Do While not f.AtEndOfStream

arrM = Split(f.ReadLine,";")
'arrM = Split(Emp,";")
strFelt1 = arrM(0)

strSQL = "select * from branche where Felt4=" & arrM(4) & ";"
set rs = Conn.Execute(strSQL)
       
if instr(strFelt1, "UPDATE")>0 Then
if rs.eof then

strSQL = "Insert into Branche (Felt1, Felt2, Felt3, Felt4) values(" & arrM(1) & ", '" & arrM(2) & "','" & arrM(3) & "','" & arrM(4) & "')"
set rs = Conn.Execute(strSQL)
else

'Response.write arrM(0) & arrM(4)
SQL="Update Branche set "&_
"Felt1='"&arrM(1) &"'," &_
"Felt2='"&arrM(2) &"'," &_
"Felt3='"&arrM(3) &"'," &_
"Felt4='"&arrM(4) &"'" &_
"where Felt4=" & arrM(4)
set rs = Conn.Execute(strSQL)
End if

Else if instr(strFelt1, "DELETE")>0 Then
if not rs.eof then
'response.Write arrM(0) & arrM(4)
SQL = "DELETE FROM Branche where Felt4=" & arrM(4) & ";"
set rs = Conn.Execute(strSQL)
End if
End if

End if

Loop
f.Close
'rs.Close 
Conn.Close
Set Conn = Nothing

%>

Håber, at du kan hjælpe ...
Avatar billede hooh Nybegynder
28. januar 2005 - 10:23 #11
hvor får du semicolon fejl??

når du tester din UPDATE så er du vel sikker på at den findes i basen, ik?
Avatar billede razser Nybegynder
28. januar 2005 - 10:37 #12
Mht. UPDATE, så ændrer jeg blot en værdi i txt-filen (naturligvis ikke primærnøglen) - så de findes i databasen i forvejen. Det samme med DELETE.

Jeg får kun fejl, hvis jeg sletter et "felt" i txt-filen, for scriptet fjerner semikolon, når det indlæses. En linie i txt-filen kunne f.eks. se sådan ud:

UPDATE;43672012;4;Sand;1002
DELETE;43672012;4;Grus;1003

Hvis jeg fjerner noget, så linien bliver:

UPDATE;;4;Sand;1002

opstår naturligvis fejl. Måske skal jeg indlæse hele txt-filen først og replace ;; med et eller andet - ellers skriver den kun de 3 første ind i databasen, uden at tage det sidste felt med...
Avatar billede hooh Nybegynder
28. januar 2005 - 10:44 #13
strSQL = "select * from branche where Felt4=" & arrM(4) & ";"
skal ændres til:
strSQL = "select * from branche where Felt4='" & arrM(4) & "';"

så går den ihverfald ikke ned, når den modtager blank.

Det samme skal gøres med delete:
SQL = "DELETE FROM Branche where Felt4='" & arrM(4) & "';"

Så skulle de 2 være løst. Hvor får du mere fejl
Avatar billede razser Nybegynder
28. januar 2005 - 11:01 #14
Hvis jeg indsætter:

strSQL = "select * from branche where Felt4='" & arrM(4) & "';"

Får jeg følgende fejl:

Microsoft OLE DB Provider for ODBC Drivers (0x80040E07)
[Microsoft][ODBC Microsoft Access-driver] Datatyperne stemmer ikke overens i kriterieudtrykket

Under både UPDATE og DELETE har jeg lavet en response.write, som fortæller hvad der skal ske, og her skrives det rigtigt.
Fx. DELETE 1003, UPDATE 1002 - så den tidligere sætning må tilsyneladende være rigtig... Den udfører dog ikke selve handlingen...????
Avatar billede hooh Nybegynder
28. januar 2005 - 11:14 #15
ok så arrM(4) er skal altså være et tal

så prøv denne istedet:

if arrM(4)<>"" then
strSQL = "select * from branche where Felt4='" & arrM(4) & "';"
set rs = Conn.Execute(strSQL)
  if not rs.eof then
    found=true
  else
    found=false
  end if
else
found = false
end if

if instr(strFelt1, "UPDATE")>0 Then
if found then

strSQL = "Insert into Branche (Felt1, Felt2, Felt3, Felt4) values(" & arrM(1) & ", '" & arrM(2) & "','" & arrM(3) & "','" & arrM(4) & "')"
set rs = Conn.Execute(strSQL)
else

'Response.write arrM(0) & arrM(4)
SQL="Update Branche set "&_
"Felt1='"&arrM(1) &"'," &_
"Felt2='"&arrM(2) &"'," &_
"Felt3='"&arrM(3) &"'," &_
"Felt4='"&arrM(4) &"'" &_
"where Felt4=" & arrM(4)
set rs = Conn.Execute(strSQL)
End if

nu kan arrM(4) godt være blank
Avatar billede razser Nybegynder
28. januar 2005 - 11:26 #16
arrM(4) er det, der fungerer som primærnøgle i databasen (en unik ID - den er dog ikke autogeneret), så den må ikke være blank.. det er kun de andre der må...
Avatar billede hooh Nybegynder
28. januar 2005 - 11:45 #17
har du mulighed for at zippe det hele og sende det til min mail, så kigger jeg lige på det og sender det tilbage
Avatar billede razser Nybegynder
28. januar 2005 - 11:55 #18
Jeps, har du en hotmail eller noget.....
Avatar billede hooh Nybegynder
28. januar 2005 - 11:59 #19
min mail er hooh@masti.dk
Avatar billede razser Nybegynder
28. januar 2005 - 12:52 #20
..lad mig høre om du har modtaget det ;-)
Avatar billede hooh Nybegynder
28. januar 2005 - 12:58 #21
jeg har fået den.. kigger lige
Avatar billede hooh Nybegynder
28. januar 2005 - 13:20 #22
prøv lige denne side:

http://www.masti.dk/eksperten/585349/import.asp

er det sådan du ønsker det?
Avatar billede razser Nybegynder
28. januar 2005 - 13:35 #23
Ja, det der trækkes ud ser rigtigt ud. Jeg har bare ikke kunne få det til at udføre selve handlingerne.....????

Når det virker, skal jeg blot have lavet en redirect, så det hele bliver afviklet skjult...
Avatar billede hooh Nybegynder
28. januar 2005 - 13:52 #24
sådan
Avatar billede hooh Nybegynder
28. januar 2005 - 14:00 #25
nu har smidt en tom db over

så læg mærke til at den først indsætter...

og hvis du refresher... så laver den UPDATE
Avatar billede razser Nybegynder
28. januar 2005 - 14:00 #26
har du fået det hele til at virke ? :)
Avatar billede hooh Nybegynder
28. januar 2005 - 14:01 #27
insert/update virker ihvetfald

har ikke testet delete

har du?
Avatar billede hooh Nybegynder
28. januar 2005 - 14:03 #28
ok delete virker også!!!!

nu kører det
Avatar billede razser Nybegynder
28. januar 2005 - 14:21 #29
Ja, jeg har også lige testet det - genialt !!!! 
Den sidste ting er dog det med en tom celle. Hvis man i txt'en sletter et felt, så der står

UPDATE;;4;Stål;1001

Så fejler scriptet. Jeg ved ikke om man fra start kunne replace ;; med ;0 
så der i databasen bare kommer til at stå 0 i de felter, der ikke benyttes???
Måske har du et mere prof forslag?
Avatar billede hooh Nybegynder
28. januar 2005 - 15:20 #30
efter din split laver du en for-løkke og tjekker dit array og sætter 0 i dem der nu er tomme

sådan:
arrM = Split(lineTxt,";")
for x=0 to ubound(arrM)
if arrM(x) = "" then arrM(x)  = 0
next
Avatar billede razser Nybegynder
28. januar 2005 - 15:33 #31
Genialt, suverænt, super !!!! Post et svar, og de 200 points er dine ;-)
Avatar billede razser Nybegynder
28. januar 2005 - 15:48 #32
- håber i øvrigt, at kunne hjælpe dig (selv om det bliver svært)...
Avatar billede hooh Nybegynder
28. januar 2005 - 16:36 #33
Selv tak...
glad for at kunne hjælpe :-)
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