Oracle db, jdbc, web app with struts2/spring.
Example table could be this:
CREATE TABLE album
(
album_id number(10) not null,
artist varchar2(50) not null,
title varchar2(50) not null,
released DATE,
CONSTRAINT album_pk PRIMARY KEY (album_id)
);
In may app the user MAY search, MAY sort, and the result from an select might return 10.000 rows.
The basic sql usually look like this.
String sql = "select album_id, artist, title, released from album";
Then in the html page the user can add search criteria for each column. Like type "iron maiden" in artist field, put "1982" in released field. And you all know what the exceptionally result should be from that :)
Now I need to modify the sql a bit:
if( artist search field contains stuff )
{
sql = sql + " where nvl( artist,' ') like ?"
}
we try use prepared statements right? So we use ? as placeholders, and then add "iron maiden" into this statement later on.
Nice, no big fuzz right, and pretty safe from sql injections i guess.
But now I have to have an if/else for every single field in the table. Boring. In my app I got like 25 tables like this, with 20 columns minimum. Copy/Paste have never been so boring.
I also might have to add "order by" with user selected columns and their order. I have to count the query to get total result in case i got to split it up in pages. So there is alot of if/else and sql = sql + "more stuff", and sticking to ? and pure prepared statements is impossible.
But doing this is not good either:
for( each element in a map)
{
sql = sql + " and nvl( " + key + ",' ') like ?"
}
Where key is "artist".
In struts and other tag libs its easy to make kode like:
<s:textfield name="model.addSearch( 'artist' )" value="%{model.getSearch( 'artist' )}" size="30" />
Silly example maybe, but just to make a point.
Inputed values in an html form, can very easily be a part of a dynamic created sql - which becomes a security problem later on.
Artist is an column name. Key should be validated if it contained an valid column name.
I could make a list of strings, containing valid column names to check against.
My question is if there is possible to get this type of information from the database, so I don't have to hand-make these lists?
But I also want to keep the number of heavy and slowing queries down.
My app have like 25 tables now, and I could easily get away with hand-make everything, copy/paste around etc. But I have more projects and this question will be here next time too. And after there again...