How to make SELECT statement case sensitive in jdbc (DB2) - java

I have the following query
String sql = select id from sheet_tab where filename in ('value.xls','export.xls')
and I am executing it using
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
Now the problem is there is another file in my db with name of 'Export.xls' and when I try to fetch for 'export.xls' it doesn't return me any id (which I am finding it strange), but seems to work fine when 'Export.xls' is passed and it fetches the concurrent id for that particular file.
Can anyone pls help me with this.???
I want a query which wd fetch the result set for 'export.xls' and NOT 'Export.xls' (i.e. as case sensitive one)
P.S. LOWER func wont work as the filename is getting fetched by a javacode dynamically so we don't actually know what are the filenames that are being queried, e.g. it can be value.xls, VaLue.xls , ExPort.xls.

String sql = select id from sheet_tab where filename in ('value.xls','export.xls')
String sql = select id from sheet_tab where ucase(filename) in ('VALUE.XLS','EXPORT.XLS')
String sql = select id from sheet_tab
where UCASE(filename) in (UCASE('value.xls'),UCASE('export.xls'))

Related

ORA-04054: database link GMAIL.COM does not exist

I need help with my college's project(Java web with hibernate and oracle database), this has to edit the users already added previously which have:
Mail pk
pass
typeuser.iduser FK.
add and remove it works but doesnt edit, the error is :
javax.servlet.ServletException: java.sql.SQLSyntaxErrorException: ORA-04054: database link GMAIL.COM does not exist
i already tried with using prepared statement but i think i did it wrong
the mail does not need to be edited. only the type of user and password needs it but at the moment of pressing the edit button it shows me the error gmail.com does not exist
<%
//CONECTANOD A LA BASE DE DATOS:
Class.forName("oracle.jdbc.OracleDriver").newInstance();
Connection con = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:XE", "C##PORTA", "oracle");
String id = request.getParameter("correo");
PreparedStatement stm = con.prepareStatement(id);
String Query = "select * from usuario where correo=" + id;
PreparedStatement ps;
ResultSet rs = stm.executeQuery(Query);
while (rs.next()) {
%>```
OldProgrammer has shown you the correct way to do this. If you use a PreparedStatement (correctly) it will deal with quoting correctly, and also protect against SQL injection attacks.
The reason you got the obscure error message was that your SQL statement most likely looks something like this after you concatenated it:
select * from usuario where correo=someone#gmail.com
Since the email address is not quoted, the SQL parser doesn't recognize that as a string literal. Instead, it is treating it as a "db link" as described in CREATE DATABASE LINK.
After you have created a database link, you can use it in SQL statements to refer to tables and views on the other database by appending #dblink to the table or view name.
And that fails because no such database link with the name "gmail.com" has been created.
You are not calling the correct methods with the correct parameters. Should be something like:
String id = request.getParameter("correo");
String query = "select * from usuario where correo= ?";
PreparedStatement stm = con.prepareStatement(query);
stm.setString(1, id );
ResultSet rs = stm.executeQuery();

Sql query does not cooperate

I get this weird error (java.sql.SQLSyntaxErrorException) when running my program. I didnt find something 100% related unfortunately. Any help would be appreciated!I am using Derby db.
String id = request.getParameter("gid");
stmt = con.createStatement();
String strSql = "select img from guitar where gid="+id+" ";
rs = stmt.executeQuery(strSql);
String id = request.getParameter("gid");
'id' is string hence :
String strSql = "select img from guitar where gid="+"'"+id+"'"+" ";
If you believe id has to be integer then convert it into integer before you pass it
Side Note : Your code is prone to sql injection, why don't use PreparedStatment and pass the variable
The error says SyntaxError so probably you write something wrong in the query. getParameter returns a string. Based on the comments, you are trying to insert a string into a integer column. Try parsing it before.
I'm asuming you already established the conection to the DB and get a response, try select * from guitar that should get the list of records in the table, if you get a response the try to write directly the query in your DB. gid must be the name of a column, also img and try specifiying the database name as [name].guitar. Otherwise, your conection is failling
Also which .jar are you using? take a look at JDBC
I fixed it by using the following:
String strSql = "select img from guitar where gid=" + Integer.parseInt(idString);
Thanks for your help anyway!!

Java PreparedStatement SQL syntax error [duplicate]

This question already has answers here:
Java PreparedStatement complaining about SQL syntax on execute()
(6 answers)
Closed 6 years ago.
This is a really weird error that only started appearing today. When I use a prepared statement with ? for parameters, I get an error, but when I use it without parameters, it works just fine.
Here is the error-causing code:
String table = "files";
Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
PreparedStatement prep = conn.prepareStatement("SELECT * FROM ?");
prep.setString(1, table);
ResultSet rs = prep.executeQuery();
while(rs.next()) {
System.out.println(rs.getString("file_name"));
}
This produces the following error:
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''files'' at line 1
Also, changing it to the following works just fine:
String table = "files";
Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
PreparedStatement prep = conn.prepareStatement("SELECT * FROM " + table);
ResultSet rs = prep.executeQuery();
while(rs.next()) {
System.out.println(rs.getString("file_name"));
}
This doesn't seem to be making a whole lot of sense. Any ideas?
Tried it on another table and got more weired results.
This works and logs the admin in correctly:
String sql = "SELECT * FROM " + ADMIN_AUTH_TABLE + " WHERE " + column + " = '" + hashedPassword + "'";
PreparedStatement prepared = connection.prepareStatement(sql);
The following doesn't cause errors, but returns a message saying that the password entered is incorrect (it's correct - I double triple checked).
String sql = "SELECT * FROM " + ADMIN_AUTH_TABLE + " WHERE ? = ?";
PreparedStatement prepared = connection.prepareStatement(sql);
prepared.setString(1, column);
prepared.setString(2, hashedPassword);
Got it: use ? for values.
Also, the answer here helped.
Bind parameters cannot be used for identifiers in the SQL statement. Only values can supplied through bind placeholders.
This will work:
SELECT foo FROM bar WHERE id = ?
This will not work, because the table name is an identifier
SELECT foo FROM ? WHERE id = 2
You can't supply a column name, because column names are also identifiers.
A statement like this will run, but it may not do what you think it does.
SELECT ? AS foo FROM bar WHERE ? = 0
If we supply values of 'foo' for both placeholders, the query will actually be equivalent to a query containing two string literals:
SELECT 'foo' AS foo FROM bar WHERE 'foo' = 0
MySQL will run that statement, because it's a valid statement (if the table bar exists and we have privileges on it.) That query will return every row in bar (because the predicate in the WHERE clause evaluates to TRUE, independent of the contents of the table.. And we get returned the constant string foo.
It doesn't matter one whit that the string foo happens to match the name of column in our table.
This restriction has to do with how the SQL optimizer operates. We don't need to delve into all the details of the steps (briefly: parsing tokens, performing syntax check, performing semantics check, determining query plan, and then the actual execution of the query plan.)
So here's the short story: The values for bind parameters are supplied too late in that process. They are not supplied until that final step, the execution of the query plan.
The optimizer needs to know which tables and columns are being referenced at earlier stages... for the semantics check, and for developing a query plan. The tables and columns have to be identified to the optimizer. Bind placeholders are "unknowns" at the time the table names and column names are needed.
(That short story isn't entirely accurate; don't take all of that as gospel. But it does explain the reason that bind parameters can't be used for identifiers, like table names and column names.)
tl;dr
Given the particular statement you're running, the only value that can be passed in as a bind parameter would be the "hashedPassword" value. Everything else in that statement has to be in the SQL string.
For example, something like this would work:
String sqltext = "SELECT * FROM mytable WHERE mycolumn = ?";
PreparedStatement prepared = connection.prepareStatement(sqltext);
prepared.setString(1, hashedPassword);
To make other parts of the SQL statement "dynamic" (like the table name and column name) you'd have to handle that in the Java code (using string concatenation.) The contents of that string would need to end up like the contents of the sqltext string (in my example) when it's passed to the prepareStatement method.
The parameters of PreparedStatement should be applied only in parameters that can be used in conditional clauses. The table name is not the case here.
If you have a select where the table name can be applied in the conditional clause you can do it, otherwise you can not.

JDBC CallableStatement Stored Procedure CURSOR result set fetch

I want to export huge data from oracle to csv file. so i used simple JDBC select statement to get data in memory but and then write it to file, But data is very large of i am getting Out of memory exception. So i thought of using CallableStatement to call Stored Procedure which will return CURSOR with ResultSet as below :-
String getDBTableCursorSql = "{call getDBTableCursor(?,?)}";
callableStatement = dbConnection.prepareCall(getDBTableCursorSql);
callableStatement.setString(1, "test");
callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
// execute getDBTableCursorSqlstore procedure
callableStatement.executeUpdate();
// get cursor and cast it to ResultSet
rs = (ResultSet) callableStatement.getObject(2);
// loop it like normal
while (rs.next()) {
String userid = rs.getString("ID");
String userName = rs.getString("NAME");
..
..
}
Oracle Proc :-
CREATE OR REPLACE PROCEDURE getDBTableCursor(
p_username IN DBUSER.USERNAME%TYPE,
c_dbuser OUT SYS_REFCURSOR)
IS
BEGIN
OPEN c_dbuser FOR
SELECT * FROM CUSTOMER WHERE USERNAME LIKE p_username || '%';
END;
Question 1 :-
does above ResultSet will fetch all the data in single shot ? or it will go to database for each rs.next(),
Question 2:-
is there any other approach which can deal with large data export to file in java using chunks so it wont get Out of memory issue?
I can't use pagination in this condition because of requirement.
Regarding your first question: the Oracle jdbc driver by default fetches 10 rows at a time. This can be verified or set to other value via standard jdbc:
https://docs.oracle.com/cd/E11882_01/java.112/e16548/resltset.htm#JJDBC28621

Oracle DB Query Runs in sqlDev but not in Java Program

I have been messing with Oracle DB queries that run from my JAVA app. I can successfully get them all to run in SQL Developer. But when I am trying to execute them from my JAVA app I usually get UpdatadbleResultSet Error/Exception on certain queries.
Also, sometimes I receive, ExhaustedResultset. As I mention at the bottom I will re work the question to break it down(When I get a chance). I keep editing and pretty soon it'll be a book.
Why is this? I cannot seem to pinpoint the problem.
Some queries run successfully such as:
SELECT table_name
FROM all_tables
SELECT column_name, data_length
FROM all_tab_columns
WHERE table_name = 'mytable'
But when I try and run something like
SELECT length(<myColumnName>)
FROM mytable
I get the updateableResultSetError
I am running my queries as methods called on button clicks (example below).
static void testQuery() {
String query = "SELECT blah from blah"
String length;
ResultSet rs = db.runQuery(query);
Length = rs.getString("length(myCol)")
System.out.println(length);
}
I have also tried while rs.next()
I can only think that for some reason I am unable to get into each table and I can only pull the "bigger" picture.
EDIT: Explained DB Connection
I am connecting using some other jarfiles that have been added to my project.
private static IDriver driver = null;
private static Database db = null;
I then pass in all my connection credentials in a separate method.
private void connectDB(){
driver = new OracleDriver();
db = new Database(driver)
driver.getPassword;
driver.getetc;
driver.getEtc;
}
EDIT:
When I getstacktrace all I am returning is.
Ljava.lang.StatckTraceElement;(assortment of random characters).
I may not be getting stack traces right so someone can fill me in. After all I am offering a bounty.
Also I will edit this question and break it down again when I have the time.
Your problem is that you're trying to update a query that can't be updated, hence the updateable result error. It seems that whoever is creating your database connection or executing your query is creating an updatable result set.
You can't use certain types of select in an updatable result set: you can't use aggregated functions (such as length, min, max), you can't use select * etc.)
For the full list see Result Set Limitations and Downgrade Rules
Try retrieving the value in your select statement via the columnIndex instead of the column name and see if that makes a difference.
Currently, its hard to tell what your db.runQuery() does since that code is not posted.
String query = "SELECT length(myCol) FROM myTable";
String length;
ResultSet rs = db.runQuery(query);
while (rs.next()) {
length = rs.getString(1);
System.out.println(length);
}
I've got an inkling what may be happening here (which would explain why some queries work, and some don't). Accoring to the jdbc ResultSet javadocs, when using the getString() method of the result set, the column label.
the label for the column specified with the SQL AS clause.
If the SQL AS clause was not specified, then the label is the name of the column
As "length(myCol)" is neither a label nor a column name, it may be that it fell over because of that (but without stacktrace it is difficult to say what your problem actually is).
Try
String query = "SELECT length(myCol) AS myCol_len FROM myTable"
ResultSet rs = db.runQuery(query);
String length = rs.getString("myCol_len");
Though are you sure, you didn't want:
int length = rs.getInt("myCol_len");
Alternatively (as written by Kal), you can use the column index to get the data from the result set, which oblivates the need for a SQL AS label:
String query = "SELECT length(myCol) FROM myTable"
ResultSet rs = db.runQuery(query);
String length = rs.getString(1);

Categories