Why does Bluemix dashDB operation throws a SqlSyntaxErrorException with SQLCODE=-1667? - java

I'm getting this error even though I am not trying to edit the table/column:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: The operation failed because the operation is not supported with the type of the specified table. Specified table: "DASH103985.wajihs". Table type: "ORGANIZE BY COLUMN". Operation: "WITH RS".. SQLCODE=-1667, SQLSTATE=42858
#MultipartConfig
public class DemoServlet extends HttpServlet {
private static Logger logger = Logger.getLogger(DemoServlet.class.getName());
private static final long serialVersionUID = 1L;
#Resource(lookup="jdbc/db2")DataSource dataSource;
private String getDefaultText() {
TweetsCombined = new String(" ");
try {
// Connect to the Database
Connection con = null;
try {
System.out.println("Connecting to the database");
} catch (SQLException e) {
TweetsCombined = "first" +e;
}
// Try out some dynamic SQL Statements
Statement stmt = null;
try {
stmt = con.createStatement();
String tableName = "wajihs";// change table name here to one
// chosen in the first website
String columnName = "msgBody";// msgBody is where the tweets
// are stored
String query = "SELECT * FROM \"" + tableName + "\"";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
content = rs.getString(columnName) + ". ";
if (content.toLowerCase().contains("RT".toLowerCase())
|| content.toLowerCase().contains("Repost: ".toLowerCase())) {
// do nothing
}
else {
TweetsCombined.concat(content);
}
}
// Close everything off
// Close the Statement
stmt.close();
// close
con.commit();
// Close the connection
con.close();
} catch (Exception e) {
TweetsCombined = "second" +e;
System.out.println(e.getMessage());
}
} catch (Exception e) {
TweetsCombined = "third" + e;
System.out.println(e);
}
return TweetsCombined;
}

As I explained here, dashDB, with its BLU Acceleration features, has certain limitations compared to DB2 without BLU Acceleration. In your case it is that you can only run queries with the CS isolation level against column-organized tables.
Either change your connection configuration to use CS isolation level or create your table(s) while explicitly specifying ORGANIZE BY ROW.

Related

Null result statement from other class

The result set that I'm trying to retrieve from another class returns null, even though the query works.I'm trying to initialize my object based on the records kept in databases,which means if there is initially a record in sqlite,I retrieve the one with latest date.Else,I try to retrieve the earliest one from mysql database. The code that is supposed to retrieve result set from mysql database is like this:
public ResultSet lowestDate() throws SQLException {
ResultSet rs1 = null;
String resultQuery = "SELECT * FROM alarm ORDER BY `timestamp` ASC LIMIT 1";
rs1 = stmt.executeQuery(resultQuery);
return rs1;
}
Statement is initialized globally.And I call this in another class like this:
public void setLastAlarm() throws SQLException, ParseException {
String liteQuery = "SELECT * FROM alarm_entries ORDER BY date(`timestamp`) DESC LIMIT 1";
conn.connectLite();
Connection getCon = conn.getLiteConnection();
try {
stmt = getCon.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
try {
rs = stmt.executeQuery(liteQuery);
if (rs.next()) {
//while (rs.next()) {
nuDate = rs.getString("timestamp");
newDate = format.parse(nuDate);
lastAlarm.setBacklogId(rs.getBytes("backlog_id"));
lastAlarm.setTimestamp(newDate);
//}
}
else{
rsq=mysqlConnection.lowestDate();
lastAlarm.setTimestamp(format.parse(rsq.getString("timestamp")));
lastAlarm.setBacklogId(rsq.getBytes("backlog_id"));
}
}catch (Exception e){
e.printStackTrace();
}
}
public void run() {
try {
setLastAlarm();
You never call ResultSet#next() on the result set being returned from the lowestDate() helper method. Hence, the cursor is never being advanced to the first (and only) record in the result set. But I think it is a bad idea to factor your JDBC code in this way. Instead, just inline your two queries like this:
try {
rs = stmt.executeQuery(liteQuery);
if (rs.next()) {
nuDate = rs.getString("timestamp");
newDate = format.parse(nuDate);
lastAlarm.setBacklogId(rs.getBytes("backlog_id"));
lastAlarm.setTimestamp(newDate);
}
else {
String resultQuery = "SELECT * FROM alarm ORDER BY timestamp LIMIT 1";
rs = stmt.executeQuery(resultQuery);
if (rs.next()) {
String ts = rs.getString("timestamp");
lastAlarm.setTimestamp(format.parse(ts));
lastAlarm.setBacklogId(rs.getBytes("backlog_id"));
}
}
} catch (Exception e){
e.printStackTrace();
}

SQLException: ResultSet closed

I'm trying to execute method which should create a new object with fields from database, and everytime i run this code im getting SQLException: ResultSet closed.
public DatabasedClient getDatabaseClient(int clientDatabaseid){
if(DatabaseClientUtil.isInDatabase(clientDatabaseid)){
return DatabaseClientUtil.getDBClient(clientDatabaseid);
}else{
try{
System.out.println("Trying to find user in db");
ResultSet rs = fbot.getStorage().query("select * from database_name where clientDBId = " + clientDatabaseid);
System.out.println("deb " + rs.getString("nick"));
while (rs.next()) {
DatabasedClient databasedClient = new DatabasedClient(clientDatabaseid);
databasedClient.setUid(rs.getString("uid"));
databasedClient.setNick(rs.getString("nick"));
databasedClient.setLastConnect(rs.getLong("lastConnected"));
databasedClient.setLastDisconnect(rs.getLong("lastDisconnect"));
databasedClient.setTimeSpent(rs.getLong("timeSpent"));
databasedClient.setLongestConnection(rs.getLong("longestConnection"));
return databasedClient;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
}
Im using hikari, here are methods from AbstractStorage class
#Override
public void execute(String query) throws SQLException {
try (Connection connection = getConnection()){
connection.prepareStatement(query).executeUpdate();
}
}
#Override
public ResultSet query(String query) throws SQLException {
try (Connection connection = getConnection()) {
return connection.prepareStatement(query).executeQuery();
}
}
Screenshot from error
I hope someone will help me with this.
I think the exact error you are seeing is being caused by the following line of code:
System.out.println("deb " + rs.getString("nick"));
You are trying to access the result set before you advance the cursor to the first record. Also, your method getDatabaseClient is returning a single object which conceptually maps to a single expected record from the query. Hence, iterating once over the result set would seem to make sense. Taking all this into consideration, we can try the following:
try {
System.out.println("Trying to find user in db");
ResultSet rs = fbot.getStorage().query("select * from database_name where clientDBId = " + clientDatabaseid);
// do not access the result set here
if (rs.next()) {
DatabasedClient databasedClient = new DatabasedClient(clientDatabaseid);
databasedClient.setUid(rs.getString("uid"));
databasedClient.setNick(rs.getString("nick"));
databasedClient.setLastConnect(rs.getLong("lastConnected"));
databasedClient.setLastDisconnect(rs.getLong("lastDisconnect"));
databasedClient.setTimeSpent(rs.getLong("timeSpent"));
databasedClient.setLongestConnection(rs.getLong("longestConnection"));
return databasedClient;
}
} catch (SQLException e) {
e.printStackTrace();
}

How do I call data from a table in a database into a java class in netbeans?

first time posting so sorry if my question is slightly strange.
So I have a project in school that requires us to create java classes using netbeans that open up a window with three options, check stock, purchase item and update stock.
We had a class called stockdata that held the details of 5 different items for us to use in our three classes to check, purchase and update items. The latest stage of our coursework requires us to create a derby database and enter the items into a table.
I have done this with no issues but I am having a problem getting the items from the table back into my classes to use. We were given the following code but I can't get it to work, even using the commented hints.
package stock;
// Skeleton version of StockData.java that links to a database.
// NOTE: You should not have to make any changes to the other
// Java GUI classes for this to work, if you complete it correctly.
// Indeed these classes shouldn't even need to be recompiled
import java.sql.*; // DB handling package
import java.io.*;
import org.apache.derby.drda.NetworkServerControl;
public class StockData {
private static Connection connection;
private static Statement stmt;
static {
// standard code to open a connection and statement to an Access database
try {
NetworkServerControl server = new NetworkServerControl();
server.start(null);
// Load JDBC driver
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
//Establish a connection
String sourceURL = "jdbc:derby://localhost:1527/"
+ new File("UserDB").getAbsolutePath() + ";";
connection = DriverManager.getConnection(sourceURL, "use", "use");
stmt = connection.createStatement();
} // The following exceptions must be caught
catch (ClassNotFoundException cnfe) {
System.out.println(cnfe);
} catch (SQLException sqle) {
System.out.println(sqle);
} catch (Exception e) {
System.out.println(e);
}
}
// You could make methods getName, getPrice and getQuantity simpler by using an auxiliary
// private String method getField(String key, int fieldNo) to return the appropriate field as a String
public static String getName(String key) {
try {
// Need single quote marks ' around the key field in SQL. This is easy to get wrong!
// For instance if key was "11" the SELECT statement would be:
// SELECT * FROM Stock WHERE stockKey = '11'
ResultSet res = stmt.executeQuery("SELECT * FROM Stock WHERE stockKey = '" + key + "'");
if (res.next()) { // there is a result
// the name field is the second one in the ResultSet
// Note that with ResultSet we count the fields starting from 1
return res.getString(2);
} else {
return null;
}
} catch (SQLException e) {
System.out.println(e);
return null;
}
}
public static double getPrice(String key) {
// Similar to getName. If no result, return -1.0
return 0;
}
public static int getQuantity(String key) {
// Similar to getName. If no result, return -1
return 0;
}
// update stock levels
// extra is +ve if adding stock
// extra is -ve if selling stock
public static void update(String key, int extra) {
// SQL UPDATE statement required. For instance if extra is 5 and stockKey is "11" then updateStr is
// UPDATE Stock SET stockQuantity = stockQuantity + 5 WHERE stockKey = '11'
String updateStr = "UPDATE Stock SET stockQuantity = stockQuantity + " + extra + " WHERE stockKey = '" + key + "'";
System.out.println(updateStr);
try {
stmt.executeUpdate(updateStr);
} catch (SQLException e) {
System.out.println(e);
}
}
// close the database
public static void close() {
try {
connection.close();
} catch (SQLException e) {
// this shouldn't happen
System.out.println(e);
}
}
}
Sorry if this seems a stupid question but I am fairly new to Java and was making good progress until this roadblock.
Thanks in advance!
Alex
Searching for "java sql" on Google delivers this link: https://docs.oracle.com/javase/tutorial/jdbc/basics/processingsqlstatements.html
From a connection you can create a statement (you can find this in the link and in your code) , then fetch a result set and loop over that with rs.next(). That should get your started.
Of course you have to make sure that the driver and database are there/running, just saying...
Here netbeans has nothing to do with database. This is a Java-based integrated development environment(IDE) that will help you to reduce syntactic error.
public void dataAccess(){
try {
String connectionUrl = "suitable connection url as per your database";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
Class.forName("JDBC driver name as per your database");
con = DriverManager.getConnection(connectionUrl, userName, password);
String SQL = "SQL query as per your criteria";
stmt = con.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
// look into ResultSet api and use method as per your requirement
}
rs.close();
}
catch (Exception e) {
//log error message ;
}
}

Querying a database via a constructor

I'm really hopping some help from anyone who would be kind enough to help me resolve this. I've been at it since yesterday.
See, what I'm trying to do is create a database query class that I can re-use over and over again as many times as possible without having to write a query every other time I need to search or display items from the database.
I'd like to be able to pass the query specifications via a constructor.
I however, get this error:
run:
Connecting to a selected database...
Connected database successfully...
Creating statement...
org.h2.jdbc.JdbcSQLException: Data conversion error converting ; SQL statement:
This is my code so far:
import java.sql.*;
public class RsToAList {
private final String table;
private final String columns;
private final String whereColumn;
private final String equalsEntry;
public RsToAList (String columns, String table, String whereColumn, String equalsEntry) {
this.table = table;
this.columns = columns;
this.whereColumn = whereColumn;
this.equalsEntry = equalsEntry;
}
// JDBC driver name and database URL
static String JDBC_DRIVER = "org.h2.Driver";
static String DB_URL = "jdbc:h2:file:C:/tryDb/tryDb";
// Database credentials
static String USER = "sa";
static String PASS = "";
public static void main (String[] args) {
RsToAList tryAndGet = new RsToAList("fullNames", "CLIENT", "postOfficeBoxNumber", "6448");
tryAndGet.ourQueryMethod();
}
public void ourQueryMethod () {
Connection conn = null;
Statement stmt = null;
try {
// STEP 2: Register JDBC driver
Class.forName(getJDBC_DRIVER());
// STEP 3: Open a connection
System.out.println("Connecting to a selected database...");
conn = DriverManager.getConnection(getDB_URL(), getUSER(), getPASS());
System.out.println("Connected database successfully...");
// STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql = "SELECT " + (columns) + " FROM " + (table) + " WHERE "+ (whereColumn) +" = "+ (equalsEntry) +"";
ResultSet rs = stmt.executeQuery(sql);
//STEP 5: Extract data from result set
while (rs.next()) {
// Retrieve by column name
String first = rs.getString(columns);
// Display values
System.out.print("ID: " + first);
}
rs.close();
} catch (SQLException se) {
// Handle errors for JDBC
se.printStackTrace();
} catch (Exception e) {
// Handle errors for Class.forName
e.printStackTrace();
} finally {
// finally block used to close resources
try {
if (stmt != null)
conn.close();
} catch (SQLException se) {
} // do nothing
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
se.printStackTrace();
} // end finally try
} // end try
System.out.println("Goodbye!");
} // end main
/**
* #return the JDBC_DRIVER
*/
public static String getJDBC_DRIVER() {
return JDBC_DRIVER;
}
/**
* #param aJDBC_DRIVER the JDBC_DRIVER to set
*/
public static void setJDBC_DRIVER(String aJDBC_DRIVER) {
JDBC_DRIVER = aJDBC_DRIVER;
}
/**
* #return the DB_URL
*/
public static String getDB_URL() {
return DB_URL;
}
/**
* #param aDB_URL the DB_URL to set
*/
public static void setDB_URL(String aDB_URL) {
DB_URL = aDB_URL;
}
/**
* #return the USER
*/
public static String getUSER() {
return USER;
}
/**
* #param aUSER the USER to set
*/
public static void setUSER(String aUSER) {
USER = aUSER;
}
/**
* #return the PASS
*/
public static String getPASS() {
return PASS;
}
/**
* #param aPASS the PASS to set
*/
public static void setPASS(String aPASS) {
PASS = aPASS;
}
}
I'm a JAVA/ Programming newbie, and I'm trying to teach myself how to code from home in case my question seems too simple, or I seem to have overlooked something in my code.
Edit:
I'm not sure if this could help you help me, but this is the class that creates the database table:
//STEP 1. Import required packages
import java.sql.*;
public class JDBCExampleCreateTables {
// JDBC driver name and database URL
private static String JDBC_DRIVER = "org.h2.Driver";
private static String DB_URL = "jdbc:h2:file:C:/tryDb/tryDb";
// Database credentials
private static String USER = "sa";
private static String PASS = "";
public static void main (String[] args) {
Connection conn = null;
Statement stmt = null;
try {
//STEP 2: Register JDBC driver
Class.forName(JDBC_DRIVER);
//STEP 3: Open a connection
System.out.println("Connecting to a selected database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
System.out.println("Connected database successfully...");
//STEP 4: Execute a query
System.out.println("Creating table in given database...");
stmt = conn.createStatement();
String sql = "CREATE TABLE CLIENT " +
"(ID INT UNSIGNED NOT NULL AUTO_INCREMENT, " +
" fullNames VARCHAR(255), " +
" iDNumber VARCHAR(255), " +
" pINNumber VARCHAR(255), " +
" passportNumber VARCHAR(255), " +
" postOfficeBoxNumber VARCHAR(255), " +
" postalCode VARCHAR(255), " +
" telephoneNumberLandline VARCHAR(255), " +
" telephoneNumberMobile VARCHAR(255)) ";
stmt.executeUpdate(sql);
System.out.println("Created table in given database...");
} catch (SQLException se) {
//Handle errors for JDBC
se.printStackTrace();
} catch (Exception e) {
// Handle errors for Class.forName
e.printStackTrace();
} finally {
// finally block used to close resources
try {
if (stmt!=null)
conn.close();
} catch(SQLException se) {
} // do nothing
try {
if (conn!=null)
conn.close();
} catch (SQLException se) {
se.printStackTrace();
} // end finally try
} // end try
System.out.println("Goodbye!");
} // end main
} // end
Looks like a error in your sql statement.Make sure the data type you are comparing is compatible.PreparedStatement is handy instead of concatenating queries.
PreparedStatement stm = conn.prepareStatement("select * from person where name=?");
stm.setString(1,"ABC");
ResultSet rs= stm.executeQuery();
Although you have not shared the column type for the where condition. But most proabably you may be passing a string value to where clause but not enclosing it in single quotes:
String sql = "SELECT " + (columns) + " FROM " + (table) + " WHERE "+ (whereColumn) +" = "+ (equalsEntry) +"";
change it to:
String sql = "SELECT " + (columns) + " FROM " + (table) + " WHERE "+ (whereColumn) +" ='"+ (equalsEntry) +"'";
The other potential candidate for defect is this statementn:
String first = rs.getString(columns);
It may throw an error if any of your column type is not VARCHAR

How to retrieve sequences metadata from JDBC?

I am trying to retrieve different kind of metadata of my Oracle DB from Java code (using basic JDBC). For example, if I want to retrieve the list of tables with _FOO suffix, I can do something like:
Connection connection = dataSource.getConnection();
DatabaseMetaData meta = connection.getMetaData();
ResultSet tables = meta.getTables(connection.getCatalog(), null, "%_FOO", new String[] { "TABLE" });
// Iterate on the ResultSet to get information on tables...
Now, I want to retrieve all the sequences from my database (for example all sequence named S_xxx_FOO).
How would I do that, as I don't see anything in DatabaseMetaData related to sequences?
Do I have to run a query like select * from user_sequences ?
Had the same question. It's fairly easy. Just pass in "SEQUENCE" into the getMetaData().getTables() types param.
In your specific case it would be something like:
meta.getTables(connection.getCatalog(), null, "%_FOO", new String[] { "SEQUENCE" });
You can't do this through the JDBC API, because some databases (still) do not support sequences.
The only way to get them is to query the system catalog of your DBMS (I guess it's Oracle in your case as you mention user_sequences)
You can use the hibernate dialect api for retrieving sequence Name. see : http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/dialect/Dialect.html
From below example, you can see how to use dialect to get sequence names
public static void main(String[] args) {
Connection jdbcConnection = null;
try {
jdbcConnection = DriverManager.getConnection("", "", "");
printAllSequenceName(jdbcConnection);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if(jdbcConnection != null) {
try {
jdbcConnection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void printAllSequenceName(Connection conn) throws JDBCConnectionException, SQLException {
DialectResolver dialectResolver = new StandardDialectResolver();
Dialect dialect = dialectResolver.resolveDialect(conn.getMetaData());
if ( dialect.supportsSequences() ) {
String sql = dialect.getQuerySequencesString();
if (sql!=null) {
Statement statement = null;
ResultSet rs = null;
try {
statement = conn.createStatement();
rs = statement.executeQuery(sql);
while ( rs.next() ) {
System.out.println("Sequence Name : " + rs.getString(1));
}
}
finally {
if (rs!=null) rs.close();
if (statement!=null) statement.close();
}
}
}
}
If you don't desire to use hibernate, then you have to crate custom sequential specific implementation.
Sample code for custom implementation
interface SequenceQueryGenerator {
String getSelectSequenceNextValString(String sequenceName);
String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize);
String getDropSequenceStrings(String sequenceName);
String getQuerySequencesString();
}
class OracleSequenceQueryGenerator implements SequenceQueryGenerator {
#Override
public String getSelectSequenceNextValString(String sequenceName) {
return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
}
#Override
public String getCreateSequenceString(String sequenceName,
int initialValue, int incrementSize) {
return "create sequence " + sequenceName + " start with " + initialValue + " increment by " + incrementSize;
}
#Override
public String getDropSequenceStrings(String sequenceName) {
return "drop sequence " + sequenceName;
}
#Override
public String getQuerySequencesString() {
return "select sequence_name from user_sequences";
}
}
class PostgresSequenceQueryGenerator implements SequenceQueryGenerator {
#Override
public String getSelectSequenceNextValString(String sequenceName) {
return "select " + getSelectSequenceNextValString( sequenceName );
}
#Override
public String getCreateSequenceString(String sequenceName,
int initialValue, int incrementSize) {
return "create sequence " + sequenceName + " start " + initialValue + " increment " + incrementSize;
}
#Override
public String getDropSequenceStrings(String sequenceName) {
return "drop sequence " + sequenceName;
}
#Override
public String getQuerySequencesString() {
return "select relname from pg_class where relkind='S'";
}
}
public void printSequenceName (SequenceQueryGenerator queryGenerator, Connection conn) throws SQLException {
String sql = queryGenerator.getQuerySequencesString();
if (sql!=null) {
Statement statement = null;
ResultSet rs = null;
try {
statement = conn.createStatement();
rs = statement.executeQuery(sql);
while ( rs.next() ) {
System.out.println("Sequence Name : " + rs.getString(1));
}
}
finally {
if (rs!=null) rs.close();
if (statement!=null) statement.close();
}
}
}
public static void main(String[] args) {
Connection jdbcConnection = null;
try {
jdbcConnection = DriverManager.getConnection("", "", "");
printAllSequenceName(new OracleSequenceQueryGenerator(), jdbcConnection);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(jdbcConnection != null) {
try {
jdbcConnection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Given that recent versions of the Oracle JDBC drivers (e.g. 12.1.0.2) don't return sequence information when you call DatabaseMetaData#getTables with types set to ["SEQUENCE"], your best bet is to run the necessary query yourself, e.g.:
SELECT o.owner AS sequence_owner,
o.object_name AS sequence_name
FROM all_objects o
WHERE o.owner LIKE 'someOwnerPattern' ESCAPE '/'
AND o.object_name LIKE 'someNamePattern' ESCAPE '/'
AND o.object_type = 'SEQUENCE'
ORDER BY 1, 2
... where someOwnerPattern and someNamePattern are SQL patterns like the ones you'd use with the LIKE operator (e.g. % matches anything).
This is basically the same as the query run by the driver itself, except that it queries for objects of type SEQUENCE.

Categories