sql2o - select query removing trailing spaces from VARCHAR coulmn - java

using sql2o (https://github.com/aaberg/sql2o)
when selecting a VARCHAR column that has trailing spaces (for example "some value ") the return value is "some value"
when selecting from mysql cli the result contains the trailing spaces
cant find any documentation how to prevent this from happening
table:
CREATE TABLE names
(
name VARCHAR(100),
PRIMARY KEY (experiment_key, metric_name)
);
code example:
Sql2o sql2o;
String name = "some name with trailing space ";
try (Connection con = sql2o.open()) {
con.createQuery("INSERT INTO names (name) VALUES(:name)")
.addParameter("name", name)
.executeUpdate();
}
String nameFromDB;
try (Connection con = sql2o.open()) {
nameFromDB = con.createQuery("select name from names")
.executeAndFetchFirst(String.class);
}
if (!nameFromDB.equals(name)){
throw new RuntimeException("where did the trailing spaces go ??? :( ");
}

Think I found your answer in Sql2o.
I believe by using String.class, it is using the StringConverter class to convert your query output into a string. At the very bottom of the StringConverter class is this line:
return val.toString().trim();
Found here

Related

Insert statement with subquery and extra column

I want to use insert statement with select subquery from another table. In my case, I want to add a row from PRESENTATION table to AVAILABILITY table.
AVAILABILITY table structure:
availableID (number, generated using sequence)
availableDay (varchar)
availableStart (varchar)
availableEnd (varchar)
lecturerID(FK) (varchar)
presentationID(FK) (number, generated using sequence)
PRESENTATION table structure:
presentationID (number, generated using sequence)
presentationDay (varchar)
presentationStart (varchar)
presentationEnd (varchar)
I tried to construct the query in DAO like this :
String lecturerID = Abean.getLecturerID();
String availableDay = Abean.getAvailableDay();
String availableStart = Abean.getAvailableStart();
String availableEnd = Abean.getAvailableEnd();
Date availableDate = Abean.getAvailableDate();
String presentationID = Abean.getPresentationID();
try{
currentCon = JavaConnectionDB.getConnection();
PreparedStatement ps=currentCon.prepareStatement("
insert into availability (availableID,
lecturerID,
availableDay,
availableStart,
availableEnd,
presentationid)
select(availabilityseq.nextval,
?,
presentationDay,
presentationStart,
presentationEnd,
presentationid)
from presentation where presentationid=?
");
ps.setString(1,Abean.getLecturerID());
ps.setString(2,Abean.getAvailableDay());
ps.setString(3,Abean.getAvailableStart());
ps.setString(4,Abean.getAvailableEnd());
ps.setString(5,Abean.getPresentationID());
// ps.setString(6,Abean.getAvailableID());
ps.executeUpdate();
}
catch(Exception e){
System.out.println("add availability 2 failed: An Exception has occurred! " + e);
}
As expected, it return error
ERROR: java.sql.SQLException: Invalid column index
So, how can i do insert with subquery with extra column?
UPDATE: MY DAO codes
You need to match the setting of bind variables values with the bind variables specification in the SQL text :
EDIT Apr 18th: removed parenthesis from select subquery
PreparedStatement ps=currentCon.prepareStatement("
insert into availability (availableID,
lecturerID,
availableDay,
availableStart,
availableEnd,
presentationid)
select availabilityseq.nextval,
?,
presentationDay,
presentationStart,
presentationEnd,
presentationid
from presentation where presentationid=?
");
ps.setString(1,Abean.getLecturerID()); // match first "?"
ps.setString(2,Abean.getPresentationID()); // match 2nd "?"

Mysql concat string with comma in java

I am trying to concatenate two ID numbers together but add a comma between them to separate from each other. I know the mysql statement to use but I am having difficulty translating this to a string in my java program. I can get it to work without the comma but I can't seem to figure out the syntax for adding the comma.
Here is my attempt:
query = "UPDATE table SET idColumn = concat(idColumn, ','"+idNum+") WHERE word = '"+wordVariable+"' ";
To clarify, I have a word table which contains a word column and an ID number column. As an example, my ID column might contain a single number as the ID but after multiple concatenations it might look like:
2,5,4,7,1
Change your query to:
query = "UPDATE table SET idColumn = concat(idColumn, ',"+idNum+"') WHERE word = '"+wordVariable+"' ";
I Think you have made mistake on using inverted commas.
Or you can add comma after ','.
query = "UPDATE table SET idColumn = concat(idColumn, ',' , '"+idNum+"') WHERE word = '"+wordVariable+"' ";
Change:
query = "UPDATE table
SET idColumn = concat(idColumn, ','"+idNum+")
WHERE word = '"+wordVariable+"' ";
To:
query = "UPDATE table SET idColumn = concat( idColumn, ',', ? ) WHERE word = ? ";
You were missing a , comma after ',' in the concat.
And using an instance of PreparedStatement you can set values for query placeholders.
pst.setInt( 1, idNum );
pst.setString( 2, wordVariable );
And, I think, your data table design is not correct on idColumn. Instead of storing comma separated values, you better use a normalized form of tables and data.

Update() method doesn't work with ORACLE database

I don't know why the update() method doesn't work with ORACLE database
deleteQuery = "delete from USBRPF where upper(userid) = upper(?)" ;
String s= "ABC " ;
getJdbcTemplate().update(deleteQuery, s.trim());
There's a row with column USERID having data 'ABC ' (there's some spaces character after 'C' character)
It seems to not find out that row.
However, if I change code to below, it works
deleteQuery = "delete from USBRPF where upper(userid) like upper(?)" ;
String s= "ABC " ;
getJdbcTemplate().update(deleteQuery, s.trim() + "%");
or
deleteQuery = "delete from USBRPF where upper(trim(userid)) = upper(?)" ;
String s= "ABC " ;
getJdbcTemplate().update(deleteQuery, s.trim());
Note: all works with MSSQL database, with data migrated from ORACLE.
I guess there's problem with database setting. Could have someone figure it out? Thanks
MODIFIED:
Column information:
ORACLE
BRANCH CHAR(2 CHAR)
COMPANY CHAR(1 CHAR)
DATIME TIMESTAMP(6)
JOBNM CHAR(10 CHAR)
UNIQUE_NUMBER NUMBER(18,0)
USERID CHAR(10 CHAR)
USRPRF CHAR(10 CHAR)
MSSQL
[UNIQUE_NUMBER] [bigint] IDENTITY(1,1) NOT NULL,
[USERID] [nchar](10) NULL,
[COMPANY] [nchar](1) NULL,
[BRANCH] [nchar](2) NULL,
[USRPRF] [nchar](10) NULL,
[JOBNM] [nchar](10) NULL,
[DATIME] [datetime2](6)> NULL,
CHAR is a fixed length type. So even if your data looks like "ABC" in the database, it's stored as "ABC ". CHAR columns will be padded with spaces up their size.
Therefore on the first example you're comparing "ABC " (as stored in the DB) to "ABC" (as passed from Java after the trim() call). On your second and third example you're working around this.
I would recommend that you use VARCHAR2 since it's more natural and more commonly used. If not possible, you could try padding the value that you pass from Java up to the CHAR size as defined in Oracle.

SQL query to select tablename

I want to get all database table names that ends with _tbl like xyz_tbl, pqr_tbl,etc..
in mysql using java.pls help me.. currently my query retreives all tablename but i jst want table names that ends with _tbl.
My code is...
public List selectTable() {
List tableNameList= new ArrayList();
try {
DatabaseMetaData dbm = c.conn.getMetaData();
String[] types = {"TABLE"};
c.rs = dbm.getTables(null, null, "%", types);
while (c.rs.next()) {
tableNameList.add(c.rs.getString("TABLE_NAME"));
}
} catch(Exception e) {
System.out.println(e.toString());
}
return tableNameList;
}
Did you try using a different table name pattern?
You can try this: -
c.rs = dbm.getTables(null, null, "%_tbl", types);
You can use mysql query
show tables from tablename like '%_tbl';
I am unable to reply to Rohit's post. his answer looks correct.
If you do to JDK documentation for DatabaseMetaData's getTables method following is the signature and documentation comment.
ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern,
String[] types) throws SQLException
Parameters:
catalog - a catalog name; must match the catalog name as it is stored
in the database; "" retrieves those without a catalog; null means that
the catalog name should not be used to narrow the search
schemaPattern
- a schema name pattern; must match the schema name as it is stored in the database; "" retrieves those without a schema; null means that the
schema name should not be used to narrow the search tableNamePattern -
a table name pattern; must match the table name as it is stored in the
database types - a list of table types, which must be from the list of
table types returned from getTableTypes(),to include; null returns all
types
In this case using %_tbl should work.
Use the String.endsWith() method to check if the table name ends with "_tbl".
For example inside your while loop:
while (c.rs.next())
{
String tableName = c.rs.getString("TABLE_NAME");
if(tableName.endsWith("_tbl"))
{
tableNameList.add(c.rs.getString("TABLE_NAME"));
}
}

resultSet obtained if parameter containing whitespace concatenated, but not using setString

I have this piece of code, with a prepared statement. I know the query is redundant. the parameter id is a string <space>413530 (" 413530"). Please note the preceding whitespace character.
String query = "SELECT RSCode as id FROM Customer WHERE RSCode=?";
PreparedStatement newPrepStatement = connection
.prepareStatement(query);
newPrepStatement.setString(1, id);
resultSet1 = newPrepStatement.executeQuery();
while (resultSet1.next()) {
System.out.println("Got a result set.");
logindata.add(resultSet1.getString("id"));
}
I do not get any results after executing this query.
Now, if I use the same statements and append the parameter as part of the string as follows:
String query = "SELECT RSCode as id FROM Customer WHERE RSCode=" + id;
PreparedStatement newPrepStatement = connection
.prepareStatement(query);
resultSet1 = newPrepStatement.executeQuery();
while (resultSet1.next()) {
System.out.println("Got a result set.");
logindata.add(resultSet1.getString("id"));
}
I get a result as after executing this prepared statement. Same also works with a java.sql.statement
I wish to know why the driver ignores the whitespace in the second piece of code, but has a problem in the first part.
If you use setString the parameter will be bound as a string resulting in this SQL (considering the bound parameter an SQL string):
SELECT RSCode as id FROM Customer WHERE RSCode=' 0123';
If you use concatenation the SQL used will be (considering the concatenated value as an integer, since space will be ignored as part of the SQL syntax):
SELECT RSCode as id FROM Customer WHERE RSCode=<space>0123;
In this case I would advise to convert it to int or long or whatever it is and bind it with the right type. With setInt() or setLong().
And if you field is a string you could normalize it first using for example:
String normalizedValue = String.trim(value);
newPrepStatement.setString(1, normalizedValue);
or even direct in SQL like:
SELECT RSCode as id FROM Customer WHERE RSCode=TRIM(?);
In scenario - 1, the query will look like this
"SELECT RSCode as id FROM Customer WHERE RSCode=' 413530'"
In scenario - 2, the query will look like this
"SELECT RSCode as id FROM Customer WHERE RSCode= 413530"

Categories

Resources