Convert PostgreSQL Serial Primary Key to Oracle Statement - java

I have a java file that connects to a database and this is the code:
package movies;
import java.sql.*;
public class CreateTable {
public static void main(String args[]) {
Connection c = null;
Statement stmt = null;
String sql;
try {
Class.forName("oracle.jdbc.OracleDriver");//driver
c = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521/XE", "username", "password");//PUT DATABASE CONNECTION INFO
System.out.println("Opened database successfully from within CreateTable.java");
stmt = c.createStatement();
sql = "CREATE TABLE MOVIES "
//+ "(ID SERIAL PRIMARY KEY,"//can't figure out this statement and it works if I comment it out.
+ " (NAME NVARCHAR2(255) PRIMARY KEY,"//I don't want this to be the primary key.
+ " YEAR NVARCHAR2(255),"
+ " RATING NVARCHAR2(16),"
+ " ACTORS NVARCHAR2(1024))";
stmt.executeUpdate(sql);
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
System.out.println("Table created successfully");
}
}
The commented part is where I'm running into problems. I'm trying to convert a PostgreSQL statement to an Oracle 11g XE statement. I would like to have an ID with a sequential number to identify it. (ie. 0001, 0002, 0003, etc.) How can I do this? Could you provide an example? I'm at a loss right now. I'm using Netbeans 8.02, Oracle 11g XE, and Apache Tomcat 8.0.15.0.
edit I'm trying to have the ID column as the only primary key. I would eliminate the NAME column as a primary key and make the ID column the new primary key.

I don't think you can have two separate columns with primary key like that, if you want a primary key on two columns use,
edit :
sql = "CREATE TABLE MOVIES "
+ "(ID INT PRIMARY KEY," -- CHANGES
+ " NAME NVARCHAR2(255),"
+ " YEAR NVARCHAR2(255),"
+ " RATING NVARCHAR2(16),"
+ " ACTORS NVARCHAR2(1024))";
i have created the table to show the syntax works in oracle now..
SQL> create table movies
2 (id int primary key,
3 name NVARCHAR2(255),
4 year NVARCHAR2(255),
5 rating NVARCHAR2(255),
6 actors NVARCHAR2(1024));
Table created.

This code worked. See the comments below to view the changes:
try {
Class.forName("oracle.jdbc.OracleDriver");//driver
c = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521/XE", "username", "password");//PUT DATABASE CONNECTION INFO
System.out.println("Opened database successfully from within CreateTable.java");
stmt = c.createStatement();
sql = "CREATE TABLE MOVIES "
//THE FOLLOWING LINE WAS CHANGED:
+ "(\"ID\" INTEGER PRIMARY KEY, \"TYPE\" VARCHAR2(32),"
+ " NAME NVARCHAR2(255),"
+ " YEAR NVARCHAR2(255),"
+ " RATING NVARCHAR2(16),"
+ " ACTORS NVARCHAR2(1024))";
//THE FOLLOW TWO STATEMENTS WERE ADDED:
String sql1 = "CREATE SEQUENCE MOVIES_SEQ START WITH 1 INCREMENT BY 1 NOMAXVALUE";
String sql2 = "CREATE TRIGGER MOVIES_TRIGGER BEFORE INSERT ON MOVIES FOR EACH ROW BEGIN SELECT MOVIES_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL; END;";
stmt.executeUpdate(sql);
//THESE TWO WERE ALSO ADDED:
stmt.executeUpdate(sql1);
stmt.executeUpdate(sql2);
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}

Related

How do I show the table names that exist in a Java SQLite3 database? [duplicate]

This question already has answers here:
How can I list the tables in a SQLite database file that was opened with ATTACH?
(17 answers)
Closed 4 years ago.
In the spirit of test-driven design I want to test whether the tables get properly created in my SQLite3 database. For that purpose I want to list the table names via an SQL query.
I created the tables with:
public static void setupTables(){
try(Statement stmt = con.createStatement()) {
String sql_student = ("CREATE TABLE IF NOT EXISTS " + STUDENT_TABLE + "(\n "
+ ID + " integer PRIMARY KEY,\n "
+ FIRSTNAME + " text,\n "
+ LASTNAME + " text\n"
+ ");");
String sql_teacher = ("CREATE TABLE IF NOT EXISTS " + TEACHER_TABLE + "(\n "
+ ID + " integer PRIMARY KEY,\n "
+ FIRSTNAME + " text,\n "
+ LASTNAME + " text\n"
+ ");");
stmt.execute(sql_student);
stmt.execute(sql_teacher);
stmt.close();
}catch(Exception e){
e.printStackTrace();
}
}
What's the query I need for my test? Do I need to be concerned about order, or does the order in which the tables get created gurantee that they will always stored in the same order?
1) ATTACH mydb.db as my_db
2) SELECT name FROM my_db.sqlite_master where type='table';
3) For temporary tables: SELECT name FROM sqlite_temp_master WHERE type='table';
Hope it will help!

Unnecessary Foreign Key Constraint Failure

So I have a mock database for a conference where I'm creating tables for the authors, papers, reviewers, etc.
The reviewers provide an email which refers to the Program Committee emails. This is the key constraint I put in place. Then I add data to the PC table and then attempt to add data to the reviewer table. This is the error I get:
Exception encountered com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`sampledb`.`review`, CONSTRAINT `review_ibfk_2` FOREIGN KEY (`email`) REFERENCES `pcmember` (`email`))
Here are the other functions:
public int loadPCMember(){
String tablename = "pcmember";
String create = "CREATE TABLE IF NOT EXISTS pcmember(email VARCHAR(100), name VARCHAR(50), PRIMARY KEY (email));";
makeTable(create);
System.out.println("made table pcmember");
//CSV Reader
String[][] content = CSVReader(tablename,2);
for(int i = 0 ; i < content.length; i++){
try{
String query = "INSERT INTO pcmember(email,name) VALUES (?,?)";
PreparedStatement ps2 = net.prepareStatement(query);
ps2.setString(1, content[i][0]);
ps2.setString(2, content[i][1]);
ps2.executeUpdate();
System.out.println((i+1)+ " done");
// Throw exception
}catch (SQLException e){System.out.println("Exception encountered");return 0;}
}
System.out.println("PC Member Done");
return 1;
}
//Load next
public int loadReview(){
String tablename = "review";
String create = "CREATE TABLE IF NOT EXISTS review(reportid INTEGER, sdate DATE, comment VARCHAR(250), recommendation VARCHAR(6), paperid INTEGER NOT NULL, email VARCHAR(100) NOT NULL, PRIMARY KEY(reportid), FOREIGN KEY (paperid) REFERENCES paper(paperid), FOREIGN KEY(email) REFERENCES pcmember(email));";
makeTable(create);
System.out.println("made table review");
//CSV Reader
String[][] content = CSVReader(tablename,6);
for(int i = 0 ; i < content.length; i++){
System.out.println("" + content[i][0] + "\t" +content[i][1] + "\t" + content[i][2] + "\t" +content[i][3] + "\t" +content[i][4] + "\t" +content[i][5]);
try{
//SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
//java.util.Date date = sdf.parse(content[i][1]);
//System.out.println(""+date);
//Date newDate = new Date(date.getTime());
//System.out.println(""+newDate);
String query = "INSERT INTO review(reportid,sdate,comment,recommendation,paperid,email) VALUES (?,?,?,?,?,?)";
PreparedStatement ps2 = net.prepareStatement(query);
ps2.setInt(1, Integer.parseInt(content[i][0]));
ps2.setDate(2, java.sql.Date.valueOf(content[i][1]));
ps2.setString(3, content[i][2]);
ps2.setString(4, content[i][3]);
ps2.setInt(5, Integer.parseInt(content[i][4]));
ps2.setString(6, content[i][5]);
ps2.executeUpdate();
System.out.println((i+1)+ " done");
// Throw exception
}catch (SQLException e){System.out.println("Exception encountered "+ e);return 0;
}//catch (ParseException e){System.out.println("Parse Exception encountered "+e);}
}
System.out.println("Review Done");
return 1;
}
I have a decent understanding of the key constraints and I'm pretty spot on with the CSV files having the same exact emails, so what could be causing this error?
I'm a SQL guy, not a Java guy. If I ask or suggest anything that doesn't make sense because of that - you know why. To be clear - based on that error message and the sql you have included it looks like you trying to insert a record into the review table that has an email address that doesn't exist in the pcmember table thus violating the foreign key constraint on the review table. This seems like a data problem with the CVSs you are using. However since you mentioned that you are confident in the data files is it possible that the it's trying to INSERT the rows into the review table before the pcmember INSERT has successfully completed?

Does the prepared-statement work this way?

I am trying to populate one table in my database with pretty complex data. For this, I am using a generator API (which gives me random data).
public void populateCrackers(){
PreparedStatement psm;
String queryJoke = "(SELECT jid FROM Jokes WHERE jid=?)";
String queryHat = "(SELECT hid FROM Hats WHERE hid=?)";
String queryGift = "(SELECT gid FROM Gifts WHERE gid=?)";
String query = "INSERT INTO Crackers(cid, name, jid, hid, gid, quantity) VALUES(" +
"?, " +
"?, " +
queryJoke + ", " +
queryHat + ", " +
queryGift + ", " +
"?)";
System.out.println(query);
String cracker_String = utils.JSONUtils.getJSON(crackerAPI, client);
JSONObject crackerJSON = new JSONObject(cracker_String);
JSONArray crackers = crackerJSON.getJSONArray("results");
for(int j=0; j<crackers.length(); j++){
try{
psm = connection.prepareStatement(query);
psm.setInt(1,crackers.getJSONObject(j).getInt("cid"));
psm.setString(2, crackers.getJSONObject(j).getString("cname"));
psm.setInt(3, crackers.getJSONObject(j).getInt("rjoke"));
psm.setInt(4, crackers.getJSONObject(j).getInt("rhat"));
psm.setInt(5, crackers.getJSONObject(j).getInt("rgift"));
psm.setInt(6, crackers.getJSONObject(j).getInt("cquantity"));
psm.execute();
System.out.println(crackers.getJSONObject(j).get("cid") + " "
+ crackers.getJSONObject(j).get("cname") + " "
+ crackers.getJSONObject(j).get("cquantity") + " "
+ crackers.getJSONObject(j).get("rjoke") + " "
+ crackers.getJSONObject(j).get("rhat") + " "
+ crackers.getJSONObject(j).get("rgift"));
}catch (Exception e){
e.printStackTrace();
}
}
}
This is the method that populates my "Crackers" tab. I am wondering if this be accepted as a prepared statement. When I run it in psql interactive command line tool, exactly that statement with some chosen ids (e.g INSERT INTO Crackers (cid, name, hid, jid, gid, quantity) VALUES('cid', 'name', (SELECT hid FROM Hats WHERE hid=11), (SELECT jid FROM Jokes where jid=99), (SELECT gid FROM Gifts WHERE gid=13), 5) it works flawlessly.
Does my preparedstatement break the Constraint?
Any ideas?
LATER EDIT: The inconsistency is the form of that null values can reach my Crackers table (e.g. Cracker(1, "hello", null, null, 3, 123) appears in the table.
There is nothing about Prepared statement. Constraint can be broken by parameters you set to it. And you can run your PLSQL statement as anonimous block in PreparedStatement as well.
Just surround it with BEGIN ... END. only one thing is different - for JDBC parameters are ? mark not :parameter as for PLSQL and there is no way to use named parameter.
That means if you need to use parameter more than once for JDBC you have to have that many ? marks and set all of them.
So, focus on parameters you pass to and their sequence.
The code is correct, though the prepared statement must be closed, and it would be better to create the statement once, before the for loop.
Now there is crackers.length() times a statement created but not closed. That might give problems.
Use the try-with-resouce syntax for automatic closing, irrespective of any exception or return.
try (PreparedStatement psm = connection.prepareStatement(query)) {
for (int j = 0; j < crackers.length(); j++) {
...
psm.executeUpdate();
And call executeUpdate instead of the more general execute. The resulting update count might be of interest (1/0).
I realised I had the wrong constraints on my table. I was letting null values in. There was nothing wrong with the prepared statement.
The right query to create the table is this one:
String createCrackersQuery = "CREATE TABLE Crackers(" +
" cid INTEGER," +
" name VARCHAR NOT NULL," +
" jid INTEGER NOT NULL," +
" hid INTEGER NOT NULL," +
" gid INTEGER NOT NULL," +
" quantity INTEGER NOT NULL," +
" CONSTRAINT Cracker_Primary PRIMARY KEY (cid)," +
" CONSTRAINT Cracker_Name_Unique UNIQUE(name)," +
" CONSTRAINT Joke_Foreign FOREIGN KEY (jid) REFERENCES Jokes(jid)," +
" CONSTRAINT Hat_Foreign FOREIGN KEY (hid) REFERENCES Hats(hid), " +
" CONSTRAINT Gift_Foreign FOREIGN KEY (gid) REFERENCES Gifts(gid)" +
")";

How to Dynamically Assign Table Name in mysql Server

I am trying To Create Tables in mysql dynamically And Assign them Name Using The Email Address User Provided. But Whenever I try to Assign Table Name dynamically it shows me error and i don,t know anyother way to fulfil my requirement.
Here is The Code I Wrote
String TableName = Email.getText();
try {
String myTableName = "CREATE TABLE '" + TableName + "' "
+ "(id INTEGER not NULL, "
+ " first VARCHAR(255), "
+ " last VARCHAR(255), "
+ " age INTEGER, "
+ " PRIMARY KEY ( id ))";;
Class.forName(m.RegisterationString);
java.sql.Connection con;
con = DriverManager.getConnection(m.URL, m.UserName, m.Password);
Statement State = con.createStatement();
//This line has the issue
State.executeUpdate(myTableName);
System.out.println("Table Created");
}
In MySQL the name of table should not be between '' it can be between :
String myTableName ="CREATE TABLE `" + tableName + "`"
//--------------------------------^-----------------^
Note for good pratice don't start the name of variable with upper letter like State or TableName, Email

creating column family in cql?

when i create column family using the cql it gives me very unexpected output.
public static void createColumnfamily()
{
try
{
Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
Connection con = DriverManager.getConnection("jdbc:cassandra://192.168.1.32:9160/temp");
String qry = "CREATE TABLE users(user_name varchar," +
"password varchar," +
"gender varchar," +
"session_token varchar," +
"birth_year bigint," +
"PRIMARY KEY (user_name)" +
")";
Statement smt = con.createStatement();
smt.executeUpdate(qry);
System.out.println("TABLE(column family) is created");
con.close();
}
catch(Exception e)
{
System.out.println(" : " + e.getMessage());
}
}
Here what i got : line 1:132 extraneous input ')' expecting EOF
You're using CQL 2, which does not support that style of primary key declaration. If you want to declare it that way, you should be using CQL 3, which you can accomplish by requesting that version in the connection URL:
DriverManager.getConnection("jdbc:cassandra://192.168.1.32:9160/temp?version=3.0.0");
However, CQL 3 isn't necessary just for this. As Steve Van Opstal suggested, you can simply put the PRIMARY KEY marker with the column definition itself, since you don't have a multi-component primary key.
CREATE TABLE users(
user_name varchar PRIMARY KEY,
password varchar,
gender varchar,
session_token varchar,
birth_year bigint,
);
CQL 3 is to be generally preferred if your Cassandra supports it, as it is the way forward, but in case you don't want to switch right now, you can make that second change.
I only see two possible problems here.
The query doesn't accept your way of defining the primary key
Try this:
String qry = "CREATE TABLE users(user_name varchar PRIMARY KEY," +
"password varchar," +
"gender varchar," +
"session_token varchar," +
"birth_year bigint"
")";
The query doesn't accept varchar's as primary key
Try this:
String qry = "CREATE TABLE users(user_id int" +
"user_name varchar," +
"password varchar," +
"gender varchar," +
"session_token varchar," +
"birth_year bigint," +
"PRIMARY KEY (user_id)" +
")";

Categories