28. april 2010 - 14:59Der er
23 kommentarer og 1 løsning
Form-indtastet streng skal indsættes i database
Jeg har en form, hvori jeg indtaster data, som kan indsættes i en mysql-database. Der er også mulighed for at hente tidligere poster, modificere dem, og updatere en post. Dette har tidligere virket.
Nu er jeg ved at lave det sådan, at hvis brugeren indtaster et linieskift manuelt, så kommer dette også med i databasen. Jeg har læst på nettet, at et linieskift sagtens kan håndteres i databasen, eftersom det blot automatisk angives som "\n". Jeg troede egentlig, at dette var det nuværende problem.
Men nu har jeg lige lavet en "normal" opdatering af posten - altså uden linieskift i. Men nu giver det stadig problemer. Findes der en måde, hvorpå man kan komme nærmere den nøjagtige fejl?
Jeg udvikler i Netbeans, og under kørsel har jeg udskrevet sql-en. Denne har jeg manuelt sat ind i et sql-windue i netbeans, og eksekveret. Den tillader execution'en, så syntax'en er vel rigtigt nok? Når jeg så laver en "select all" på tabellen, så er de forventede ændringer ikke at finde????
Det vil sige, at jeg skal ændre mit manuelt konstruerede "UPDATE"-statement i min java-klasse, så der benyttes "PreparedStatement"?
Jeg skal til at læse lidt om Hibernate, men det kommer ikke til at være lige foreløbig. Så hvis en løsning på den gode "gammeldags" måde kan strikkes sammen, så vil det være bedst.
Fra "UPDATE" i dit indlæg, omhandler det så Hibernate? For min sql-sætning er jo med "Update" i begyndelsen, og den har jo også virket førhen. Kan man angive en "auto commit" et sted i java, eller var det Hibernate?
Jeg ved ikke om Statement virker med linieskift, men PreparedStatement vil virke. Og som side effekt beskytter det jo ogsaa mod SQL injection.
Auto commit er en egenskab paa Connection (og dermed JDBC). Jeg siger ikke at det er det, men det er en klassisk fejl: man koerer en masse UPDATE og INSERT med de gemmes ikke - fordi at man ikke fik aendringerne committet.
Ah, jeg tror, jeg har fundet fejlen nu. Primær-nøglen er et tal med 5 decimaler. Og mit update-statement har kun 4 decimaler i sig. Så det lyder som en forklaring. Jeg tester lige i morgen.
Jeg havde det godt på fornemmelsen i begyndelsen, men efter grundig overvejelse kom jeg frem til: "hvorfor er det dét?"
Så vidt jeg ved af, må man gerne bruge int's. Og en double er vel det samme, bare med et komma i. Så en evt. problemstilling burde man da kunne programmere sig ud af. Det eneste lille problem, jeg kan se, er, at der i teorien kan være et uendeligt antal decimaler på en primærnøgle, som derfor ikke kan lokaliseres i databasen. Men dette kan man da lave en programmerings-mæssig løsning på...?
Floating point er pr. definition unøjagtige (nogle værdier "findes" ikke). Ønsker du præcission OG decimaler, så brug DECIMAL (men forstår ikke hvorfor en entydig ikke-brugervendt nøgle, skulle have decimaler).
"(men forstår ikke hvorfor en entydig ikke-brugervendt nøgle, skulle have decimaler)." ->det skal den i dette tilfælde fordi, den repræsenterer koordinater i landskabet. Og de angives med decimaler. Men når man kommer ud på 5 decimaler, så er nøjagtigheden på under 1 meter, hvilket må siges at være godt nok i dette tilfælde.
Mine overvejelser i beslutningsprocessen mht. at bruge en anden nøgle som primary key var, at når der alligevel skal checkes i systemet, om en aktuel koordinat findes i forvejen, og der ud fra tillade eller acceptere indtastningen, så er det vel blot et check for checkets skyld. Altså unødvendige beregninger som sløver systemet ned. Så kan man vel lige så godt klare det hele i første hug, og lave primary key ud fra koordinatet?
Java int & database INTEGER er fint som PK Java BigDecimal & database DECIMAL (eller NUMBER) er fint som PK Java double (eller float) & database ditto duer ikke som PK
PK's formaal er at finde en enkelt raekke med WHERE felt=vaerdi.
Floating point har nogle egenskaber som goer at = til sammenligning er ret meningsloest.
Man bruger ikke if(x==y) men if(Math.abs(x-y)<EPS). Det fungerer ikke i database sammenhaeng.
Jeg bruger ikke koordinaterne, som er double, til beregninger eller andet fancy. Jeg bruger det udelukkende til toString(), så de kan udskrives og sammenlignes med andre koordinater med samme antal decimaler.
Med det i mente, overholder mit system vel stadigvæk det angivne i #12 ?
#16 Ja, det mente jeg nu også godt jeg kunne, når det var samme antal decimaler og strings.
Og jeg kan godt se problematikken i dit eksempel. Faktisk har jeg netop oplevet et lignende problem i dag. Jeg skal ikke kunne sige, om det var nøjagtig samme problemstilling, men eftersom det var floats, der blev behandlet, og de kom ud af "maskineriet" som fejlfortolket (funktion af Google Maps-framework), så konkluderede jeg, at det nok var float'en som sådan, den var gal med.
10.0f skal laeses som 10.0 +/- 0.000001 og 10000.0f skal laeses som 10000.0 +/- 0.001 og 100000000.0f skal laeses som 100000000.0 +/- 10.0 !
Det er ganske glimrende til alt der skal maales.
Hvis man har 50 km til arbejde, saa har man ikke et problem med at det betyder 50 +/- 0.0000005 da det jo betyder 50 km +/- 5 mm og det giver ingen mening at diskutere millimeter i den sammenhaeng.
Men det er ikke godt til penge *i de fleste sammenhaenge).
Og det er heller ikke godt til == hverken i app eller i database.
Jeg lavede det her MySQL eksempel til et andet spoergsmaal for nogle aar siden:
mysql> CREATE TABLE fproblem (id INT PRIMARY KEY,x FLOAT(12,2)); Query OK, 0 rows affected (0.09 sec)
Ja, det kan jeg godt se. Lækkert med udførligt eksempel :-)
Men jeg må dog lige påpege, at det tilsyneladende går godt i eksemplet, så længe der IKKE modificeres/overskrives med beregninger. Hvis der bruges float til primary key, så er det vel ikke for at modificere nøglen eller overskrive den ud fra beregninger. En primary key skal der ikke pilles ved - hvis den skal ændres, skal row'en slettes, og en ny row med passende primary key oprettes. Det er vel den gænge standart? Og i så fald duer eksemplet ikke...
Jeg fik dog lige den tanke i dit sidste eksempel, at hvad nu hvis ".0f" ligger udenfor sammenlignings-intervallet? Så vil det jo forklare, hvorfor der ikke bliver udskrevet det forventede eftersom det vel er en afrunding.
Jeg kan dog ikke helt finde sammenhængen med syntaxen, og så forklaringen på syntaxen i #18.
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.