UCASE and UPPER sql functions - java

I am trying to do the following query:
String query = "SELECT * FROM EMP WHERE UCASE(LAST_NAME) ";
query += "LIKE '" + lastName.toUpperCase() + "%'";
in an example of usage of an servlet to access to a database
But I am getting the error message:
Excepcion java.sql.SQLSyntaxErrorException: ORA-00904: "UCASE": invalid identifier
On the other hand, when I use the UPPER sql function, the example works but the results do not show the values of the LASTNAME column in uppercase. I do not understand what happens.

You're just comparing the upper case values, but you're selecting the actual values with select *

to get the uppercase name in your resultset you need to use UPPER in your select list, not UCASE, like this:
String query = "SELECT UPPER(LAST_NAME) AS UPPERNAME, * FROM EMP WHERE UPPER(LAST_NAME) ";
query += "LIKE '" + lastName.toUpperCase() + "%'";
What your code is doing here is building a query string named query. Once query is complete, it will be sent to the database for parsing and running.
When you are building a query to the database, you have to use the built-in database functions for the part of the query that the database is going to parse and run. So, in your example, Java is doing toUpperCase on lastName and then putting that literal into the query string that will go to the database. UPPER(LAST_NAME) is going into the query string as is, it will get passed to the database just like that and run by the database. So it needs to be a function that the database can parse and run: an Oracle function, not a Java function.

UCASE is a DB2 function & not Oracle. For Oracle, you need to use UPPER .
Second part of your question is already answered by James Z.
Having said that, I am answering because previous answers didn't pointed out SQL injection problem with the way you listed your query.
Make it a habit to always execute parametrized queries with jdbc & not by directly appending values to query string.
String query = "SELECT * FROM EMP WHERE UCASE(LAST_NAME) LIKE ? ";
Your parameter would be - lastName.toUpperCase()+"%"
SQL Injection

Related

Combine JPA Query annotation with Oracle sample method

i am trying to pass a parameter into a JPA query
Example code
#Query(value =
"select *\n"
+ "from adress sample(:percentile)\n"
+ "where adress.number in (:adressNumbers)\n"
+ "fetch first (:rows) rows only,"
+ "nativeQuery = true
List<X> sampleExample(Integer rows, List<Integer> adressNumbers, Double percentile)
But i get an error because of the sample(:percentile).
If i just hardcode a number in there it works but not with a param.
Is there a way to escape the brackets or something similar?
Thx
The error is on the following part
from adress sample(:percentile)
Unfortunately it does not belong to the where part of the query and so the parameter passed :percentile can't be bound to the query.
There is not any quick fix around this. You won't be able to use a method parameter that will be able to be bound in the query in the part that you want it to be, because parameters can only be bound in the where part of the query.

Query returning sql string with wrong parameters

I am currently working on fixing some SQL injection bugs in my project.
Here is my current sql string:
String sql = "select * from :table order by storenum";
Here is how I am setting the parameters:
SQLQuery query = sess.createSQLQuery(sql).setParameter("table", table);
(table is a string that is passed in through a method)
Whenever I run the program I get something like this:
select * from ? order by storenum
You can't dynamically bind table names, only values, so you'll have to resort to string manipulation/concatenation to get the table name dynamically. However, you would probably want to escape it to avoid SQL Injections.

Postgres metrics query

I am new in the database side. My Question is, how to append a piece of query as param arguments. In my logic we are trying to append query using below
GET_DATA= "SELECT [:metrics] from table name"
am passing metrics as argument like below
paramMap.put("metrics", "name,age");
when am executing the query using query runner.
ResultSet rs = queryRunner.runQuery(context, GET_DATA, paramMap, RESULT_SET_HANDLER);
The output of the query like below
SELECT 'name,age' from table name
How can i avoid single quotes from the query?
I have tried these two changes but getting SQL error
[metrics]
metrics
If we put similar syntax with a condition like where colum_name=[:abc],its work fine for me.
Expecting a better solution.
Try this:
String columns = paramMap.get("metrics");
GET_DATA = "Select" +
columns +
" FROM" +
" name";

Passing clojure vec to POSTGRES IN statement (?)

I'm trying to pass an array of strings to a select statement and I keep getting the error:
org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of clojure.lang.PersistentVector. Use setObject() with an explicit Types value to specify the type to use.
I know that the column type is correct, it looks as if passing a vector is the culprit. What is the correct way to do this?
The sql statement is formatted like so:
"SELECT * FROM said_table WHERE item_id IN (?)"
This answer assumes you are using jdbc and not korma or something like it and need to generate the sql directly instead of going through some tool:
the in directive requires you to crate one ? for each item in the list. I end up using this pattern when something else requires me to build the SQL manually:
(let [placeholders (s/join ", " (repeat (count things-go-here) "?"))
query "SELECT * FROM said_table WHERE item_id IN (%s)"]
(exec-raw [(format query placeholders) things-go-here] :results)
....)

using java variable in sql statement

I'm trying to build a web page to better learn Java and SQL. My question is, is there a way in Java to make a generic SQL select statement? For example:
SELECT var1 FROM var2 WHERE var3=var4
or something of the sort.
My idea is to fill the vars with user selected items from the web page. I know this can be done in PHP using the Post method, but I'm not using PHP. Also, I've read about the Prepared Statement in Java, but seems only to work when the used after the comparison operator; ex:
SELECT * FROM table Where attr = ? &
Also, I do know i can do the hard coded version of "SELECT " + var1 + "FROM " + var2 + "WHERE attr = " + var3 + " " but that doesn't seem very generic and prone to a lot of errors.
Incase: I'm trying to build this test page using HTML & JSP.
What you are doing with the ? is parameterizing the query. The query can only be parameterized for values not names of tables or columns.
Every time you run a query. The database has to create a query plan. If you are running the same query again and again, you can reduce this overhead by creating a PreparedStatement.
The first execution of PreparedStatement will generate the query plan. The subsequent executions will reuse the same plan.
Same query here means, it is identical in all respects except values used in where clause, expressions etc.
If you change the Column or Table name or modify the structure of the query, then it is a different query and will require a different query plan. A PreparedStement is not useful in this case and you should stick to the hardcoded version you talked about. Because of this reason you will get an error if you try to parameterize Table or Column names in PreparedStement.
Having said that. It is not advisable to take such a generic approach for queries. If your queries are that simple, you can benefit from ORM tools. You would not have to maintain even a line of SQL. For complex queries you have an option of using ORM specific query language or JPQL or Native SQL. Look for JPA + Hibernate
Your specific usage is not permitted by JDBC. You need to hard code the table name when creating the prepared statement. If you really do want to do that I suggest you use String concatenation to create the SQL statements and then create a PreparedStatement with parameters to handle the where part. In case you are wondering why bother with PreparedStatements in the specific solution, it's to avoid SQL injection.
You can use PreparedStatement to achive your objective.
For example -
String query = "SELECT * FROM table Where attr = ?";
PreparedStatement pt = con.prepareStatement(query);
pt.setString(1, attribete);
pt.executeUpdate();
There is no such direct provision in any of SQL packaged classes or others to replace table, column names along with query parameter values, in a query string, using a single method.
You require to depend on both PreparedStatement and any of String methods replace(...) and replaceFirst(...) to achieve your requirement.
String sql = "Select $1, $2 from $3 where $4=? and $5=?";
sql = sql.replaceFirst( "$1", "col1_name" );
sql = sql.replaceFirst( "$2", "col2_name" );
sql = sql.replaceFirst( "$3", "table_name" );
sql = sql.replaceFirst( "$4", "col4_name" );
sql = sql.replaceFirst( "$5", "col5_name" );
// .. and so on
PreparedStatement pst = con.prepareStatement( sql );
// use relevant set methods to set the query parametrs.
pst.setXXX( 1, value_for_first_query_parameter ); // from a variable or literal
pst.setXXX( 2, value_for_second_query_parameter); // from a variable or literal
// ... and so on
If you are using JDBC, can try this
PreparedStatement statement = connection.prepareStatement("SELECT ? FROM ? WHERE ?=? ");
then
statement.setString(1, "column_name");
statement.setString(2, "table_name");
statement.setString(3, "column_name");
statement.setBigDecimal(4, 123);
If you are using other ORM like Hibernate or JPA, I believe there are also ways to do.

Categories

Resources