Spring Data Cassandra custom insert query failing at '.' in String - java

I have written a custom save query so that I can add a configurable TTL on each item. Here is my repo:
#Repository
public interface MyCassandraRepository extends
TypedIdCassandraRepository<MyCassandraItem, UUID> {
#Query("insert into " + TABLE_NAME + " (" + CQL_UUID + ", " + CQL_PLAN + ") values (?0, ?1) using ttl ?2")
MyCassandraItem customSaveWithTtl(UUID uuid, String plan, Integer ttl);
}
Here is my table:
CREATE TABLE IF NOT EXISTS my_users.plans (
user_id uuid,
plan text,
PRIMARY KEY (user_id)
) ;
However, when I try to add an entry where the plan String contains a full stop/period (eg. eyJhbGciOiJIUzUxMiJ9.hsdyu7832uwhjjdsjkdsew2389dhj), I get the following error:
org.springframework.cassandra.support.exception.CassandraQuerySyntaxException: line 1:110 mismatched input 'eyJhbGciOiJIUzUxMiJ9' expecting ')' (...plan) values ('c7a8fd65-8ef5-420e-b02e-898fe248bbf3', ''[eyJhbGciOiJIUzUxMiJ9]....); nested exception is com.datastax.driver.core.exceptions.SyntaxError: line 1:110 mismatched input 'eyJhbGciOiJIUzUxMiJ9' expecting ')' (...plan) values ('c7a8fd65-8ef5-420e-b02e-898fe248bbf3', ''[eyJhbGciOiJIUzUxMiJ9]....)
Trying to add it manually using CQLSH, I also get an error with the '.':
SyntaxException: line 1:826 no viable alternative at input '.' (... "plan") VALUES (c7a8fd65-8ef5-420e-b02e-898fe248bbf3, [eyJhbGciOiJIUzUxMiJ9].hsdyu7832uwhjjdsjkdse...)
Can anyone see how I can get it to add the whole String and not just stop at the '.'?

You may try using PreparedStatement
String originalPlan = "eyJhbGciOiJIUzUxMiJ9.hsdyu7832uwhjjdsjkdsew2389dhj";
PreparedStatement preparedStatement = cqlTemplate.getSession().prepare("insert into plans (user_id, plan) values (?, ? )");
Statement insertStatement = preparedStatement.bind(UUIDs.timeBased(), originalPlan );
cqlTemplate.execute(insertStatement);

Related

Creating a sequence on an existing table - ORA-00940: invalid ALTER command

I created a sequence and I want a table to make use of it. The creation of the sequence works fine. However, I when I try to alter the table in order to make use of the sequence, I get this error (in personInformationSequenceAlterTest):
ORA-00940: invalid ALTER command
Please note I need to use Java (Eclipse IDE).
String personInformationSequenceTest =
"CREATE SEQUENCE seq_person "
+ "start with 1 "
+ "increment by 1 "
+ "NOCACHE "
+ "NOCYCLE ";
String personInformationSequenceAlterTest =
"alter table personInformationTest "
+ "alter column personId "
+ "set default nextval('seq_person')";
String personInformationSequenceOwnedTest =
"alter sequence seq_person owned by personInformationTest.personId";
Your alter statement has syntax problem.
Try this (assuming datatype is int for that column. Change accordingly):
alter table personInformationTest modify (personId int default seq_person.nextval);
This will only work in Oracle 12c and up.
For 11g or lower, you can use triggers. If you don't want to use triggers, you can explicitly use seq_person.nextval in your inserts.
insert into personInformationTest (personId, . . .)
values (seq_person.nextval, . . .)
Check by Changing
String personInformationSequenceAlterTest =
"alter table personInformationTest "
+ "alter column personId "
+ "set default nextval('seq_person')";
to
String personInformationSequenceAlterTest =
"alter table personInformationTest "
+ "modify column personId "
+ "set default nextval('seq_person')";
In Oracle and MySql we use "Modify" for altering an existing column . In SQL Server / MS Access , "Alter" is used .

JDBC: Create table query syntax error

I am trying to execute a create query using JDBC. I have a method which creates the query and then I execute it but its showing me syntax error. Below is the stack trace :
com.mysql.jdbc.exceptions.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 'supplierId varchar,supplierUrl varchar,totalActivities varchar,activityName varc' at line 1
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2941)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3243)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1343)
at com.mysql.jdbc.Statement.executeUpdate(Statement.java:1260)
Now the query generated is this :
create table demo ( ID INTEGER PRIMARY KEY AUTO_INCREMENT,supplierName varchar,supplierId varchar,supplierUrl varchar,totalActivities varchar,activityName varchar,activityPrice varchar,tourCode varchar,starRating varchar,totalReviews varchar,geography varchar,duration varchar,category varchar,subCategory varchar);
And below is the method which is generating this query :
private static String getCreateTableQuery(String tableName, String columnData) {
StringBuilder sqlStatement = new StringBuilder("");
sqlStatement.append("create table " + tableName + " ( ID INTEGER PRIMARY KEY AUTO_INCREMENT,");
String[] columns = columnData.split(">"); // columns are separated by >
for (int i = 0; i < columns.length; i++) {
sqlStatement.append(columns[i] + " varchar");
if (i != columns.length - 1) { // no commas after last column
sqlStatement.append(",");
}
}
sqlStatement.append(");");
return sqlStatement.toString();
}
And this is how am executing the query :
SessionImpl sessionImpl = (SessionImpl) getSessionFactory().openSession();
Connection conn = (Connection) sessionImpl.connection();
Statement statement = (Statement) conn.createStatement();
statement.executeUpdate(query);
sessionImpl.close();
conn.close();
Am unable to understand the syntax error. Can someone please explain?
I think you have to pass max length for varchar fields:
Please check this your query will be like that:
create table demo ( ID INTEGER PRIMARY KEY AUTO_INCREMENT,supplierName varchar(255),supplierId varchar(255),supplierUrl varchar(255),totalActivities varchar(255),activityName varchar(255),activityPrice varchar(255),tourCode varchar(255),starRating varchar(255),totalReviews varchar(255),geography varchar(255),duration varchar(255),category varchar(255),subCategory varchar(255));
Here is insert Query:
insert into demo
( supplierName, supplierId, supplierUrl, totalActivities, activityName,
activityPrice, tourCode, starRating, totalReviews, geography, duration,
category, subCategory)
values
(supplierName, supplierId, supplierUrl, totalActivities, activityName,
activityPrice, tourCode, starRating, totalReviews, geography, duration,
category, subCategory)
In Mysql you need to define a length to the varchar. Take a look here:
Why does VARCHAR need length specification?
I don't see a problem with your Java code. Fix your create table statement and you'll probably be fine.

Database value insertion Error

How can i manually insert values if not exist...i tried following code but it produce error.How can i insert values if not exist in the table
String sql1 = "CREATE TABLE IF NOT EXISTS admin " +
"(id INTEGER not NULL AUTO_INCREMENT, " +
" user_name VARCHAR(255), " +
" password VARCHAR(255), " +
" isAdmin BOOLEAN NOT NULL DEFAULT '0', " +
" memo VARCHAR(255), " +
" PRIMARY KEY ( id ))";
stmt.executeUpdate(sql1);
String insert="INSERT INTO admin IF NOT EXISTS(id,user_name,password,isAdmin,memo)VALUES(1,'admin','admin',1,'memo')";
stmt.executeUpdate(insert);
it produce an error like
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 'IF NOT EXISTS(id,user_name,password,isAdmin,memo)VALUES(1,'admin','admin',1,'mem' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
String insert="INSERT INTO admin IF NOT EXISTS(id,user_name,password,isAdmin,memo)VALUES(1,'admin','admin',1,'memo')";
should be
String insert="INSERT IGNORE INTO admin (id,user_name,password,isAdmin,memo)VALUES(1,'admin','admin',1,'memo')";
MySQL (and any other SQL implementation as well) doesn't support IF NOT EXISTS in INSERT queries.
your INSERT query must be
"INSERT IGNORE INTO admin (id,user_name,password,isAdmin,memo) VALUES (1,'admin','admin',1,'memo')"
What you want may be INSERT ... ON DUPLICATE KEY UPDATE or INSERT IGNORE....
The former will update an existing row if a duplicate insert is detected, while the latter will just throw away duplicate inserts.
In both cases, you'll have to create a UNIQUE constraint on the column you want to check for duplicates. If the UNIQUE is violated, the alternate function is invoked.

keep column name variable in Java INSERT INTO command with PreparedStatement?

I have the following problem:
I have two tables in one data base which consist of the same columns besides the name of the last column. I want to write data into them using Java.
I want to use the same preparedStatement for both tables, where I check with an if-command whether it is table1 or table2. table2 has amount10 as the name for the last column, table1 has amount20 for it. This number is stored in a variable within my code.
Below you can see a (simplified) example and how I tried to let the column name variable but it doesn't work. Is there any way to fix this without copying the whole statement and manually changing the number variable?
String insertData = "INSERT INTO `database`.`"+table+"`
(`person_id`,`Date`,`amount`+"number") VALUES "+
"(?,?,?) ON DUPLICATE KEY UPDATE " +
"`person_id` = ? , " +
"`Date` = ? , " +
"`amount`+"number" = ? ; ";
PreparedStatement insertDataStmt;
This will not work since variables number and table are not going to be magically injected into your insertData string while you are changing them.
I'd to a method prepareInsertstatement(String table, String number) that would return correct PreparedStatement:
public void prepareInsertStatement(Connection conn, Strint table, String number) {
String insertData = "INSERT INTO `database`.`"+table+"`
(`person_id`,`Date`,`amount+"number"') VALUES "+
"(?,?,?) ON DUPLICATE KEY UPDATE " +
"`person_id` = ? , " +
"`Date` = ? , " +
"`amount+"number"' = ? ; ";
PreparedStatement insertDataStmt = conn.prepareStatement(insertData);
return insertDataStmt;
}
Just remember to close the PreparesStatement when you don't need it any more.
I suppose that reason for that is invalid syntax. When you concatenate string for last column name you use code 'amount' + number. If your number value is 20, than concat result will be
'amount'20 that cause invalid syntax exception. Just move one extra ' after number.
"'amount" + number + "'"
Note: log, or just error that appears during this statement execution would be very useful to find right answer for your question.

Escaping a single quote when using JdbcTemplate

We're using JdbcTemplate to modify our underlying Oracle database. We're doing this by way of the update(String sql) method.
The code looks somehow like the following:
String name = "My name's yellow";
String sql = "update FIELD set NAME = '" + name "' where ID = 10
jdbcTemplate.update(sql);
This causes the error:
java.sql.SQLException: ORA-00933: SQL command not properly ended
The problem is the unescaped ' in the name variable.
What's the most convenient and correct way to escape this character?
Use PreparedStatement. That way you nominate a placeholder and the JDBC driver will perform this correctly by sending the database the statement, plus the parameters as arguments.
String updateStatement =
"update " + dbName + ".COFFEES " +
"set TOTAL = TOTAL + ? " +
"where COF_NAME = ?";
PreparedStatement updateTotal = con.prepareStatement(updateStatement);
updateTotal.setInt(1, e.getValue().intValue());
updateTotal.setString(2, e.getKey());
The question marks in the above represent the placeholders.
Because these values get passed as parameters, you don't have problems with quoting, and it protects you against SQL injection too.
Try for name :
if ( name.contains("'") ){
name.replaceAll("'", "''");
}

Categories

Resources