When using QUERY_BAND whith paramitrized PreparedStatement, i got this exception :
java.sql.SQLException: [Teradata Database] [TeraJDBC 16.20.00.04] [Error 5992] [SQLState HY000] A syntax error was found in the QUERY_BAND.
My code :
String queryBand = "SET QUERY_BAND = ? UPDATE FOR SESSION VOLATILE;";
try {
dbConnection = baseJDBCTemplate.getDataSource().getConnection();
//set user name in the Query Band
try (PreparedStatement stmt = dbConnection.prepareStatement(queryBand)) {
stmt.setString(1, "USER=x256;");//"+rtId+"
stmt.execute(queryBand);
}
catch (SQLException e) {
throw new SIRRestitGeneratorException("DB Exception ",e);
}
i did the same thing recomanded n Teradata documentation
https://docs.teradata.com/r/eWpPpcMoLGQcZEoyt5AjEg/RH2BOZYzHp6u4dhsrWbRlw
i'm using
Teradata version 16.20.00.04
Spring Boot 1.5.8
As you are using the JdbcTemplate you are using it wrong, and dangerous as this leaks a connection, when executed enough times, it will grind your app to a hold.
Use the JdbcTemplate in a proper way.
jdbcTemplate.execute(queryBand, (ps) -> {
ps.setString(1, "USER=x256");
return ps.execute();
});
This should execute your query and return a boolean if it succeeded or not. Which of course you can ignore if you don't need that.
With this you are properly utilizing the JdbcTemplate.
Finally i found the response in this doc
https://docs.teradata.com/r/rgAb27O_xRmMVc_aQq2VGw/oXcSulxgPuaDnG0qMLYYrg
The ? parameter is not supported for SESSION, it's supported only for TRANSACTION.
String queryBand = "SET QUERY_BAND=? UPDATE FOR SESSION VOLATILE;"; // not accepted
String queryBand = "SET QUERY_BAND=? UPDATE FOR TRANSACTION;"; // accepetd
So in my case (updating the session), i can't use the ? parameter, so i use this (even i have sonar security alert):
String queryBand = "SET QUERY_BAND='USER="+StringEscapeUtils.escapeSql(rtfeId)+";' UPDATE FOR SESSION VOLATILE;";
Related
Getting Exception from below hibernate query while calling the API.
dao class method:
public List<ErmChangeLog> fetchChangeLog(JsonInput jsonInput) throws SQLException {
Session session = this.sessionFactory.openSession();
List<ErmChangeLog> objectList = null;
Long instanceKey = 0L;
try {
instanceKey = jsonInput.getSystematic_Risk_ID();
logger.debug("Connection creation process is completed.");
Query query = session.createQuery(CommonConstants.fetch_ChangeLog);
logger.info("query : " + CommonConstants.fetch_ChangeLog);
query.setParameter("instanceKey", instanceKey);
logger.info("instanceKey : " + instanceKey);
objectList = query.list();
} catch (Exception e) {
logger.debug("Failed to fetch Change Log");
e.printStackTrace();
throw e;
}
session.close();
return objectList;
}
query : String fetch_ChangeLog= "from ErmChangeLog p where p.instanceKey =:instanceKey";
exception :
at java.lang.Thread.run(Thread.java:745)
[2019-07-16 16:39:10,915]:org.hibernate.util.JDBCExceptionReporter-[WARN]: SQL Error: 17059, SQLState: 99999
[2019-07-16 16:39:10,915]:org.hibernate.util.JDBCExceptionReporter-[ERROR]: Fail to convert to internal representation
[2019-07-16 16:39:10,916]:org.hibernate.jdbc.ConnectionManager-[DEBUG]: transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
Looks like your parameters do not match the data types expected by the query. Can you try with Integer instead of Long?
I agree with the answer of #Ucello; this will appear when there is a data type mismatch. But also when running the wrong project's version.
I used to have separated front-end and back-end projects. When I ran Grails (front-end), I didn't realize I was running MyApp v3.1 but having started the Java back-end of MyApp v3.0. So, between the 3.1 and 3.0 versions, there was a mismatch in the data types and throwing this error.
Not sure if this helps other users. It took me time to realize :)
I'm getting a syntax error in my prepared statement even though my query runs in SQL Management Studio. I am using GlassFish 4.1.1. What am I doing wrong?
I've tried switching the syntax around a bit but I always get an error.
Here is my connection pool code:
try {
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup("java:comp/env/" + database);
} catch (Exception ex) {
ex.printStackTrace();
}
Here is my query code:
ConnectionPool pool = new ConnectionPool("BoxPointHAMBURGO");
Connection connection = pool.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
try {
String query = "SELECT Tabla FROM BoxPointHAMBURGO.dbo.NombresTablas";
ps = connection.prepareStatement(query);
rs = ps.executeQuery();
} catch (Exception ex) {
System.err.println("Error: " + ex.getMessage());
}
The error that I get is:
Syntax error: Encountered "." at line 1 column 39.
As per this answer the double dot .. operator results in default schema for the current database user being used for the query. However you shouldn't expect that SQL Management Studio query syntax will work when using JDBC. These are two completely different driver interfaces with different limitations, JDBC most likely being more restrictive.
You probably should select the BoxPointHAMBURGO database when you establish the JDBC connection. You would have to modify the JDBC URL as per Building the Connection URL the syntax is:
jdbc:sqlserver://localhost;databaseName=BoxPointHAMBURGO
and then remove the database name from the SQL query:
SELECT Tabla FROM dbo.NombresTablas
Do note that tables under dbo schema can only be accessed by the user that is the database owner.
Okay I executed the same code thats in the update query in the SQLite db browser and it worked successfully
public void StatusUpdate(ActionEvent event) {
try {
String test = null;
test = txtEditStatus.getText();
System.out.println(test);
String query = "UPDATE member SET desc = ? WHERE username = ?";
PreparedStatement preparedStmt = connection.prepareStatement(query);
preparedStmt.setString (1, test);
preparedStmt.setString(2, "Custom Hue");
// execute the java preparedstatement
preparedStmt.executeUpdate();
connection.close();
} catch (Exception e) {
}
However when running eclipse with JFx, it prints what I type in the console but doesnt update in the db, anyone know why?
For the user asking about the connection:
Connection connection;
public ProfileController() {
connection = SQLConnection.Connector();
if (connection == null)
System.exit(1);
}
I would check that your connection is actually connected to the correct database.
are you sure you have the right connection string set up?
you should do an output on your exception handler, what if there is an exception?
are you sure the connection is open?
are you sure the user exists in the database and table you are trying to update?
try doing a read first, to see if you have an open connection. Print your exception, just in case, never leave it blank. That's just bad practice.
How about you try a
preparedStmt.executeUpdate();
connection.commit();
connection.close();
Just incase autocommit isn't enabled?
How can get the name of the database name from connection object
try {
this.ds = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/amger");
} catch (NamingException ne) {
}
Connection conObj = ds.getConnection();
How do I get that Database name from con
Probably the most straightforward way to get the database name from the JDBC Connection object itself is via the getCatalog() method:
Connection#getCatalog()
However, as Konstantin pointed out in his comment below, that value will not change if the current MySQL database is changed by issuing a USE dbname statement.
getCatalog() might still be useful in an application that
does not change databases, or
does things "The JDBC Way" by using setCatalog() to change the current database,
but for MySQL, using SELECT DATABASE() appears to be safer overall.
Note also that this potential discrepancy between getCatalog() and the actual current database depends on the behaviour of the particular JDBC driver. Out of curiosity I tried something similar with the Microsoft JDBC Driver 4.0 for SQL Server and .getCatalog() was indeed aware of the change to the current database immediately after running a USE dbname statement. That is, the code
String connectionUrl = "jdbc:sqlserver://localhost:52865;"
+ "databaseName=myDb;" + "integratedSecurity=true";
try (Connection con = DriverManager.getConnection(connectionUrl)) {
System.out.println(String.format(
"getCatalog() returns: %s",
con.getCatalog()));
try (Statement s = con.createStatement()) {
System.out.println(" Executing: USE master");
s.execute("USE master");
}
System.out.println(String.format(
"getCatalog() returns: %s",
con.getCatalog()));
} catch (Exception e) {
e.printStackTrace(System.out);
}
produced the following results:
getCatalog() returns: myDb
Executing: USE master
getCatalog() returns: master
If you know that DB is Mysql you could just perform SELECT DATABASE() on your connection and read the resulset with current database name in it.
Here is description of DATABASE function.
Let's assume you used url as "jdbc:mysql://localhost/test"
Then do the following:
DatabaseMetaData dmd = connection.getMetaData();
String url = dmd.getURL();
System.out.println(url.substring(url.lastIndexOf("/") + 1));
Run
System.out.println(connection.getMetaData().getURL());
Paste the output in notepad
search the value for 'databaseName=yourDBName'
Table 1 :questions(qid,category,question); PRIMARY KEY:qid,category
Table 2 :choices(ch_id,qid1,category1,choice); PRIMARY KEY: ch_id
Here qid, ch_id use AUTO_INCREAMENT.
Sql Query:
mysql>INSERT INTO choices(qid1,category1,choie)
->SELECT qid,category,'Some Choice'
->FROM questions
WHERE qid1=qid AND category1=category;
With this scenario how would I write this code for java with the same query.
First, you need an instance of java.sql.Connection. Depending from the context, there are various ways to obtain one, but if you are using some kind of Java EE container, like Tomcat, for example, you will want to use a javax.sql.DataSource (another way, without a Java EE server, would be using a java.sql.DriverManager, but it's less efficient). There also various ways to get a DataSource, but the most common looks like this:
String jndiName = "java:comp/env/jdbc/myDB";
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(jndiName);
This will use the database connection you have set up in your Tomcat configuration.
After that, you need a Connection:
Connection con = ds.getConnection();
And then a java.sql.Statement, the class used to execute a SQL statement:
Statement stmt = con.createStatement();
Now, you can execute your SQL code:
stmt.execute("INSERT INTO choices(qid1,category1,choie) SELECT qid,category,'Some Choice' FROM questions WHERE qid1=qid AND category1=category;");
Are we done? No, we aren't. We need to manage our transactions, by adding some specific code and Exception handling, and we need to release the various database resources we are using in order to be able to reuse them later. We do that in the finally block so we are sure it get executed. At the end, the whole thing looks like this (untested code!):
try {
String jndiName = "java:comp/env/jdbc/myDB";
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(jndiName);
Connection con = ds.getConnection();
con.setAutoCommit(false); // Transaction are managed manually
Statement stmt = con.createStatement();
stmt.execute("INSERT INTO choices(qid1,category1,choie) SELECT qid,category,'Some Choice' FROM questions WHERE qid1=qid AND category1=category;");
con.commit(); // Transaction OK
} catch (SQLException sqle) {
con.rollback(); // Transaction not OK
} finally { //Resource management
if (stmt!=null) {
stmt.close();
}
if (con != null) {
con.close();
}
}
You should take a look in the Javadoc. A good starting point:
http://docs.oracle.com/javase/6/docs/api/javax/sql/DataSource.html