Avatar billede netrnger Nybegynder
29. august 2000 - 15:24 Der er 17 kommentarer og
1 løsning

For lidt pladsallokering i ASP ved nye RS-obj?

Jeg har et problem når jeg prøver at oprette nye recordsets i ASP i en MySQL-database.
Jeg har lavet et object af typen ADODB.RecordSet og åbnet det med forbindelse til min database via en sql-sætning lydende \"Select * from TestDB where id = 1\"

Databasen TestDB indeholder to felter - ID som er en integer og autonummerering (her er ingen problem), og så et felt kaldet Titel som er af typen varchar(50) - dvs. den må være op til 50 karakterer.

Nu laver jeg så en RS.AddNew, fordi jeg gerne vil lave et nyt recordset. Den fra sql-sætningen udtrukne recordsæt indeholder en Titel med længden 8 karakterer (men må jo være op til 50).
Med det nye RS skriver jeg nu RS(\"Titel\") = \"abcd efgh\" (altså 9 karakterer), men dette giver en fejl. Fejlen jeg får siger mig ikke noget, for den siger bare \"Errors occurred\". Men efter længere tid har jeg fundet ud af at såfremt jeg holder mig under (eller lig) antallet af karakterer i den post, dvs. pt. 8 karakterer, så er der ingen problemer.
Opretter jeg et felt databasen via en rå sql-streng, som indeholder en Titel på f.eks. 40 karakterer, og åbner databasen/RS\'et med den post istedet for, så kan jeg lave nye objekter optil 40 karakterer, men altså ikke de 50 som jeg har specificeret i felt-definitionen.
På en måde knytter det sig altså til det object jeg åbner db\'en med.
Jeg har prøvet adskillige ting, bl.a. også alle mulige andre felttyper på Titel-feltet - f.eks. Char(50), Text, m.v.

Alternativt er at jeg skal til at oprette (og editere eksisterende faktisk også!) poster via rå sql-sætninger, og så mister jeg jo det brugervenlige princip med at man kan sige
RS(\"Titel\") = \"blabla\"
RS.Update

Her er min lille testkode (for jeg troede det var min eksisterende database det var galt med, så jeg lavede en helt ny for at finde fejlen):
----
  Set RS = Server.CreateObject(\"ADODB.RecordSet\")
  sql = \"SELECT * FROM TestDB where id=1\"
  %><!-- #include file=DatabaseConnection.asp --><%
  RS.Open sql, conn, adOpenStatic, adLockOptimistic, adCmdText

  RS.AddNew
  RS(\"Titel\") = \"98765432109876543210abcd\"
  RS.Update
  RS.Close

  set RS = nothing
  set conn = nothing
---

Håber nogen kan hjælpe...
Avatar billede netrnger Nybegynder
29. august 2000 - 15:27 #1
includefilen DatabaseConnection.asp indeholder:
---
SQLserveradr=\"xxxx\"
SQLdatabase=\"xxxx\"   
SQLlogin=\"xxxx\"
SQLpassword=\"xxxx\"

conn = \"driver={MySql};server=\"& SQLserveradr &\";database=\"& SQLdatabase &\";uid=\"& SQLlogin &\";pwd=\"& SQLpassword
---
Avatar billede styrmand Nybegynder
29. august 2000 - 17:58 #2
Fortæller fejlen dig ikke noget om, hvilken linie, det er som giver problemet?
Avatar billede netrnger Nybegynder
29. august 2000 - 18:04 #3
Jo, og det er når jeg sætter RS(\"Titel\") lig med en streng der er større end det der blev \"allokkeret\" (eller hvad fejlen nu skyldes), men stadig mindre en de 50 defineret i tabeldefinitionen.
Avatar billede styrmand Nybegynder
29. august 2000 - 18:15 #4
Har du husket at inkludere adovbs.inc. Hvis ikke så er parametrene adOpenStatic, adLockOptimistic og adCmdText ukendte.
Du kan i stedet bruger ,RS.Open sql,conn,3,3,1
Avatar billede netrnger Nybegynder
29. august 2000 - 18:25 #5
Undskyld jeg svarer lidt spydigt :o), men selvfølgelig har jeg det, ellers ville
1: fejlen opstå allerede ved åbning af databasen
2: indsættelser af poster under 8 karakterer jo ikke gå godt (som de gør)
Avatar billede styrmand Nybegynder
29. august 2000 - 18:46 #6
Ja ja, svin mig bare til...:-)
Nej, jeg sidder og tænker på noget med om det kunne have noget at gøre med Widechar, Bytechar contra MySql o.s.v., men som regel ligger problemet i noget mere simpelt, derfor spørger jeg dig om de ting er i orden.
Jeg havde heller ikke fået fat i at, det faktisk fungerer delvist.
Hvis du udskriver din tabeldefinition, viser den så stadig varchar(50)?
Når jeg kigger i MySql Manualen, så er VarChar defineret således at den kun fylder det antal tegn (+1), som er lagret i feltet. Char fylder altid den definerede længde.
Derfor bør det fungerer, med mindre der er noget andet vi har overset..
Avatar billede netrnger Nybegynder
29. august 2000 - 18:55 #7
Ja tit kan det ligge i noget elementært...

Hvis jeg udskriver tabeldefinitionen, så viser den stadig varchar(50). Idéen med varchar er jo at den ikke FYLDER mere end det som står i feltet, men den kan dynamisk udvides til at fylde op til 50 karakterer. Modsat en char(50), som altid vil fylde 50 karakterer om så de bliver brugt eller ej. (kan være jeg tager fejl, men sådan har jeg vist lært det, hvis jeg husker ret :)).

Men ikke desto mindre, så har jeg (som tidligere beskrevet) prøvet at definere feltet til at være en del andre ting, såsom char, text osv., men uden det hjælper.
Der er jo ingen problemer når jeg indsætter posten ved at skrive en rå sql-sætning, så mit gæt er at det må have noget med kombinationen af ASP at gøre?
Avatar billede styrmand Nybegynder
29. august 2000 - 19:03 #8
Hvad nu hvis du tilskriver strengen en værdi således.
s=\"\"
For i=1 to 49
  s = s & chrB(65)
Next
RS(\"Title\")=s
Avatar billede netrnger Nybegynder
29. august 2000 - 19:19 #9
Det giver desværre det samme at ligge indholdet i en variabel først...

Det er RS(\"Titel\") der har en eller anden ide om at strengen max må være 8 karakterer.
Avatar billede netrnger Nybegynder
29. august 2000 - 19:21 #10
Til en lille information skal det måske siges, at det er et website som tidligere har kørt på Access-databaser, som skal ligges over i MySQL. Så alle sider har kørt udemærket inden da. JFYI :)
Avatar billede styrmand Nybegynder
29. august 2000 - 19:48 #11
Det slår mig pludselig, hvorfor åbner du tabellen og finder en bestemt post, når du alligevle, bare skal indsætte en ny.
Prøv i stedet at åbne tabellen således.
RS.Open \"TestDB\", adOpenKeyset, adLockOptimistic, adCmdTable


 
Avatar billede netrnger Nybegynder
29. august 2000 - 20:03 #12
Det gør jeg fordi jeg ikke vidste man kunne åbne den som du har vist - det er hvad man får ud af at selvlære ting ved kigge i andres sources :)

Grunden til at jeg taget en bestemt post ud, er for at mindste indholdet af RS\'en. Ellers vil den jo indeholde hele tabellens indhold, så det er vel et spørgsmål om performance.

Men for nu at svare på din løsning, så virkede det desværre ikke :( Jeg tilføjede lige en \", conn\" i sætningen, men det virker ikke. Jeg sad ellers lige og håbede, da det virkede sandsynligt... I dit tilfælde fylder den også alt indholdet fra DB\'en ind i RS\'et, og der sker her det at den finder de før 8 karakterer, ud fra den post der har den største værdi. Så altså indeholder DB\'en Titler á 8, 17, 5 og 13 karakterer - så kan jeg maximalt indsætte 17 karakterer nu (og stadig ikke 50).

Det er altså kryptisk underligt det her, og det BURDE virke, men gør det ikke :(
Avatar billede styrmand Nybegynder
29. august 2000 - 20:25 #13
Du har godtnok sagt at du ikke vil bruge SQL, men det er det eneste bud jeg har tilbage.
Erstat alt fra RS.Open... til Set RS=Nothing med følgende:

set ObjCom=server.CreateObject(\"ADODB.Command\")
    objCom.CommandText=\"Insert into TestDb (ID)\"
    objCom.CommandText= objCom.CommandText & \" values (\"ghghhghghghhjgh\");\"
    objCom.ActiveConnection = Conn
    objCom.CommandType=adCmdText
    objCom.execute
set objCom=nothing
Avatar billede netrnger Nybegynder
29. august 2000 - 20:28 #14
Jeps, det er pt. også eneste udvej jeg kan se, men løser ikke mit egentlig problem som jeg helst vil have det løst, så jeg venter lige lidt og ser om der kommer andre svar på spørgsmålet...
Avatar billede alvion Nybegynder
05. september 2000 - 14:58 #15
Der er to grunde til at vælge rene sql-kald fremfor recordset:
1) Du undgår kompabilitetsproblemer mellem ADO og ODBC
2) Du vil opleve et stort performance skub i den rigtige retning

Det kræver en uddybning (følgende er erfaringer jeg har gjort mig efter mange timer dybt begravet i logfiler):

ad 1)
Microsoft\'s ADO.Recordset overholder sjovt nok ikke helt standarderne omkring ODBC 2.0. Vanen tro er der lavet særlige funktioner, som ADO benytter sig af, hvis ODBC-driveren hedder SQL-server eller JET... Det går tydeligvis ud over andre databaser der overholder ODBC-standarden, som man vælger at tilgå via ADO.Recordset. Jeg har f.eks. oplevet at felter af typen TEXT ikke må være tomme eller NULL, når jeg retter en record.

ad 2)
Hvis du har en tabel, som den du beskriver overfor, og laver en opdatering af en eksisterende record (id=5 og titel=\"qwe\") via recordset, genererer ADO følgende SQL sætning:

\"update testdb set id=5 and titel=\'blabla\' where (id=5 and titel=\'qwe\');\"

Kan du se problemet i ovenstående sætning? \"id\" er din primære nøgle, derfor behøver titel IKKE indgå i where-sætningen. Forestil dig nu en tabel med 20 tekst-felter nogle af typen VARCHAR og andre af typen TEXT. Der bliver kastet ret meget unødig data rundt - de vil alle blive brugt i where-sætningen (tro mig - jeg har prøvet det!)

Derfor: Brug altid Connection til indsættelse og opdatering. Brug kun recordset til udtræk - og opret dem altid implicit:

set rs = conn.execute(\"select .....\")

Dermed ikke sagt at det skal være besværligt :-) Lav en include fil, med nogle hjælpefunktioner, som kan generere sqlsætningerne for dig. Email mig privat, hvis du skal ha\' hjælp med sådan nogle hjælpe funktioner.
Avatar billede netrnger Nybegynder
05. september 2000 - 15:11 #16
Da der ikke er nogen løsning på mit problem, udover det som jeg selv kunne have svaret, samt at sitet gik i luften igår, så må jeg desværre tildele mig selv pointsene (hvis jeg kan).

Jeg ved godt at RecordSets giver dårligere performance, men de er nemmere at arbejde, og når jeg nu havde et eksisterende site hvor der VAR brugt RecordSets istedet for rene sql-kald, så er det altså langt at foretrække en løsning på problemet (hvis der bare var noget). Men da det hele nu er konverteret til rene sql-sætninger, og der ikke kom nogen løsning jeg kunne bruge, så lukker jeg spørgsmålet - tak for hjælpen til dem som har forsøgt... :)
Avatar billede styrmand Nybegynder
05. september 2000 - 20:02 #17
Det var dog usympatisk. Regn ikke med hjælp herfra i fremtiden
Avatar billede alvion Nybegynder
06. september 2000 - 08:47 #18
Ja, det vil jeg nok også sige - vi har givet dig en løsning. Løsningen var ikke med Recordset, da diskussionen meget tidligt konstaterede at det ikke kan lade sig gøre pga. en bug i recordsets. Men en løsning var der.

Hvad vil du have? Skulle vi grave C++ compileren frem, stjæle Microsoft\'s kildekode og skrive en bugfix til dig?
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
Computerworld tilbyder specialiserede kurser i database-management

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