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.
Related
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.
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 " +
")";
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.
I'm trying to insert values into a SQL database from within Java. This works fine, except for some of the values. Eg, when I insert "foo" it appends null at the start so it becomes "nullfoo". If I insert the same statement in SQL Server Management Studio this doesn't happen.
To be sure: I print the string before inserting it and it reads "foo".
My insert code:
statement.execute("INSERT INTO " + settings.getProperty("table") + " VALUES ('" + value1+ "', '" + value2 + "', '" + value3 + "')");
You're concatenating values into the SQL statement. If any of those references (value1, value2 etc) are null, then those will be converted into the string "null" as part of concatenation.
The correct fix for this is not to change the way you're doing validation - it's to stop putting the values into the SQL statement itself. Use PreparedStatement with parameterized SQL and set parameter values instead.
Benefits:
You won't get "null" inserted any more
You won't be vulnerable to SQL injection attacks any more (you are now)
When inserting non-text data you won't need to worry about problematic conversions (this is particularly relevant for date/time fields)
Your code will be clearer, as you'll be separating the code (SQL) from the data (parameter values)
Your prepared statement query plan can be cached by the server, so it may perform faster
You should use variable binding in your SQL
http://decipherinfosys.wordpress.com/2007/08/29/bind-variables-usage-parameterized-queries-in-sql-server/
It's easier to check for errors.
In your case you are probably adding null+"foo" so you get nullfoo.
I'm currently using HSQLDB to save java data. Within theses datas, there are some Double, and some of them can be of values of NaN (described as 0.0/0.0 in the javadoc). HSQLDB know how to handle these values in setDouble and setFloat of PreparedStatement. The thing is, I have to use a Statement object, not a precompiled stored procedure, and I just can't find a way to make it work.
If you had the tinyest hint, it would be most welcome :)
Thanks.
EDIT : Here's the bunch of code I'm using :
stmt.executeUpdate("insert into Mesh(Id, name, dimension, meshtype, totalVolume, NumberOfCoarseCell) values (identity(), "
+ "'" + name_ + "',"
+ dimension_ + "," // this value can be NaN
+ "'" + type_.toString() + "',"
+ totalVolume_ + "," // this value can be NaN
+ numberOfCoarseCells_ + ")");
You mean you need a way to write a NaN within a SQL statement? The following works for the H2 database:
select sqrt(-1) from dual
However, it doesn't work for Apache Derby and PostgreSQL (I didn't test other databases). For HSQLDB, it no longer works in version 2.1 and newer, unless you set SET DATABASE SQL DOUBLE NAN FALSE.
With HSQLDB 1.8.x you can use (0.0e1/0.0e1) as an expression that returns NaN.
For example:
create table t (d double)
insert into t values (0.0e1/0.0e1)
For HSQLDB 2.1 and above, an property must be specified with an SQL statement:
SET DATABASE SQL DOUBLE NAN FALSE
Or as a connection property:
hsqldb.double_nan=false