How to to create schema and tables in oracle NoSQL using its Java API - oracle-nosql

I am using oracle.nosql.client-3.2.5.jar.
I am able to create schema and tables in oracle NoSQL using the shell.
But is it possible to do this via its Java API? If yes, any pointer on that.

I am a beginner in ONS & did some research on this. Programmatically it can be done like this:
public void createTable() {
TableAPI tableAPI = store.getTableAPI();
StatementResult result = null;
String statement = null;
try {
statement =
"CREATE TABLE myTable (" +
"item STRING," +
"description STRING," +
"count INTEGER," +
"percentage DOUBLE," +
"PRIMARY KEY (item))";"
result = store.executeSync(statement);
} catch (IllegalArgumentException e) {
System.out.println("Invalid statement:\n" + e.getMessage());
} catch (FaultException e) {
System.out.println
("Statement couldn't be executed, please retry: " + e);
}
}
Souce: http://docs.oracle.com/cd/NOSQL/html/GettingStartedGuideTables/tablesapi.html#tabledefine

Related

Spring jdbc 'select for update'

I have the following method that I use with Spring JDBC
public String getState() {
String stateLink = template.queryForObject(
"select state_url from state_scrape_queue where in_use = false ORDER BY scrape_timestamp NULLS FIRST LIMIT 1",
(result, rowNum) -> {
return result.getString("state_url");
});
return stateLink;
}
I can't find an example of how to do a for update with Spring JDBC. I want in_use to be set to true using for update.
I need to use select for update since this application will be used in a multi-threaded fashion. I don't want more than one thread to get the same row and the way to prevent that is by using select for update
I was able to do this with plain JDBC, here is the question I asked how to do it with plain JDBC
select "for update" with JDBC?
Anyone know how this would be done?
This is what I came up with, feel free to recommend improvements
public String getState() throws SQLException {
String state = null;
Connection conn = DataSourceUtils.getConnection(template.getDataSource());
try {
conn.setAutoCommit(false);
String[] colNames = { "id", "state_url", "in_use" };
String query = "select " + Stream.of(colNames).collect(Collectors.joining(", "))
+ " from state_scrape_queue where in_use = false ORDER BY scrape_timestamp NULLS FIRST LIMIT 1 FOR UPDATE";
System.out.println(query);
try (Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(query)) {
while (rs.next()) {
// Get the current values, if you need them.
state = rs.getString(colNames[1]);
rs.updateBoolean(colNames[2], true);
rs.updateRow();
conn.commit();
}
}
} catch (SQLException e) {
conn.setAutoCommit(true);
e.printStackTrace();
} finally {
conn.setAutoCommit(true);
}
return state;
}

What is the best way to get the max id of table?

What is the best way to get the max id of table? Below I have paste the error and code. So I was planning on using afterLast() method to get the max id but I get an error.
ERROR:
SQLException: feature not supported
Code:
public class ex03 {
public static void main(String[] args) {
String url = "jdbc:ucanaccess://C:/Users/dave_000/My_WorkSpace/Eclipse_Workspaces/workspace-jsp/T_01_JDBC_01.accdb";
Connection con;
// Get Max ID
Statement stmt0;
String query0 = "select * from user";
try {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
} catch (java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try {
con = DriverManager.getConnection(url, "", "");
stmt0 = con.createStatement();
// Get last ID
ResultSet rs = stmt0.executeQuery(query0);
rs.afterLast();
int maxID = rs.getInt("ID");
System.out.println(maxID);
pstmt1.close();
con.close();
} catch (SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
}
}
It is much more efficient to use SQL to find the maximum value:
select max(id) from user

Sorting item from JComboBox

I'm having problem sorting my items from jcombobox, here are my codes.
public void fillCombo()
{
String dataSourceName = "CheckWriterDB";
String dbURL = "jdbc:odbc:" + dataSourceName;
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con = DriverManager.getConnection(dbURL, "", "");
st = con.createStatement();
st.execute("select Suppliers from SuppliersTable");
rs = st.getResultSet();
if(rs!=null)
{
while(rs.next())
{
temp = rs.getString(1);
listOfSuppliersCombo.addItem(temp1);
}
}
st.close();
con.close();
}
catch(Exception e)
{
System.out.println("Your error is: " + e);
}
}
Can anybody help me on how to sort the item shown in my JComboBox, data source of the items shown in my combobox is from my DATABASE. Thank you so much.
Use order by in your query to retrieve data ordered from your database
st.execute("select Suppliers from SuppliersTable order by <fields>");
Syntax: http://en.wikipedia.org/wiki/Order_by_(SQL)

jdbc get generatedKeys along with other data efficieintly

After batch insert a number of rows, I wish to retrieve the generated keys along with their corresponding inserted rows. how do I do this efficiently? Naively I can use statement.getGeneratedKeys() to query the database for each row based on each generated id, but that seems slow. the code below does a batch insert and then go through all the results in the table, however I don't want to include data that already exists in the table prior to insertion.
is there an alternative?
public static void main(String[] args) throws Exception {
Connection conn = getMySqlConnection();
ResultSet rs = null;
Statement stmt = null;
try {
conn = getMySqlConnection();
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
conn.setAutoCommit(false);
stmt.addBatch("INSERT INTO survey(id, name) VALUES('11', 'Alex')");
stmt.addBatch("INSERT INTO survey(id, name) VALUES('22', 'Mary')");
stmt.addBatch("INSERT INTO survey(id, name) VALUES('33', 'Bob')");
int[] updateCounts = stmt.executeBatch();
System.out.println(updateCounts);
conn.commit();
rs = stmt.executeQuery("SELECT * FROM survey");
while (rs.next()) {
String id = rs.getString("id");
String name = rs.getString("name");
System.out.println("id="+id +" name="+name);
}
}
catch(BatchUpdateException b) {
System.err.println("SQLException: " + b.getMessage());
System.err.println("SQLState: " + b.getSQLState());
System.err.println("Message: " + b.getMessage());
System.err.println("Vendor error code: " + b.getErrorCode());
System.err.print("Update counts: ");
int [] updateCounts = b.getUpdateCounts();
for (int i = 0; i < updateCounts.length; i++) {
System.err.print(updateCounts[i] + " ");
}
}
catch(SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
System.err.println("SQLState: " + ex.getSQLState());
System.err.println("Message: " + ex.getMessage());
System.err.println("Vendor error code: " + ex.getErrorCode());
}
catch(Exception e) {
e.printStackTrace();
System.err.println("Exception: " + e.getMessage());
}
finally {
rs.close();
stmt.close();
conn.close();
}
}
You have a list of IDs you are interested in. You can use the 'id in (...,...,)' constraint:
StringBuilder newIds = new StringBuilder();
ResultSet rs = stmt.getGeneratedKeys();
while (rs.next()) {
if (newIds.length() > 0) newIds.append(',');
newIds.append(rs.getInt(1));
}
if (newIds.length() > ) {
rs = stmt.executeQuery("SELECT * FROM survey where id in ("+newIds+")");
...
}

Exception handling - Is there a better way?

public bool AddEntity(int parentId, string description)
{
try
{
_connection.Open();
SqlCommand command = new SqlCommand("INSERT Structure (Path,Description) " +
"VALUES(" + GetPath(parentId) + ".GetDescendant(" + GetLastChildPath(parentId, 1) + ", NULL), " +
description + ")", _connection);
if (command.ExecuteNonQuery() <= 0) _success = false;
command.Connection.Close();
if (_success)
{
return true;
}
throw new Exception("An error has occured whilst trying to add a entity");
}
catch (Exception ex)
{
AddError(new ErrorModel("An error has occured whilst trying to add a entity", ErrorHelper.ErrorTypes.Critical, ex));
return false;
}
}
Is there a better way of handling the exceptions in the example above?
Thanks in advance for any help.
Clare
There's quite a few things wrong here.
a. You're using inline SQL and injecting what I can only assume to be user generated data into it. This is a security risk. Use a parameterised query.
b. You're exception handling is ok but this will leave the connection open if an error occurs. I'd write it like so:
public bool AddEntity(int parentId, string description)
{
try
{
//Assuming you have a string field called connection string
using(SqlConnection conn = new SqlConnection(_connectionString))
{
SqlParameter descriptionParam = new SqlParameter("#description", SqlDbType.VarChar, 11);
descriptionParam.Value = description;
SqlParameter parentIdParam = new SqlParameter("#parentId", SqlDbType.Int, 4);
parentIdParam.Value = parentId;
//Bit confused about the GetPath bit.
SqlCommand command = new SqlCommand("INSERT Structure (Path,Description) " +
"VALUES(" + GetPath(parentId) + ".GetDescendant(" + GetLastChildPath(parentId, 1) + ", NULL),#description)", conn);
command.Parameters.Add(descriptionParam);
if (command.ExecuteNonQuery() <= 0) _success = false;
}
if (_success)
{
return true;
}
//This isn't really an exception. You know an error has a occured handle it properly here.
throw new Exception("An error has occured whilst trying to add a entity");
}
catch (Exception ex)
{
AddError(new ErrorModel("An error has occured whilst trying to add a entity", ErrorHelper.ErrorTypes.Critical, ex));
return false;
}
You can take advantage of the IDisposable interface, and the power of a using block.
using(var connection = new Connection()) // Not sure what _connection is, in this method, so making pseudo-code
{
// ... work with connection
}
This will close the connection even if an exception is thrown. It turns into (more-or-less) this:
var connection = new Connection();
try
{
// ... work with connection
}
finally
{
connection.Dispose();
}
Dispose, in this case, will close the connection.

Resources