I am dynamically adding column to table in db through code using alter table query.
But i am facing problem wen i am trying to insert values in that column. it throws an exception column does not exists.
And wen i clean and rebuild my project through netbeans it works fine.
I am using java and mysql as databse .
Is there any body who know the solution for this problem.
Following is my alter table query Code
String alterTableQuery ="alter table `test` add `abc` varchar(50) NOT NULL default ''";
stmt = conn.prepareStatement(alterTableQuery);
boolean val = stmt.execute();
And I am trying to insert data using following code.
String sqlQuery = "insert into `test` (`id`,`abc`) values (?)" ;
stmt = conn.prepareStatement(sqlQuery);
boolean val = stmt.execute();
You might also rethink your design. In general it is a poor practice for the user interface to add columns to tables. Perhaps you need a more normalized design. Database structural changes should not come from the user. You could create a real mess if different users were making changes at the same time. Additionally users should not have the security rights to add columns. This is a major risk for your system.
I dont know about Java but in .net after performing a change on a table you need to call dataAdapter.AcceptChanges(); which essentially commits the change to the table.
In your codedo you need to make a similar call after you have added the column to the table,for the insert to be able to work.
This may be because Data Description Language (DDL) is often executed outside of transactions. Perhaps a commit/rollback, or even reconnect would sort the problem. Just a guess.
Related
I'm relatively new to working with JDBC and SQL. I have two tables, CustomerDetails and Cakes. I want to create a third table, called Transactions, which uses the 'Names' column from CustomerDetails, 'Description' column from Cakes, as well as two new columns of 'Cost' and 'Price'. I'm aware this is achievable through the use of relational databases, but I'm not exactly sure about how to go about it. One website I saw said this can be done using ResultSet, and another said using the metadata of the column. However, I have no idea how to go about either.
What you're probably looking to do is to create a 'SQL View' (to simplify - a virtual table), see this documentation
CREATE VIEW view_transactions AS
SELECT Name from customerdetails, Description from cakes... etc.
FROM customerdetails;
Or something along those lines
That way you can then query the View view_transactions for example as if it was a proper table.
Also why have you tagged this as mysql when you are using sqlite.
You should create the new table manually, i.e. outside of your program. Use the commandline 'client' sqlite3 for example.
If you need to, you can use the command .schema CustomerDetails in that tool to show the DDL ("metadata" if you want) of the table.
Then you can write your new CREATE TABLE Transactions (...) defining your new columns, plus those from the old tables as they're shown by the .schema command before.
Note that the .schema is only used here to show you the exact column definitions of the existing tables, so you can create matching columns in your new table. If you already know the present column definitions, because you created those tables yourself, you can of course skip that step.
Also note that SELECT Name from CUSTOMERDETAILS will always return the data from that table, but never the structure, i.e. the column definition. That data is useless when trying to derive a column definition from it.
If you really want/have to access the DB's metadata programatically, the documented way is to do so by querying the sqlite_master system table. See also SQLite Schema Information Metadata for example.
You should read up on the concept of data modelling and how relational databases can help you with it, then your transaction table might look just like this:
CREATE TABLE transactions (
id int not null primary key
, customer_id int not null references customerdetails( id )
, cake_id int not null references cakes( id )
, price numeric( 8, 2 ) not null
, quantity int not null
);
This way, you can ensure, that for each transaction (which is in this case would be just a single position of an invoice), the cake and customer exist.
And I agree with #hanno-binder, that it's not the best idea to create all this in plain JDBC.
I have a table with more than 7 million of rows in mysql (InnoDB) and I do some operations with Java. Everything was working correctly until I had to delete some rows and insert some new rows.
The problem is that when I do a select, I keep getting the old values instead of the news. For example if I try to do a count(*), I get 2760, instead of 2786.
Any idea?
Thanks for your time.
Please, check in the Database options, if the db have the auto-commit option selected.
If auto-commit isnt possible, make a db.commit() after each transaction and make your transaction class synchcronized (for safe reasons).
use count(id) instead of count(*) where id is your primary key of your table because for count rows count(id) is preferable over count(*)
And you should mention exact problem so that we can easily solve it so provide some situation where you stuck
I'm trying to create a table in mysql through java. I'm using putty for this by the way. Here is a bit of the code I have so far but it doesn't work.
rs=s.executeQuery("CREATE TABLE test(id CHAR(2),name VARCHAR(3),PRIMARY KEY(id)); ");
while(rs.next())
{
System.out.println(rs.getString(1));
}
catch (SQLException ex)
{
System.out.println("SQLException:"+ ex.getMessage());
}
executeQuery() is for quires (usually SELECT) that return a ResultSet.
With DML (and DDL) queries you need to use executeUpdate() method.
For more information and examples use Setting Up Tables tutorial.
See this post here: Data Manipulation Statements
You should be using executeUpdate() if you wish to actually modify the database.
Your query is ok! But you don't get a result set! the CREATE TABLE won't give an rows or columns.
You have been tricked be the documentation:
Returns:
a ResultSet object that contains the data produced by the given query; never null
however
Throws:
SQLException - if a database access error occurs,... the given SQL statement produces anything other than a single ResultSet object, ...
In my opinion a call of "execute" would be the proper way.
I don't think its ever a good idea to generate your database schema via Java. Use the utility tool that comes with your database to create your schema. This way, you or anyone (such as a DBA) can create your tables, views, indexes, constraints, grant permissions, etc without having to know Java. You can even have your database utility generate an SQL script that you can run to re-generate the schema from scratch. Last point: I believe you will be better off calling your primary key test_id and making it type numberic, long, or int. this way, when you refer to it as a foreign key in another table, you will immediately know it refers back to the test table.
preparedStatement.executeUpdate()
Returns the number of rows updated. To my research so far it's not possible to do an update-query in which you would retrieve the updated rows, but this seems like such a basic feature that I'm clearly missing something. How to accomplish this?
Per first comment on question this is simply not possible in MySQL. PostgreSQL supports UPDATE...RETURNING as this feature.
If you use executeQuery instead of executeUpdate, you get a resultset back.
Then, change your stored procedure to be a function, and return the changed rows in a select at the end of the function. AFAIK, you cannot return data from a procedure in MySQL (as opposed to e.g. Microsoft SQL server).
EDIT: The suggestion struck out above is not possible. The JDBC specification does not allow updates in query statements (see the answer for this one: http://bugs.mysql.com/bug.php?id=692).
BUT, if you know the WHERE clause of the rows you are about to update, you can always select them first, to get the primary keys, perform the update, and then perform a select on them afterwards. Then you get the changed rows.
when you fire preparedStatement.executeUpdate() you already have the row identifiers using which you can uniquely identify the rows you want updated- you need to use the same identifiers to do a query and fetch the updated rows. you can not accomplish update and retrieval in one shot using JDBC apis.
There is a UNIQUE database constraint on an index which doesn't allow more than one record having identical columns.
There is a piece of code, managed by Hibernate (v2.1.8), doing two DAO
getHibernateTemplate().save( theObject )
calls which results two records entered into the table mentioned above.
If this code is executed without transactions, it results INSERT, UPDATE, then another INSERT and another UPDATE SQL statements and works fine. Apparently, the sequence is to insert the record containing DB NULL first, and then update it with the proper data.
If this code is executed under Spring (v2.0.5) wrapped in a single Spring transaction, it results two INSERTS, followed by immediate exception due to UNIQUE constraint mentioned above.
This problem only manifests itself on MS SQL due to its incompatibility with ANSI SQL. It works fine on MySQL and Oracle. Unfortunately, our solution is cross-platform and must support all databases.
Having this stack of technologies, what would be your preferred workaround for given problem?
You could try flushing the hibernate session in between the two saves. This may force Hibernate to perform the first update before the second insert.
Also, when you say that hibernate is inserting NULL with the insert, do you mean every column is NULL, or just the ID column?
I have no experience in Hibernate, so I don't know if you are free to change the DB at your will or if Hibernate requires a specific DB structure you cannot change.
If you can make changes then you can use this workaround in MSSQL tu emulate the ANSI behaviour :
drop the unique index/constraint
define a calc field like this:
alter table MyTable Add MyCalcField as
case when MyUniqueField is NULL
then cast(Myprimarykey as MyUniqueFieldType)
else MyUniqueField end
add the unique constraint on this new field you created.
Naturally this applies if MyUniqueField is not the primary key! :)
You can find more details in this article at databasejournal.com