Hi i am a newbie to use MySql statements.
This is my Parent table
Name Sell_amt Mrp_amt Cost_amt Goods_Name Goods_Weight Goods_quantity
John 100 90 80 Choclate 1lb 5
samson 100 110 60 mobile 0.5lb 8
James 100 100 70 chair 1lb 5
This is my Child table columns
Name Sell_amt Mrp_amt Special_DealStatus
Now i need to update the child table based on my parent table.
The problem is If (Sell_amt'<'Mrp_amt) then i need to update Special_DealStatus column with 1.
Please suggest,I have googled a lot but couldn't find the answer.
I created a SQL fiddle for you to try out. What you are looking for is this
INSERT INTO Child_Table (`name`, `sellamt`, `mrpamt`, `specialdealstatus`)
SELECT name, sellamt, mrpamt,1
FROM Parent_Table
WHERE sellamt < mrpamt;
here is the SQL fiddle
What this does is inserts the selected values from the Parent_Table into the the Child_Table WHERE sellamt < mrpamt as you asked. It also sets specialdealstatus to one with a static value '1' placed into the SELECT statement.
import java.sql.*;
public class MysqlPreparedStatement
{
public static void main(String[] args)
{
try
{
// create a mysql database connection
String myDriver = "org.gjt.mm.mysql.Driver";
String mySqlServer = "jdbc:mysql://localhost/test";
Class.forName(myDriver);
Connection conn = DriverManager.getConnection(mySqlServer, "root", "");
// the mysql statement
String query = " INSERT INTO Child_Table (`name`, `sellamt`, `mrpamt`, `specialdealstatus`)
SELECT name, sellamt, mrpamt,1
FROM Parent_Table
WHERE sellamt < mrpamt ";
// create the mysql insert preparedstatement
PreparedStatement preparedStmt = conn.prepareStatement(query);
// execute the preparedstatement
preparedStmt.execute();
conn.close();
}
catch (Exception e)
{
System.err.println("Throwing an exception!");
System.err.println(e.getMessage());
}
}
}
You could try something like the following with case as Andreas already mentioned.
insert into Child
select Name,Sell_amt,Mrp_amt, case when sell_amt<Mrp_amt then 1 else null end as Special_DealStatus from Parent
Related
This question already has answers here:
How to get the insert ID in JDBC?
(14 answers)
Closed 7 years ago.
In MySql, I want to use equivalent of SQL ##IDENTITY and I found this LAST_INSERT_ID(). I found in search that it work fines even if there are different sessions exist. I want to find last ID,in current session. I am using following code.
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = null;
conn = DriverManager.getConnection("jdbc:mysql://localhost/fuel","root", "");
System.out.print("Database is connected !\n");
Statement st = conn.createStatement();
String response = "<food>";
String insertQuery = "INSERT INTO transactions(user_input,fuel_response,execution_time)"+
"VALUES(?,?,?)";
PreparedStatement prepareStatementObj = conn.prepareStatement(insertQuery);
prepareStatementObj.setString(1, "I drank a babyfood juice apple.");
prepareStatementObj.setString(2, response);
prepareStatementObj.setInt(3, 4500);
prepareStatementObj.execute();
String queryForId = "SELECT LAST_INSERT_ID() FROM transactions";
ResultSet rs2 = st.executeQuery(queryForId);
if (!rs2.isBeforeFirst() ) {
System.out.println("No data");
} else {
while ( rs2.next() ) {
int id = rs2.getInt("id");
System.out.println("Last id of this session was..."+id);
}
}
conn.close();
} catch(Exception e) {
System.out.print("Do not connect to DB - Error:"+e);
}
}
Code is working for Insertion but I am not getting last inserted id. It gives following exception.
Column 'id' not found.
I will be thankful to you if you can help.
Modify your select to use alias as id:-
SELECT LAST_INSERT_ID() as id FROM transactions
You're trying to grab a column called id, but there's no such column. When you grab the last inserted ID, you get a column called last_insert_id() instead:
MySQL> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 0 |
+------------------+
1 row in set (0.02 sec)
Easier to grab it by index (use .getInt(int)). This is perfectly safe because you know there will only be one column returned.
You can use below code to get last insert id.
ResultSet rs = prepareStatementObj.getGeneratedKeys();
if(rs.next())
{
last_inserted_id=Integer.toString(rs.getInt(1));
}
The problem is when I run this code, I always get answer COL12 instead of getting all the columns with data like I am getting in MYSQL workbench. I need to get same values. Moreover when I use this query "DELETE FROM test WHERE col1 = 2;" in netbeans I get Error Exception.
Here is my Code I wrote in Netbeans.
package sams;
import java.sql.*;
import java.sql.Statement;
import java.sql.DriverManager;
public class Temp_Class {
public static void main(String[] args){
try {
String query="SELECT * FROM test";
Class.forName("com.mysql.jdbc.Driver");
Connection con= DriverManager.getConnection("jdbc:mysql://localhost/JavaProject", "root", "19881990");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery(query);
rs.next();
String sname= rs.getString(2);
System.out.println(sname);
con.close();
} catch (Exception e) {
System.out.println("Error");
}
}
}
I have made table test in MYSQL Workbench, with columns="col1, col2, col3" with values="1, COL11, COL12" and "2, COL21, COL22";
This is the code I use to delete a value in DB. . . but getting Error Exception.
public static void main(String[] args){
try {
String deletesql="DELETE FROM test WHERE col1 = 2";
Class.forName("com.mysql.jdbc.Driver");
Connection con= DriverManager.getConnection("jdbc:mysql://localhost/JavaProject", "root", "19881990");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery(select);
Statement ds=con.createStatement();
ResultSet dsrow=ds.executeQuery(deletesql);
dsrow.next();
String ds1= dsrow.getString(1);
String ds2= dsrow.getString(2);
String ds3= dsrow.getString(3);
System.out.println(ds1+" "+ ds2+" "+ds3);
con.close();
} catch (Exception e) {
System.out.println("Error");
}
}
String sname= rs.getString(2); returns one column from the resultSet. If you want to have all columns you have to use:
String sname0= rs.getString(0);
String sname1= rs.getString(1);
String sname2= rs.getString(2);
The reason you are getting one column is because you are fetching only one column
rs.next();
String sname= rs.getString(2); //will give you one column
instead do
while(rs.next){ //get all rows
String col1= rs.getString(0); //get column 1 of respective row
String col2= rs.getString(1); //get column 2 of respective row
System.out.println(col1+" "+col2);
}
I think the problem is from rs.getString(2)
Here you have just tried to get the third column. You can use rs.getString(0) and rs.getString(1) to get other values.
test table
col1 col2 col3
col1 1 2
col2 col11 col21
col3 col12 col22
you are queries for col1 (i.e. SELECT * FROM test)
String sname= rs.getString(2);
System.out.println(sname);
rs.getString(2) i.e. we are passing column index i.e. second column col2
and it prints the first value in column 2 i.e. 1
here 1 should be printed in reality
I want to execute a query in Java.
I create a connection. Then I want to execute an INSERT statement, when done, the connection is closed but I want to execute some insert statement by a connection and when the loop is finished then closing connection.
What can I do ?
My sample code is :
public NewClass() throws SQLException {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
System.out.println("Where is your Oracle JDBC Driver?");
return;
}
System.out.println("Oracle JDBC Driver Registered!");
Connection connection = null;
try {
connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:orcl1", "test",
"oracle");
} catch (SQLException e) {
System.out.println("Connection Failed! Check output console");
return;
}
if (connection != null) {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * from test.special_columns");
while (rs.next()) {
this.ColName = rs.getNString("column_name");
this.script = "insert into test.alldata (colname) ( select " + ColName + " from test.alldata2 ) " ;
stmt.executeUpdate("" + script);
}
}
else {
System.out.println("Failed to make connection!");
}
}
When the select statement ("SELECT * from test.special_columns") is executed, the loop must be twice, but when (stmt.executeUpdate("" + script)) is executed and done, then closing the connection and return from the class.
Following example uses addBatch & executeBatch commands to execute multiple SQL commands simultaneously.
import java.sql.*;
public class jdbcConn {
public static void main(String[] args) throws Exception{
Class.forName("org.apache.derby.jdbc.ClientDriver");
Connection con = DriverManager.getConnection
("jdbc:derby://localhost:1527/testDb","name","pass");
Statement stmt = con.createStatement
(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String insertEmp1 = "insert into emp values
(10,'jay','trainee')";
String insertEmp2 = "insert into emp values
(11,'jayes','trainee')";
String insertEmp3 = "insert into emp values
(12,'shail','trainee')";
con.setAutoCommit(false);
stmt.addBatch(insertEmp1);
stmt.addBatch(insertEmp2);
stmt.addBatch(insertEmp3);
ResultSet rs = stmt.executeQuery("select * from emp");
rs.last();
System.out.println("rows before batch execution= "
+ rs.getRow());
stmt.executeBatch();
con.commit();
System.out.println("Batch executed");
rs = stmt.executeQuery("select * from emp");
rs.last();
System.out.println("rows after batch execution= "
+ rs.getRow());
}
}
Result:
The above code sample will produce the following result.The result may vary.
rows before batch execution= 6
Batch executed
rows after batch execution= = 9
Source: Execute multiple SQL statements
In the abscence of the schema or the data contained in each table I'm going to make the following assumptions:
The table special_columns could look like this:
column_name
-----------
column_1
column_2
column_3
The table alldata2 could look like this:
column_1 | column_2 | column_3
---------------------------------
value_1_1 | value_2_1 | value_3_1
value_1_2 | value_2_2 | value_3_2
The table alldata should, after inserts have, happened look like this:
colname
---------
value_1_1
value_1_2
value_2_1
value_2_2
value_3_1
value_3_2
Given these assumptions you can copy the data like this:
try (
Connection connection = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:orcl1", "test", "oracle")
)
{
StringBuilder columnNames = new StringBuilder();
try (
Statement select = connection.createStatement();
ResultSet specialColumns = select.executeQuery("SELECT column_name FROM special_columns");
Statement insert = connection.createStatement()
)
{
while (specialColumns.next())
{
int batchSize = 0;
insert.addBatch("INSERT INTO alldata(colname) SELECT " + specialColumns.getString(1) + " FROM alldata2");
if (batchSize >= MAX_BATCH_SIZE)
{
insert.executeBatch();
batchSize = 0;
}
}
insert.executeBatch();
}
A couple of things to note:
MAX_BATCH_SIZE should be set to a value based on your database configuration and the data being inserted.
this code is using the Java 7 try-with-resources feature to ensure the database resources are released when they're finished with.
you haven't needed to do a Class.forName since the service provider mechanism was introduced as detailed in the JavaDoc for DriverManager.
There are two problems in your code. First you use the same Statement object (stmt) to execute the select query, and the insert. In JDBC, executing a statement will close the ResultSet of the previous execute on the same object.
In your code, you loop over the ResultSet and execute an insert for each row. However executing that statement will close the ResultSet and therefor on the next iteration the call to next() will throw an SQLException as the ResultSet is closed.
The solution is to use two Statement objects: one for the select and one for the insert. This will however not always work by default, as you are working in autoCommit (this is the default), and with auto commit, the execution of any statement will commit any previous transactions (which usually also closes the ResultSet, although this may differ between databases and JDBC drivers). You either need to disable auto commit, or create the result set as holdable over commit (unless that already is the default of your JDBC driver).
I have a requirement where I need to insert mobile number in mysql if and only if the number is is not present.So for this I am first checking if a number is present in mysql using select query .If number is not present then insert.Following is my code
PreparedStatement pt1=con.prepareStatement("select * from registerSmsUsers where mobile='"+mobile+"'");
PreparedStatement pt=con.prepareStatement("insert into registerSmsUsers values(?,?,?)");
pt.setString(1, name);
pt.setString(2, email);
pt.setString(3, mobile);
ResultSet rs1=pt1.executeQuery();
if(rs1.next())
{pt.executeUpdate();}
i dont know whether this is a efficient way or not.Please suggest me a better way then this
Probably the easiest way in mysql is:
insert ignore into registerSmsUsers values(?,?,?)
When assuming you have unique key on mobile
You may check it here: How to 'insert if not exists' in MySQL?
Or here: http://dev.mysql.com/doc/refman/5.6/en/insert.html
Many of the proposed solutions (including yours) have a race condition that can cause a primary key or unique constraint violation. You code also have a possible SQL injection attack by concatenating SQL rather than using prepared statement parameters. Use SELECT...FOR UPDATE.
PreparedStatement ps = con.prepareStatement("SELECT name, email, mobile FROM registerSmsUsers WHERE mobile=? FOR UPDATE",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
ps.setString(1, mobile);
ResultSet rs = ps.executeQuery();
if (rs.next()) { // it exists already
rs.moveToCurrentRow();
rs.updateString(3, mobile);
rs.updateRow();
} else { // it does NOT exist
rs.moveToInsertRow();
rs.updateString(1, name);
rs.updateString(2, email);
rs.updateString(3, mobile);
rs.insertRow();
}
rs.close();
ps.close();
EDIT: Just make sure you have an index on registerSmsUsers.
CREATE INDEX registerSmsUsers_mobile_ndx ON registerSmsUsers(mobile)
or a unique contraint (which implicitly creates an index):
ALTER TABLE registerSmsUsers ADD CONSTRAINT registerSmsUsers_mobile_unq UNIQUE (mobile)
With an index, even with millions of records the update/insert will basically be instant.
EDIT2: Added cursor/result set options.
I think it would be better to create a stored procedure and then in that stored procedure you can first use the IF NOT EXISTS clause to check if the user exists using the select statement. If the user is not present you can insert the user in database.
Something like this:
IF NOT EXISTS(SELECT 1 FROM `registerSmsUsers` WHERE mobile= #mobile) THEN
BEGIN
INSERT INTO
`registerSmsUsers`
(
//column names
)
VALUES
(
//values
);
END;
END IF;
Also there is a INSERT IGNORE statement which you can use like this:
insert ignore into registerSmsUsers values(?,?,?)
if not exists(select * from registerSmsUsers where mobile='232323') <-- will check your mobile no
begin
insert into registerSmsUsers values(?,?,?)
end
This one is also an efficient way to check your method is also working fine but this also can be done
See difference is you will have only one query here
i hope this will help you thanks
[Edit]
Your questions answer
Ya there is a execution time diff between yours and mine query its depends upon a database size what you are using if you are using small size database (probably 1000 people) then you will not see any diff between your query and mine query but if your are using lakhs of users then your will have a performace issues check include execution plan in mysql you will get realtime difference between two
As requested, here is my tweaked version of brettw's answer:
import java.sql.*;
public class MySQLtest {
public static void main(String[] args) {
Connection con;
try {
con = DriverManager.getConnection(
"jdbc:mysql://192.168.1.3/zzzTest?" +
"useUnicode=yes&characterEncoding=UTF-8" +
"&user=root&password=whatever");
String newName = "Gord";
String newEmail = "gord#example.com";
String newMobile = "416-555-1212";
String sql =
"SELECT " +
"id, " +
"name, " +
"email, " +
"mobile " +
"FROM registerSmsUsers " +
"WHERE mobile = ? " +
"FOR UPDATE";
PreparedStatement pst = con.prepareStatement(
sql,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_UPDATABLE);
pst.setString(1, newMobile);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
rs.moveToCurrentRow();
rs.updateString("name", newName);
rs.updateString("email", newEmail);
rs.updateRow();
System.out.println("Existing row updated.");
}
else {
rs.moveToInsertRow();
rs.updateString("name", newName);
rs.updateString("email", newEmail);
rs.updateString("mobile", newMobile);
rs.insertRow();
System.out.println("New row inserted.");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
Note that id is the Primary Key for the table: int(11) NOT NULL AUTO_INCREMENT
I have a managed bean which makes SQL queries to Oracle database. This is just very simple example how I make SQL queries. This is the table structure:
GLOBALSETTINGS
---------------------------------
SessionTTL VARCHAR2(40 BYTE)
MAXACTIVEUSERS NUMBER
ACTIVEUSERS VARCHAR2(20 BYTE)
I use this table just to store application settings. In the example listed below I can fetch just one string with one SQL statement. I want with SQL query to fetch the content of the three rows - SessionTTL, MAXACTIVEUSERS, ACTIVEUSERS. Is it possible?
public String CheckUserDB(String userToCheck) throws SQLException {
String storedPassword = null;
String SQL_Statement = null;
if (ds == null) throw new SQLException();
Connection conn = ds.getConnection();
if (conn == null) throw new SQLException();
try {
conn.setAutoCommit(false);
boolean committed = false;
try {
SQL_Statement = "SELECT Passwd from USERS WHERE Username = ?";
PreparedStatement passwordQuery = conn.prepareStatement(SQL_Statement);
passwordQuery.setString(1, userToCheck);
ResultSet result = passwordQuery.executeQuery();
if(result.next()){
storedPassword = result.getString("Passwd");
}
conn.commit();
committed = true;
} finally {
if (!committed) conn.rollback();
}
}
finally {
conn.close();
}
return storedPassword;
}
P.S I want the content of the rows.
I'm hoping I understand what you are asking for, but I fear I don't as it seems too simple, but anyway...
I think you want the contents of 3 columns, not rows. And yes you can, you just specify the columns you want returned in your SQL statement:
SELECT SessionTTL, MAXACTIVEUSERS, ACTIVEUSERS FROM GLOBALSETTINGS WHERE (condition)...
you can also use * as a shortcut for all columns iof you don't want to explicitly specify them:
SELECT * FROM GLOBALSETTINGS WHERE (condition)...
Some background reading on SQL syntax might be useful
If I read this correctly (sorry if mistaken), all you want to do is change your SQL command to select ALL COLUMNS in your database table.
To do so:
string SqlAll = #"SELECT Database.SessionTTL, Database.MAXACTIVEUSERS, Database.ACTIVEUSERS FROM Database";
This will retrieve ALL columns in the database. You can also have conditional statements in your queries when you want to filter for logical reasons, such as TOP 20 to get the first 20 results from the result set.
If you like to return multiple lines with one sql query, you may want to look into ArrayList as you need a loop, where the code would go through your records and match and find all possible results until the end of the records list.