Getting the next autonumber value specific to a connection (concurrency) - java

I have a data entry page that displays a generated case number as:
This number is the next available autonumber for the primary key of the table. It was retrieved using:
String sql="SELECT AUTO_INCREMENT \r\n"
+ "FROM information_schema.tables \r\n"
+ "WHERE table_name = 'dataentrytbl' \r\n"
+ "AND table_schema = DATABASE();";
stmt=conn.prepareStatement(sql);
rs=stmt.executeQuery(sql);
if(rs.next()) reply=rs.getInt("AUTO_INCREMENT");
Everything works perfect. The system is online, multiple users are using the data entry page and getting concurrency problems. The reason is all of them are getting the same generated auto id so when they click the ENTER button, an error is thrown.
Question: is there a way to generate a unique value for the autonumber primary key together with the connection? So if there are 5 users accessing the page simultaneously, is there a way to generate 5 different values for each of them?

Related

Running IBM Db2 DDL statements in JDBC

I need to alter a Db2 column using JDBC. The column may change its name and/or its type. In Db2 these two actions are done in two steps, the first ALTER TABLE to change the name, and the second ALTER TABLE to change the type.
For example:
ALTER TABLE T1 RENAME COLUMN C1 TO C2;
ALTER TABLE T1 ALTER COLUMN C2 SET DATA TYPE decimal(4,0);
See below the code, the first statement is executed but the second always throws an exception.
String sql = "ALTER TABLE " + tableName + " RENAME COLUMN " +
originalName + " TO " + name;
PreparedStatement ps1 = conn.prepareStatement(sql);
ps1.executeUpdate();
sql = "ALTER TABLE " + tableName + " ALTER COLUMN " + name +
" SET DATA TYPE decimal(" + sc.getLength() + "," + sc.getDec() + ")";
PreparedStatement ps2 = conn.prepareStatement(sql);
ps2.executeUpdate();
The exception is:
The operation was not performed because the table is in an invalid
state for the operation. Table name: "DB.T1".
Reason code: "23".. SQLCODE=-20054, SQLSTATE=55019, DRIVER=4.27.25
What is the meaning of a table in an "invalid state"? Why is the table in this state? What's wrong with this code?
Always give your Db2-server platform (z/os, linux/unix/windows, i series) and Db2-server version when asking for Db2-help, because the answer can depend on these facts.
The exception SQL20054N reason 23, means that the table has reached a limit on the number of alterations and before continuing, the table need to be reorganized with a REORG command. The documentation for the error is here. The REORG command will put the table back into a normal state. Normally a DBA would consider running RUNSTATS command following the REORG to ensure that table statistics are refreshed following the alterations.
Db2-LUW allows a small number of table changes (often 3) before forcing a reorg for certain kinds of alterations. Previous alterations to this table might have been performed by others, in different transactions , without getting this exception. Schema-evolution tools should detect this state and recover from it.
This is a normal situation, and the recovery is to run the REORG command.
You can either ask your DBA to do reorg for you, or you can (if your authid has the correct permissions) from jdbc call a stored procedure admin_cmd() to perform the command for you, or just use the Db2 command line interface reorg table db.t1 inplace for example . The documentation for admin_cmd is here, and if you do not understand the REORG details, ask your DBA for help.

Derby Auto Increment by 100 when specified as 1

I used the statement below to create a Derby database table with auto-increment primary column.
CREATE TABLE \"table\" (\n"
+ " \"id\" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL,\n"
+ " \"path\" VARCHAR(2000) DEFAULT NULL,\n"
+ " \"downloaded\" BOOLEAN DEFAULT false NOT NULL,\n"
+ " \"retried_times\" SMALLINT DEFAULT 0 NOT NULL,\n"
+ " \"name\" VARCHAR(40),\n"
+ " \"downloaded_date\" TIMESTAMP DEFAULT NULL,\n"
+ " PRIMARY KEY (\"id\")\n"
When I insert a row through Spring JDBC, it increments by 100. Is there any error in my statement?
This is due to pre-allocation of values for auto-increment columns. Derby being an in-memory database, caches auto-increment values when the database is first loaded into the memory. Then, future values of the auto-increment columns are generated using the cache instead of querying the database again and again. If the database is not shut down properly, unused values from the cache are lost forever.
You have two options to address this:
Add ;shutdown=true to the JDBC URL. This will shut the database down when the application ends.
Set the derby.language.sequence.preallocator property to 1 (its default value is 100). This will ensure that the column value is never cached.
Note that most databases behave similarly for sequences. For example, H2 has the exact same behaviour but uses a cache size of 32 instead of 100 like Derby does.
Thanks to #manish the second option worked for me.
In order to implement the 2nd solution, add the following code line where you set your database connection as shown in the below example.
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
String URL = "jdbc:derby:testDB;create=true;";
conn = DriverManager.getConnection(URL);
System.setProperty("derby.language.sequence.preallocator", "1"); // Add this line
Thanks to answer provided by #xfocus99, I was able to know how to implement the 2nd solution.

UcanaccessSQLException: unexpected token: ORDER

I'm making a little app in Java and MySQL with PHPMyAdmin and all runs fine, but my professor says that we have to work with a database in Access, so I just changed my class connection and imported my database. The INSERT, SELECT and other UPDATE statements run fine but this statement just doesn't run.
UPDATE table SET col1=?, col2=? WHERE col0=? ORDER BY col4 DESC LIMIT 1
I can't understand how in MySQL it runs fine but with UCanAccess it doesn't work.
I can't understand how in MySQL it runs fine but with UCanAccess it doesn't work.
That's because the various producers of database software have taken it upon themselves to implement the SQL language in slightly different ways, so a given SQL statement written for MySQL is not guaranteed to work under Access, or Microsoft SQL Server, or Oracle, or any other "dialect" of SQL.
UCanAccess tries very hard to follow the Access SQL syntax. Access SQL uses TOP n instead of LIMIT n, but Access SQL also does not allow TOP n or ORDER BY in the main part of an UPDATE query. So you need to use a subquery to identify the primary key value of the row you want to update.
For example, if your table has a primary key column named "id" then you can do
sql =
"UPDATE table1 SET col1=?, col2=? " +
"WHERE id IN ( " +
"SELECT TOP 1 id " +
"FROM table1 " +
"WHERE col0=? " +
"ORDER BY col4 DESC, id " +
")";

Why does this SQL-Statement lead to an error?

I am getting quite angry with this, so I seek help from the crowd ;)
What I want to do: We have a Unity learning game which shall implement a login window. The entered credentials are then hashed (the pw is) and sent to the server, who then should check this against a database.
I have the following table:
xy.users_confirms with the following colums:
id username email password hashcode created
Why does my code
String sql = "SELECT " + "xy.users_confirms.password as pwhash, "
+"FROM xy.users_confirms " +"WHERE xy.users_confirms.username = " +"\"userNameToGetHashFor\"";
lead me to the SQLException "Parameter index out of range (1 > number of parameters, which is 0)"
?
Thanks, any input is much appreciated!
Try this:
String parameter = "'"+ strNameToGetHashFor + "'";
String sql = "SELECT " + "xy.users_confirms.password as pwhash, "
+"FROM xy.users_confirms "
+"WHERE xy.users_confirms.username ="+ parameter;
You are using varchar value as a parameter so it's need to be quot like this.'username'. or you can use Stored Procedure.
Personally, I would try getting a working query using the custom query box directly in phpmyadmin. Once you have a working query you can re-write it in java.
And I would try writing the syntax like this into the phpmyadmin query box:
SELECT password as pwhash
FROM xy.users_confirms
WHERE username ='userNameToGetHashFor'
Using the above syntax I don't see anyway your error could persist.
Phpmyadmin screen cap showing custom query box: http://screencast.com/t/9h8anH0Aj
(the 2 empty text boxes in screen cap are just me hiding my database info)
The comma after pwhash is one potential cause:
+ "xy.users_confirms.password as pwhash*!*,*!* "
Depending on the DBMS, you may also need to use single quotes instead of double quotes like this:
+ "'userNameToGetHashFor'";
Also this code is potentially vulnerable to a SQL Injection attack so you may want to make the userNameToGetHashFor a parameter rather than concatenating the string into the SQL statement.

Error executing Create table statement in Java?

I am trying to create 2 tables in MySql using Java JDBC,the first one runs fine but I get an error when I execute the second create table command. The problem looks like in the Foreign key definition not sure what's missing ?
Error :
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 'FOREIGN KEY(UniqueBusID)
REFERENCES BUS_3_CLEARBROOK_UFV_GOLINE_TO_UFV_BusDetai' at line 1
Code
String table_UniqueBusNameTimings = BusDetails+"_BusTimings";
String timings= "Timings";
String dayofweek = "DayOfWeek";
String FuniqueBusID = "UniqueBusID";
String table_UniqueBusNameDetails = BusDetails+"_BusDetails";
String PuniqueBusID = "UniqueBusID";
String StopNames = "StopNames" ;
String sql1 = "CREATE TABLE "+table_UniqueBusNameDetails+
"(UniqueBusID VARCHAR(255) not NULL, " +
" StopNames VARCHAR(1000), " +
" PRIMARY KEY ( UniqueBusID ))";
String sql2 = "CREATE TABLE "+table_UniqueBusNameTimings+
"(Timings VARCHAR(255) , " +
" DayOfWeek VARCHAR(25), " +
" UniqueBusID VARCHAR(255) "+
" FOREIGN KEY(UniqueBusID) REFERENCES "+table_UniqueBusNameDetails+"(UniqueBusID))";
stmt.executeUpdate(sql1);
stmt.executeUpdate(sql2);
You have a comma missing after UniqueBusID VARCHAR(255). Just change it to UniqueBusID VARCHAR(255), and your code shall be fine.
For details on syntax related to CREATE TABLE with FOREIGN KEY, you can explore this page: http://www.w3schools.com/sql/sql_foreignkey.asp
We should use CREATE TABLE IF NOT EXISTS... then if we are having foreign key relation then we should use SET FOREIGN_KEY_CHECKS=0; Finally we will execute a batch what having all the statement and then commit.
Every attribute like column, index, foreign key etc. should be seprated by comma ',' in table creation syntax. so here a comma missing after UniqueBusID VARCHAR(255). It will be fine after adding comma here.
#Suzon: We should not set foreign_key_checks=0 specially during creating table or adding any constraint at it will skip any constraint checking by mysql and create major issue in database. We can use it only we are sure its impact for example we want to delete some rows from master table even child table contains corresponding rows and we are fine with this etc.

Categories