How to retrieve all generated keys from multiple row PreparedStatement in Java? - java

Assuming the following SQL Statement:
INSERT INTO MATERIAL (ID, CODE, NAME) VALUES
(NULL, 'firstCode', 'firstName'),
(NULL, 'secondCode', 'secondName');
Using the follwing code where the PreparedStatement instance ps represents the SQL statement from above. And the PreparedStatement has been obtained with the option new String[]{"ID"} in order to specify the column name of the generated keys:
try {
final int affectedRows = ps.executeUpdate();
assertEquals("failed to insert all entries", "2", String.valueOf(affectedRows));
final ResultSet generatedKeys = ps.getGeneratedKeys();
while (generatedKeys.next()) {
System.out.println(generatedKeys.getInt(1));
}
} catch (SQLException e) {
// some catch block
}
The problem is that only the ID of the second row will be retrieved. Do you have a suggestion how to retrieve all of the generated keys?
EDIT:
This is the table's definition.
CREATE TABLE IF NOT EXISTS "MATERIAL" (
"ID" INT NOT NULL AUTO_INCREMENT,
"IDMATERIAL" VARCHAR(5) NOT NULL,
"NAME" VARCHAR(100) NOT NULL
);

try this,
PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
ResultSet rs = preparedStatement.getGeneratedKeys();
while(rs.next())
{
System.out.println(rs.getLong(1));
}

Related

Unknown column 'CA1001' in 'where clause'

I'm trying to fix this one for a while but can't find the or fix the code. The error triggered when I add a auto generated 'id' which is in method.
private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/inventory?useTimezone=true&serverTimezone=UTC", "root", "ichigo197328");
int row = jTable1.getSelectedRow();
String value = (jTable1.getModel().getValueAt(row, 0).toString());
String sql = "UPDATE category SET category_name = ? WHERE category_id = "+ value;
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, CategoryNameField.getText());
pstmt.executeUpdate();
DefaultTableModel model = (DefaultTableModel)jTable1.getModel();
model.setRowCount(0);
JOptionPane.showMessageDialog(null, "Record Updated Successfully ");
DisplayTable();
conn.close();
}
catch(Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
You are correctly using a prepared statement, but you should be using a positional parameter in the WHERE clause instead of concatenation:
String sql = "UPDATE category SET category_name = ? WHERE category_id = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, CategoryNameField.getText());
pstmt.setString(2, value);
pstmt.executeUpdate();
The exact cause of the error has to do with your WHERE clause comparing the category_id string column against an unescaped string literal, e.g.
WHERE category_id = some_value -- should be 'some_value'
SQL will interpret some_value as referring to a column, table, etc. name. By using a prepared statement (which you alreary are doing), you let the database handle the proper escaping of the values.

Get the inserted id of the record before or after execute the insert statement in sql

I have this method in my DAO class to insert record to a table called idea this is my method:
public long addIdea(AddIdeaDto addIdeaDto, int userId) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = getConnection();
preparedStatement = connection.prepareStatement(
"INSERT INTO IDEA ( IDEA.I_ID,IDEA.I_NO,IDEA.I_APPROVER_NAME_CODE, IDEA.I_TITLE,IDEA.I_DESCRIPITION, IDEA.I_CREATED_DATE,IDEA.I_STATUS_CODE, "
+ "IDEA.I_IS_CODE, IDEA.I_CONTRIBUTION_CODE, IDEA.I_POSITIVE_IMPACT, IDEA.I_SECOND_MEMBER_ID,IDEA.I_THIRD_MEMBER_ID,IDEA.I_FOURTH_MEMBER_ID,"
+ "IDEA.I_FIFTH_MEMBER_ID, IDEA.I_POINTS,IDEA.I_CREATED_USER_ID)"
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
preparedStatement.executeQuery("SELECT IDEA_SEQ.nextval FROM DUAL");
// Set parameters
preparedStatement.setObject(1, Types.NUMERIC);
preparedStatement.setObject(2, Types.NUMERIC);
preparedStatement.setObject(3, addIdeaDto.getApproverNameCode());
preparedStatement.setString(4, addIdeaDto.getTitle());
preparedStatement.setString(5, addIdeaDto.getDescription());
preparedStatement.setDate(6, addIdeaDto.getCreatedDate() == null ? null
: new java.sql.Date(addIdeaDto.getCreatedDate().getTime()));
preparedStatement.setObject(7, addIdeaDto.getStatusCode());
preparedStatement.setObject(8, addIdeaDto.getIsNewCode());
preparedStatement.setObject(9, addIdeaDto.getContributionCode());
preparedStatement.setString(10, addIdeaDto.getPositiveImpact());
preparedStatement.setObject(11, addIdeaDto.getSecondMemberName());
preparedStatement.setObject(12, addIdeaDto.getThirdMemberName());
preparedStatement.setObject(13, addIdeaDto.getFourthMemberName());
preparedStatement.setObject(14, addIdeaDto.getFifthMemberName());
preparedStatement.setObject(15, addIdeaDto.getPoints());
preparedStatement.setInt(16, userId);
preparedStatement.executeQuery();
return addIdeaDto.getIdeaId();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
actually what I want is after or before the insert statement I want to get the id (IDEA_SEQ.nextval) and save it in a value in order to use it as an input to insert in anther table.
For example, I insert this record : id = 1 , no = 1, approver code = 2, title = 'test'.............
I want this value id = 1 to use it in order to insert in table A, A_id = 33, IDEA.I_ID = 1, A_name ='testing'
how i can achieve it in properer way?
I update the code based on the comments that i receive but I did not achieve it
Usually ID that need to be reuse can be handle using a previous and separate SQL query
previousPreparedStatement = connection.prepareStatement(
"select IDEA_SEQ.nextval as nextval from dual");
Result saved as a int or String parameter according to column (number or varchar) which is passed to the existing insert statement:
(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
Notice also an answer from DBA forum
you won't be able to use plain SQL to overcome this limitation: you will need some PL/SQL
A better way to handle this is the RETURNING INTO clause, which uses a single, atomic statement:
INSERT INTO mytable (id, col1, col2)
VALUES ( seq_id.nextval, c1, c2 )
RETURNING id INTO myval;
You can use PreparedStatement.getGeneratedKeys() to obtain the generated value. There is no need to use a separate statement:
You also can't prefix column names with the table name in list of columns of an INSERT statement.
String insert =
"INSERT INTO IDEA ( I_ID,I_NO,I_APPROVER_NAME_CODE, I_TITLE,I_DESCRIPITION, I_CREATED_DATE,I_STATUS_CODE, "
+ "I_IS_CODE, I_CONTRIBUTION_CODE, I_POSITIVE_IMPACT, I_SECOND_MEMBER_ID,I_THIRD_MEMBER_ID,I_FOURTH_MEMBER_ID,"
+ "I_FIFTH_MEMBER_ID, I_POINTS,I_CREATED_USER_ID)"
+ " VALUES (idea_seq.nextval,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
preparedStatement = connection.prepareStatement(insertSql, new String[] {"I_ID"});
preparedStatement.setInt(1, ???); // don't know where the value for I_NO comes from
preparedStatement.setString(2, addIdeaDto.getApproverNameCode());
preparedStatement.setString(3, addIdeaDto.getTitle());
... other parameters
preparedStatement.executeUpdate();
ResultSet rs = preparedStatement.getGeneratedKeys();
long newId = -1;
if (rs.next()) {
newId = rs.getLong("I_ID");
}
... use the NewId ...
The parameter new String[] {"I_ID"} for the prepareStatement() call tells the JDBC driver to return the generated value for that column. That value can be retrieved through getGeneratedKeys() which returns a ResultSet that contains one row for each inserted row (so exactly one in this case). The ID value can then be extracted from the ResultSet using the the usual getLong() (or getInt()) methods.

how to insert incremented primary key and foreign key in java jframe tables?

I am new in java and I am trying to insert data into three tables on netbeans jframe. I already created the data on MySql
The first table contains Primary Key
create table TraineeDetals(
TraineeID smallint unsigned not null auto_increment primary key,
FirstName varchar(100) not null,
MiddleName varchar(100) not null,
LastName varchar(100) not null
)
and the other table has the foreign key
create table CollegeDetails(
collegeName varchar(100) not null,
Specialization varchar(100) not null,
TraineeID smallint unsigned not null,
constraint 'fk_Trainee'
foreign key (TraineeID) references TraineeDetails (TraineeID)
on delete cascade
on update restrict
)
Now I want to insert data by using jframe so in the java code I did this
String url="jdbc:mysql://localhost/mysql";
String user="root";
String pass="root";
private void
SaveButtonActionPerformed(java.awt.event.ActionEvent evt) {
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection(url, user,
pass);
String sql="Insert into TraineeDetails
(FirstName,MiddleName,LastName)values(?,?,?)";
PreparedStatement pst =con.prepareStatement(sql);
pst.setString(1, firstNameTextFiled.getText());
pst.setString(2, MiddleNameTextField.getText());
pst.setString(3, LastNameTextField.getText());
String sql2 = "Insert into CollegeDetails (CollegeName,
Specialization,TraineeID)values(?,?,?)";
PreparedStatement pst2 =con.prepareStatement(sql2);
pst2.setString(1, CollegeNameTextField.getText());
pst2.setString(2, SpecializationTextField.getText());
pst.setString(3, TraineeIDTextField.getText());
pst.executeUpdate();
pst2.executeUpdate();
JOptionPane.showInputDialog(this,"Insert
Successfully");
clearText();
}
catch(Exception e)
{
JOptionPane.showInputDialog(this,e.getMessage());
}
}
This code shows data only for table TraineeDetails
All data must be added from here and the id has to be auto increment.
After that, the admin can show data that he added here. Jframe shows data only for TraineeDetails table how can I fix it
Please, what I have to do to insert auto increment Primary key and foreign key and show data together after adding them? And what about my java code, is there something missing?
You can watch this video for better understanding how to do that
https://www.youtube.com/watch?v=NC6bY2oJr7s
Here is how you can do it ...
First make class lets call it sql.java and import it to your project class library
Write this code in it
import java.sql.PreparedStatment;
public class sql {
public void id_incrementtable() {
int id = 1 ;
PreparedStatment ps = null;
ResultSet rs = null ;
Conectar db = new Conectar() ;
try {
ps = db.getConnection().prepareStatement("select max(id) from your
tablename");
rs = ps.executeQuery();
while(rs.next()) (
id = rs.getint(1) + 1 ;
)
}catch(Exception ex);
System.out.printin("error"+ex.getMessage());
}
finally (
try (
ps.close();
rs.close();
db.desconectar() ;
) catch(Exception ex) (
)
}
// by running the above you will notice it add auto serial in your tablename everytime you save record on the table
// save data button code , you first define sql s = new sql() to read from that // class which been added to your project class reference
sql s = new sql();
int id = s.id_incrementable() ;
// and your place your remaining code here ... i think you got the idea

How to insert reference values in database using JDBC?

I am trying to insert values into Oracle 10g database using the code below but its giving an error of "Missing Expression" on execution. I have to pass reference values into the insert clause but do not know the exact syntax or way of doing it.
Please help me through this.
Thanks.
Student Table:-
Sid VARCHAR2(200) PRIMARY KEY CHECK(Sid>0),
Pass_word VARCHAR2(10) NOT NULL,
S_name VARCHAR2(20) NOT NULL,
G_name VARCHAR2(20) ,
Branch VARCHAR2(10) NOT NULL,
D_company VARCHAR2(20) ,
B_Percent INT NOT NULL CHECK(B_Percent<100),
twelth_percent INT NOT NULL CHECK(twelth_percent<100),
tenth_percent INT NOT NULL CHECK(tenth_percent<100),
Certify VARCHAR2(30),
Semester INT NOT NULL CHECK(Semester<9),
D_Birth DATE NOT NULL,
Sex VARCHAR2(6) NOT NULL
CODE:
Connection connection = null;
try
{
// Load the JDBC driver
String driverName = "sun.jdbc.odbc.JdbcOdbcDriver";
Class.forName(driverName);
connection = DriverManager.getConnection("jdbc:odbc:placement","siddharth","sid");
studentID = StudentID.getText();
spassword = PasswordField.getPassword();
studentname = NameField.getText();
Gname = GuardianField.getText();
branch = BranchField.getText();
dcompany = DcompanyField.getText();
bpercent = BtechField1.getText();
twelthpercent = TwelthField.getText();
tenthpercent = TenthField.getText();
semester = SemesterField.getText();
certify = CertificationField.getText();
sex = SexCombo.getActionCommand();
date = (Date) DateTextField1.getValue();
Statement stmt = connection.createStatement();
stmt.executeUpdate("insert into student " +"(sid,pass_word,s_name,g_name,branch,d_company,b_percent,twelth_percent,tenth_percent,certify,semester,d_birth,sex)"+
"values(studentID, spassword,studentname,Gname,branch,dcompany,bpercent,twelthpercent,tenthpercent,certify,semester,date,sex)" );
stmt.close();
connection.close();
}
catch (ClassNotFoundException e) {
// Could not find the database driver
JOptionPane.showMessageDialog(null,e);
}
catch (SQLException e) {
// Could not connect to the database
JOptionPane.showMessageDialog(null,e);
}
Currently your SQL statement looks like:
insert into student (sid, pass_word, ...) values (studentID, spassword, ...)
The variable names mean nothing to the SQL itself.
You should use a prepared statement. For example, your SQL should look like this:
insert into student (sid, pass_word, ...) values (?, ?, ...)
and then you use:
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, studentID);
stmt.setString(2, spassword);
// etc
See the JDBC tutorial on prepared statements for more information.
To be on the safe side you should use prepared statements.
Prepare the Query String
String updateString = "update " + dbName + ".COFFEES " +
"set SALES = ? where COF_NAME = ?";
Create a PrepartedStatement with this query:
updateSales = connnection.prepareStatement(updateString);
Fill the ? spaceholders with you values:
updateSales.setInt(1, myVariable1);
updateSales.setString(2, myVariable2);
execute the Query
updateSales.executeUpdate();

Help needed for inserting values to a mysql table

I have created a table using mysql:
CREATE TABLE JobCard (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
JobNo Long,
RegNo VARCHAR(20),
Service_Type VARCHAR(20),
Customer_Complaints VARCHAR(100)
);
in cmd.
From Eclipse, i coded for inserting the values using prepared Statement for the table. Since ID is a auto_increment, i didn't include it in the insert statement.
String Query =
"INSERT INTO JobCard (JobNo, RegNo, Service_Type, Customer_Complaints)
VALUES (?,?,?,?)";
But the output shows me :
java.sql.SQLException: Parameter index out of range
(5 > number of parameters, which is 4).
at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at
com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3717)
at
com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3701)
at
com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4552)
at
example.Connect.DoInsertIntoDB(Connect.java:40)
Can anyone please tell me how to pass the parameter list? Please help me resolve this error!!
Update:
Here is my code:
The method call is:
System.out.println(strLine);
String[] dbColumnValues = strLine.split("%");
Connect.DoInsertIntoDB(Long.parseLong(dbColumnValues[0]),dbColumnValues[1],dbColumnValues[2], dbColumnValues[3]);
The method definition:
public static void DoInsertIntoDB(Long JobNo, String RegNo, String Service_Type, String Customer_Complaints){
String Query = "INSERT INTO JobCard (JobNo, RegNo, Service_Type, Customer_Complaints) VALUES (?,?,?,?)";
try {
Connection conn = toConnect();
PreparedStatement pstmt = conn.prepareStatement(Query);
pstmt.setLong(2, JobNo);
pstmt.setString(3, RegNo);
pstmt.setString(4, Service_Type);
pstmt.setString(5, Customer_Complaints);
pstmt.executeUpdate();
pstmt.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Need to read your stack trace. In your code (on line 40 of Connect.java) you're attempting to set a value into the 5th ? but there are only 4 ?s in your prepared statement.
When you set the parameters, you are starting with 2, and it must be 1.
If you see, the last parameter is the index 5, and you don't have a 5° parameter,
Because of this java say the exception "Parameter index out of range".
You must start in 1.
PS: Sorry for my english.
Prepare statement parameter begin from 1 number, based on your code the parameter should be 1 to 4
but you ended with 5.
it cause parameter index out of range
Your try should look like this,
try {
Connection conn = toConnect();
PreparedStatement pstmt = conn.prepareStatement(Query);
pstmt.setLong(1, JobNo);
pstmt.setString(2, RegNo);
pstmt.setString(3, Service_Type);
pstmt.setString(3, Customer_Complaints);
pstmt.executeUpdate();
pstmt.close();
conn.close();
}
and that should solve the problem....

Categories