Avatar billede dsj Nybegynder
13. februar 2003 - 18:23 Der er 16 kommentarer og
1 løsning

PreparedStatement

Hvis nu man laver en række sql-kald ved brug af PreparedStatement, hvordan skal det så helt præcist håndteres?

Skal der laves et nyt PreparedStatement for hvert sql-kald:

  String sql = "...";
  PreparedStatement prepStmt1 = con.prepareStatement(sql);
  prepStmt1.executeQuery();
  sql = "...";
  PreparedStatement prepStmt2 = con.prepareStatement(sql);
  prepStmt2.executeQuery();
  ...

eller kan/skal det samme anvendes hele vejen igennem: 

  String sql = "...";
  PreparedStatement prepStmt1 = con.prepareStatement(sql);
  prepStmt1.executeQuery();
  sql = "...";
  prepStmt1 = con.prepareStatement(sql);
  prepStmt1.executeQuery();
  ...

Hvad er det bedst set ud fra performance??
Avatar billede arne_v Ekspert
13. februar 2003 - 18:36 #1
Begge bør virke.

Og jeg tror ikke, at der nogen nævneværdig forskel på performance.
Avatar billede arne_v Ekspert
13. februar 2003 - 18:38 #2
Jeg ville bruge den første og så vælge nogle mere sigende navne a la:
  selTable1PrepStmt
  selTable2PrepStmt
for at gøre koden mere letlæselig ved at man ud fra navnet ved
hvilken SQL sætning der gemmer sig bag ved den.
Avatar billede miknil Nybegynder
13. februar 2003 - 18:42 #3
Ideen med et prepared statement er netop at det er prepared.

Der er ingen ide i at lave et prepared statement, for derefter at prepare det igen med et nyt SQL statement - så er dynamisk SQL mere velegnet.

Preparedstatement er netop beregnet til at prepare et statement en gang og derefter eksekvere det flere gange, fordelen for databasen er at den kun skal
oprette en eksekveringsplan en gang.

miknil
Avatar billede miknil Nybegynder
13. februar 2003 - 18:44 #4
Du kan med fordel anvende noget i stil med

Statement aStmt = Connection.createStatement();
ResultSet aSet = theStatement.executeQuery(theSql); 

og så genbruge aStmt istedet.

miknil
Avatar billede miknil Nybegynder
13. februar 2003 - 18:45 #5
theStatement er s'føli aStmt :-)
Avatar billede arne_v Ekspert
13. februar 2003 - 18:49 #6
miknil>

Streng taget preparer han ikke noget prepared statement igen. Det kan man
slet ikke.

De to muligheder er:

1)  en referance som først peger på et objekt og senere på et andet objekt
2)  to referancer som peger på hver sit objekt

Jeg vil fordsætte at han er færdig med den ene prepared statement inden
han går igang med den næste (ellers giver #1) ikke meget mening.

De eneste performance forskelle der er på de to er at:
- i #2 er der en referance mere
- i #1 er def første objekt klar til GC lidt før

Ingen af dem betyder noget som helst.

Det er derfor jeg synes at der skal fokuseres på letlæselig kode.
Avatar billede miknil Nybegynder
13. februar 2003 - 19:06 #7
To gange bedes databasen om prepare et SQL statement! længere er den ikke.

Der er ingen gevinst sammenlignet med dynamisk SQL, tværtom.

miknil
Avatar billede arne_v Ekspert
13. februar 2003 - 19:27 #8
Spørgsmålet gik ikke på prepared statement versus almindelig statement
men på genbrug af prepared statement referancen.

Der er 2 grunde til at bruge prepared statements.

Den ene er hvis man skal bruge samme grundliggende SQL sætning
med forskellige parametre flere gange.

Den anden er for at undgå quote problemer.

Hvis dsj kun bruger den prepared statement en gang, så gælder den
første grund ikke.

Men dsj kan jo sagtens bruge prepared statement af den anden grund
eller faktisk bruge den prepared statement flere gange og bare have
valgt ikke at gentage executeQuery linien i hans lille code outline,
fordi det som sagt intet har med hans spørgsmål at gøre.

Det er ganske almindeligt at have flere prepared statements i
et stykke kode.
Avatar billede dsj Nybegynder
13. februar 2003 - 19:29 #9
Det var noget af det som miknil nævner, som jeg tænkte på. Nu har jeg bare aldrig brug for at køre det samme sql-kald flere gange i træk - det skulle da lige være insert's, men det klarer jeg i én sætning med insert ... select (MySQL).

Er der virkelig ingen forskel andet end nogle objekt-referencer??
Avatar billede arne_v Ekspert
13. februar 2003 - 19:34 #10
Ikke i det kode fragmenter du har postet i spørgsmålet.

Hvis du kun bruger din prepared statement så er der ikke nogen
performance fordel ved det (men mkan kan stadig have nytte af det
til at undgå quote problemer).
Avatar billede arne_v Ekspert
13. februar 2003 - 19:40 #11
Dine 2 kode fragmenter ville i C++ se ud som:

  PreparedStatement *prepStmt1 = con.prepareStatement(sql);
  prepStmt1.executeQuery();
  PreparedStatement *prepStmt2 = con.prepareStatement(sql);
  prepStmt2.executeQuery();
  delete prepStmt1;
  delete prepStmt2;

og:

  PreparedStatement *prepStmt1 = con.prepareStatement(sql);
  prepStmt1.executeQuery();
  delete prepStmt1;
  prepStmt1 = con.prepareStatement(sql);
  prepStmt1.executeQuery();
  delete prepStmt1;
Avatar billede miknil Nybegynder
13. februar 2003 - 19:48 #12
Strengt taget er arne's svar korrekt.
Du bør dog overveje om det er nødvendigt at bruge preparedstatement (p.g.a bindvariable ?) eller om ikke dynamisk sql var mere velegnet.
Avatar billede dsj Nybegynder
13. februar 2003 - 19:50 #13
Jeg kan risikere quotes, så jeg bliver nødt til at anvende preparedstatement :)
Avatar billede miknil Nybegynder
13. februar 2003 - 20:04 #14
"Jeg kan risikere quotes" hmmmmm... det er da aldrig et problem - hvem bruger
quotes nu om dage ?

Ellers er det vel noget et requlært udtryk kan klare :-)

miknil
Avatar billede dsj Nybegynder
13. februar 2003 - 20:15 #15
Det gør du: Kommentar: miknil
13/02-2003 19:48:51    Strengt taget er arne's svar korrekt. <----

Det er expnote-serveren jeg arbejder på og der er ofte quotes i spørgsmålenes titler...

Og hvorfor lave en masse algoritmer, hvis man kan anvende preparedstatements :)
Avatar billede miknil Nybegynder
13. februar 2003 - 20:17 #16
"Jeg kan risikere quotes" hmmmmm ....

var selvfølgelig ment som en morsomhed :-)

miknil
Avatar billede dsj Nybegynder
13. februar 2003 - 20:21 #17
I know ;)
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