INSERT OR REPLACE works when there is only one row in the table and it happens to be the one that is replaced. However, when there are multiple rows in the table, INSERT OR REPLACE just inserts and creates a duplicate!
For example, if I create an entry with eventId = '123'. And then try to write another entry with eventId = '123' and roomnumber equal to something different than the first entry, INSERT OR REPLACE will work. However, if there are more than one rows in the table it will create a duplicate. Here is my code:
String createSql = "CREATE TABLE IF NOT EXISTS events (\n"
+ " eventId VARCHAR(20) PRIMARY KEY ON CONFLICT REPLACE,\n"
+ " roomNumber VARCHAR(20) NOT NULL,\n"
+ " startTime TIMESTAMP NOT NULL,\n"
+ " endTime TIMESTAMP NOT NULL,\n"
+ " name VARCHAR(250),\n"
+ " isVIP BOOLEAN NOT NULL,\n"
+ " capacity INTEGER(20) NOT NULL, \n"
+ " UNIQUE (eventId) \n"
+ ");";
String sql = "INSERT OR REPLACE INTO events (eventId, roomNumber, startTime, endTime, capacity, name, isVIP)" + " Values('"+event.getID()+"', '"+event.getRoomNumber()+"', '"+event.getStartTime()+"', '"+event.getEndTime()+"', '"+event.getCapacity()+"', '"+event.getName()+"', '"+event.getVIPStatus()+"')";
I would read this thread for more information about how REPLACE works.
https://stackoverflow.com/questions/29539838/replace-versus-insert-in-sql#:~:text=According%20to%20the%20documentation%2C%20the,the%20new%20row%20is%20inserted.
Also I would suggest trying just "REPLACE," as it functions as INSERT but will replace on conflicts.
Related
In this table, I want to retrieve the value 55.2 in a variable.
This value is at row 5 (ID=5) and in the column 'Weight' of type REAL.
I can already get the desired row number which is stored in 'lastID' and I know that my data is in the column 'Weight'. So I have my X and my Y in the table.
I also know the sqlite command to retrieve the 55.2 in my cursor:
Cursor cursor2 = db.rawQuery("SELECT Weight FROM <MYTABLE> WHERE ID=" + lastID, null);
Double lastWeight = cursor2.getDouble(0); //This line is wrong, I need the help here!
But I can't get the 55.2 value I am looking for in my variable lastWeight from cursor2.
Any idea?
Addendum
Here the create table:
String CREATE_TABLE2 = "CREATE TABLE " + <MYTABLE> + " (" + UID2 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL_2 + " TEXT," + COL_3 + " TEXT," + COL_4 + " REAL," + COL_5 + " REAL);";
db.execSQL(CREATE_TABLE2);
After the execution of this line:
Cursor cursor2 = db.rawQuery("SELECT Weight FROM <MYTABLE> WHERE ID=" + lastID, null);
you get the results in cursor2.
A Cursor instance like cursor2 is used to loop through its rows and to do so you must first place its index at the 1st row by moveToFirst():
if (cursor2.moveToFirst()) {
Double lastWeight = cursor2.getDouble(0);
........................................
}
The if statement is necessary just in case the cursor does not contain any rows.
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)" +
")";
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
i need a tip here , here i have a code to insert into sqlite database:
Thread t = new Thread(new Runnable() {
#Override
public void run() {
String sqlCreate = "CREATE TABLE IF NOT EXISTS " + name
+ " (ID INTEGER PRIMARY KEY AUTOINCREMENT,"
+ " Type TEXT,"
+ " Text TEXT,"
+ " OtherFormats TEXT,"
+ " Date TEXT,"
+ " Image TEXT,"
+ " RealName TEXT)";
db.execSQL(sqlCreate);
//(String Type, String Text ,String name,String OtherFormats,String Itime,String
RealName)
String sqlInsert= "INSERT INTO " + "'"+name+"'" +
" VALUES
("+"'"+ID+"'"+","+"'"+Type+"'"+","+"'"+Text+"'"+","+
"'"+OtherFormats+"'"+","+"'"+Date+"'"+"
,"+"'"+Image+"'"+","+"'"+RealName+"')";
db.execSQL(sqlInsert);
}
});
t.start();
the question is as you u see my ID is auto increment, but for executing it well, i need to put a value there,what value should i put so it database does the increament itself?
thanks
05-26 03:56:33.018: E/AndroidRuntime(23809):
android.database.sqlite.SQLiteException: near "VALUES": syntax error (code 1): ,
while compiling: INSERT INTO 'new' (Type,Text,OtherFormats ,Date,Image,RealName VALUES('m','hey','n','03:56','j','s')
You can do this. Enter the name of columns you need to insert
String sqlInsert= "INSERT INTO " + "'"+name+"' (Type,Text,OtherFormats ,Date,Image,RealName )VALUES
("+"'"+ID+"'"+","+"'"+Type+"'"+","+"'"+Text+"'"+","+
"'"+OtherFormats+"'"+","+"'"+Date+"'"+"
,"+"'"+Image+"'"+","+"'"+RealName+"')";
db.execSQL(sqlInsert);
the question is as you u see my ID is auto increment, but for executing it well, i need to put a value there,what value should i put so it database does the increament itself?
Put in a NULL or just leave it unspecified.
From the documentation:
If no ROWID is specified on the insert, or if the specified ROWID has a value of NULL, then an appropriate ROWID is created automatically.
I'm trying to create a table similar to a ready table I created before (a template, if you will) where the only variable should be the table name.
This is what I've tried so far:
I exported the template table to mysql code and copied the code to a preparedStatement object as such:
createNewLineTableStatement = constantLink.prepareStatement("CREATE TABLE IF NOT EXISTS ? (" +
" `index` int(5) NOT NULL," +
" `station` int(5) NOT NULL," +
" PRIMARY KEY (`index`)," +
" UNIQUE KEY `station` (`station`)" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;\");");
Than I try to execute the code by calling the following function:
private static boolean createNewLineTable(String tableName) throws SQLException{
createNewLineTableStatement.setString(1, tableName);
if (createNewLineTableStatement.executeUpdate() == Statement.EXECUTE_FAILED)
return false;
return true;
}
But I'm getting a syntax error exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 ''line_37_var_1' ( `index` int(5) NOT NULL, `station` int(5) NOT NULL, PRIMARY' at line 1
How can I fix the code? OR is there a cleaner, better way to do the same thing? Maybe creating a script with a user variable? I thought of that but I've never used .sql script before.
Problem 1: You can't use a prepared statement parameter as the table name.
Problem 2: You have an unmatched paren and extra characters ");at the end of your statement.
Your query string should look something like:
String query = "CREATE TABLE IF NOT EXISTS `" + tableName + "` (" +
" `index` int(5) NOT NULL," +
" `station` int(5) NOT NULL," +
" PRIMARY KEY (`index`)," +
" UNIQUE KEY `station` (`station`)" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
by design, TableName and ColumnNames cannot be parameterized.
If you are scared about SQL Injection, create a custom function to check for malicious tableName. It is safe if the value comes inside of your application.
Then concatenate it in the string, add backtick for first level of defense :D
String tableName = "Your tableName";
String query = "CREATE TABLE IF NOT EXISTS `" + tableName + "` (" +
" `index` int(5) NOT NULL," +
" `station` int(5) NOT NULL," +
" PRIMARY KEY (`index`)," +
" UNIQUE KEY `station` (`station`)" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
You are missing Table name and i think that "?" shouldn't be there.
I will be something like
"CREATE TABLE IF NOT EXISTS YOURTABLE" + the following code