Syntax error in prepared statement that runs in SQL - java

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.

Related

Parameterized PreparedStatement for QUERY_BAND in Teradata JDBC

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;";

MySQL 1064 syntax error when using statement

I am running a server that receives queries and sends them to the Database using Statements.
try{
connection = dbConnection.getDbConnection();
if(connection != null) {
System.out.println("DA2");
Statement mySt = connection.createStatement();
if(mySt != null) {
ResultSet myRs = mySt.executeQuery(query);
System.out.println("DA3");
while(myRs.next()){
//getting data and printing it
}
}
}
It prints DA2 so the connection is created succefully.
The query is send by the client in the following way
DataOutputStream out = new DataOutputStream(client.getOutputStream());
String query = "USE db_name; SELECT * FROM `tb_name`;";
out.writeUTF(query);
I changed the database name with db_name and the table name with tb_name(I am sure I wrote them correctly in my code).
The server receives them this way
Socket client = socket.accept();
DataInputStream input = new DataInputStream(client.getInputStream());
String query = input.readUTF();
When the server is running and the client sends the query an exception is thrown with the following message(I handled the exceptions to show me this).
SQLState: 42000
Error Code: 1064
Message: 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 'SELECT * FROM `tb_name`' at line 1
The same query runs correctly on a MySQL database.
How can I solve this? Is the database sending back the error and so throwing an exception or is it just the code?
SOLVED: I forgot to specify the database name in the connection.
You could use (single SQL statement with qualified name):
String query = "SELECT * FROM db_name.`tb_name`";
public static Connection dbConnect() {
Connection c = null;
try {
Class.forName("com.mysql.jdbc.Driver");
c = DriverManager.getConnection("jdbc:mysql://localhost:3306/DBNAME", "USERNAME", "PASSWORD");
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException " + e);
} catch (SQLException e) {
System.out.println("SQLException " + e);
}
return c;
}
Hope you have created dbConnect in similar fashion.
Here We heve included the database name in get connection method
So explicitly no need to use database name for each time until you are accessing another database.
so your query should be
String query = "SELECT * FROM `tb_name`";

multiple sql command

I'm trying to execute multiple sql commands, but it gives me "error in your SQL syntax;"
Db_Connection dbconn = new Db_Connection();
Connection myconnection = dbconn.Connection();
String sqlString = "SELECT DISTINCT std_id FROM std_crs WHERE crs_id ='222123'; "
+ "SELECT * FROM cplus_grades ;";
Statement myStatement = myconnection.createStatement();
boolean results = myStatement.execute(sqlString);
do {
if (results) {
ResultSet rs = myStatement.getResultSet();
while (rs.next()) {
}
rs.close();
}
results = myStatement.getMoreResults();
} while(results);
myStatement.close();
I did a small test with three JDBC drivers:
MS SQL: works, returns two result sets
MySQL: fails with a syntax error - that is what you are seeing
HSQLDB: runs, but returns only one result set.
So I guess it simply depends on the JDBC driver if this technique works. Maybe it works only in MS SQL JDBC.
UPDATE:
It also works with Postgres.
please
1. String dbUrl = "jdbc:mysql://yourDatabase?allowMultiQueries=true";
this should be your jdbc connection url

Get the connected mysql database name (JDBC)

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'

How to write query in java to insert data with foreign keys using MySql

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

Categories

Resources