When trying to pull from an SQL database, I get in Java console.
I am able to enter my ID manually in the prepareStatement, but I can't use setString to work with with the prepareStatement.
I haven't throught of too much to try, but I did find that the issue is within the while statement. rs.next returns false when it should return true. The information in SQL has been committed, and I can call all of the information in java using a function that reads out the entire table.
getemployeeDataById("01");
private static void getemployeeDataById(String e_id) {
DBConnection dbConnection = DBConnection.getInstance();
PreparedStatement ps;
try {
ps = dbConnection.getConnection().prepareStatement("select * from employee where E_ID = ?");
ps.setString(1, e_id);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("ename"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
SQL
CREATE TABLE EMPLOYEE
(E_ID CHAR(3) PRIMARY KEY,
ENAME CHAR(25),
DOB CHAR(25),
EMAIL CHAR(25),
PHONE CHAR(25),
ADDRESS CHAR(25));
INSERT INTO EMPLOYEE
VALUES
('01','JEREMY MANN','12/23/1992','jeremy#jeremy.com','317-528-1234','123 CandyCane Lane');
I am expecting to get the name outputted in the console, so for this example it would be "JEREMY MANN." The code runs and then in the Eclipse Java console it shows Application [Java Application]. It runs into an issue within the while statement, but I'm not sure what's causing rs.next to be false.
In Oracle 11g (well, Oracle versions generally) CHAR is a fixed width type, and if you give it a value shorter than the given width, it will be padded with blanks (which might not be obvious if you just dumped the table contents). In this case, your key is length 3, but the string "01" is length 2, so that won't work.
Try VARCHAR2 for the column types, that's a variable length string.
Related
Code snippet:
On a button click, actionevent will be called
public void actionPerformed(ActionEvent e)
{
Function f = new Function();
Function is a nested class which i have used to establish the connection with the database.
The code snippet for function class is also provided in the end.
ResultSet rs = null;
String Cid ="cust_id";
String Pno="cust_phone";
String cat="cust_cat";
String start_date="st_date";
String Adv_amt="adv";
String Adv_end="end_date";
String Address="addr";
t2 is the Textfield name which i have used to get entry of customer name. I want to use this customer name as a PK to fetch all the other data about that customer from DB.
rs=f.find(t2.getText());
try{
if(rs.next())
{
t1.setText(rs.getString("cust_id"));
t3.setText(rs.getString("cust_phone"));
t4.setText(rs.getString("cust_cat"));
t5.setText(rs.getString("st_date"));
t6.setText(rs.getString("adv"));
t7.setText(rs.getString("end_date"));
t8.setText(rs.getString("addr"));
}
else
JOptionPane.showMessageDialog(null,"No data for this name");
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null,ex.getMessage());
}
}
Here is the code snippet for nested class Function which is inside the main class:
class Function{
Connection con=null;
ResultSet rs= null;
PreparedStatement ps = null;
public ResultSet find(String s)
{
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection("jdbc:oracle:thin:#Localhost:1521:xe","system","qwerty");
ps= con.prepareStatement("Select * from gkkdb where cust_name='?'");
ps.setString(1,s);
rs= ps.executeQuery();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
return rs;
}
}
Please help figure out the problem.
Don't put the parameter placeholder ? in single quotes.
This:
ps = con.prepareStatement("Select * from gkkdb where cust_name='?'");
should be
ps = con.prepareStatement("Select * from gkkdb where cust_name = ?");
The ? is not recognized as a placeholder if you enclose it in single quotes.
Sorting out the bind variable will fix your immediate issue.
You should explicitly specify what columns you want selected and that way you'll only get what you need (someone might add a BLOB column later) and you'll get them in the right order (someone might change the table create script before running on another DB instance, although you are looking up the columns by name, a different order would only impact if you were using positional indexes).
Ditto on the other answer re: bind variables (i.e. no quotes)
Plus, "select * from" is never a good idea, ask your DBA.
Obviously your code is for example, but you should make sure you free up any resources (Connection, Statement, ResultSet) as soon as they are done with. Use Java 7 try-with-resources.
I created a Stored Procedure where I can select the column that I address in my Stored Procedure via Callable Statement. I tried to use SELECT SECTION NAME FROM allsections_list WHERE SECTION_NAME = ? Similar to syntax of Prepared Statement but I think its not compatible using this syntax. I'm just new learning this mysql.
Stored Procedure
CREATE STORED PROCEDURE getSECTION_NAME(OUT SECTION_NAME VARCHAR)
SELECT SECTION_NAME FROM allsections_list
Code
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
String searchSection = Section_SearchSection_Textfield.getText();
String searchSection_Name = Section_SectionName_TextField.getText();
if (searchSection.isEmpty())
{
JOptionPane.showMessageDialog(null, "Please fill up this fields");
}
else
try (Connection myConn = DBUtil.connect();
CallableStatement myCs = myConn.prepareCall("{call getSECTION_NAME(?)}"))
{
myCs.setString(1, searchSection_Name);
try (ResultSet myRs = myCs.executeQuery())
{
int resultsCounter = 0;
while (myRs.next())
{
String getSection_Name = myRs.getString(1);
Section_SectionName_TextField.setText(getSection_Name);
resultsCounter++;
}
}
}
catch (SQLException e)
{
DBUtil.processException(e);
}
When I search a records. If the records exist it the value will print out to the textfields. But it doesn't print out. And it throws me a error getSECTION_NAME does not exist. What if I want select multiple values? Because I'm having a project where I'm making a Enrollment System. I choose this Stored Procedure specially than Batch Statement based on what I read. Any help will appreciate. Thanks!
I don't use MySql, but here's a similar example in Oracle (I think this Works in MySql as well).
CREATE PROCEDURE get_section_name(OUT secName VARCHAR(100))
BEGIN
SELECT SECTION_NAME INTO secName FROM allsections_list WHERE some_condition = 100; //your procedure does not use any input arguments if you want to return just one record then you'll probably need to specify a where clause
END
/ //when executing a stored procedure in a DB client you will need to specify a terminator character (in this case slash /)
Note that there's no return statement because we're using OUT parameters.
The getOutValueForStoredProcedure method calls the stored procedure and retrieves the out value.
public String getOutValueForStoredProcedure(String procedureName, int sqlType) throws EasyORMException{
String out=null;
CallableStatement stmt=null;
try{
//out parameters must me marked with question marks just as input parameters
sqlQuery = "{call " + procedureName +"(?)}";
stmt=conn.prepareCall(sqlQuery);//I assume that a Connection has been created
stmt.registerOutParameter(1, sqlType);
stmt.execute();
out = stmt.getString(1);//you get the out variable through the Statement, not the ResultSet
}catch(Exception e){
//log exception
}finally{
//close stmt
}
return out;
}
To call this stored procedure, you can use
String out = getOutValueForStoredProcedure("get_section_name", java.sql.Types.VARCHAR);
For creating stored procedures in MySql , check this link http://code.tutsplus.com/articles/an-introduction-to-stored-procedures-in-mysql-5--net-17843
For a more elaborate example, check this http://www.mkyong.com/jdbc/jdbc-callablestatement-stored-procedure-out-parameter-example/
Here is my stored procedure:
CREATE OR REPLACE PROCEDURE VIEWBROKERS
(o_username OUT USERS.USERNAME%TYPE)
AS
BEGIN
SELECT USERNAME
INTO o_username
FROM USERS
WHERE Role_ID = 3 ;
END VIEWBROKERS;
Here is my method calling the stored procedure:
public ResultSet pullBrokers() {
ResultSet rs = null;
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection(Messages.getString("OracleUserManagement.0"), Messages.getString("OracleUserManagement.1"), Messages.getString("OracleUserManagement.2")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String storedProcedure = "{call VIEWBROKERS(?)}";
CallableStatement statement = con.prepareCall(storedProcedure);
statement.registerOutParameter(1, java.sql.Types.VARCHAR);
rs = statement.executeQuery();
con.commit();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
And lastly when I tried to print out the results:
public class TEST {
public static void main(String[] args) throws SQLException{
OraclePullListOfUsers pull = new OraclePullListOfUsers();
ResultSet rs = pull.pullBrokers();
try {
while (rs.next()){
System.out.println(rs.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
I get the error message ORA-01422: exact fetch returns more than requested number of rows
Which is strange ,because there are only two rows of data in the table...
If someone could point me in the right the direction, that would be awesome!
Looks like you're problem is not related to Java, just on the SQL side. Could it be that both those two rows in the table have Role_ID=3?
The root cause for your problem:
ORA-01422: exact fetch returns more than requested number of rows
is that PL/SQL select into statement expects a query to match to exactly one row. If the query returns no rows or if the query return more than one row (as in your case) it will throw an exception.
You can't use select into to save the results to a single out variable if the query can return more than one row. Instead your subprogram should return a cursor (that is a pointer to a record set) that your Java component can query. Note that returning a cursor is not the only option, but in your case it looks like a good starting point.
This issue has been addressed several times in StackExchange universe. Please take a look e.g.
Return many rows on a plsql Oracle10g
How to return multiple rows from the stored procedure? (Oracle PL/SQL)
Calling Oracle PL/SQL stored procedure from java middle tier using JDBC on Linux?
A Java example Using Ref Cursors To Return Recordsets.
This is a small part of the application where user can register any number of employees and employee id is generated by using a while loop....As i close the application & start filling the data again in second round...the value of employee id empid resets to zero. Well, as long as the application is running, i get the desired o/p i.e. a unique id is allotted to every employee. I dont want empid's value to start from 0 whenever i start the application. Need alternatives and/or any modification. Code is provided here
int empcount=0;
public void actionPerformed(ActionEvent ae) {
//---------------------If user wants to add data
if(ae.getActionCommand()=="ADD EMPLOYEE") {
System.out.println("ADDING");
try{
empcount=empcount+1;//----------------will assign employees with unique emp id
//--------------------returns the text in name field to variables
String s_name=name.getText();
int s_code=empcount;
String s_dept=dept.getText();
String s_ph=ph.getText();
String s_bg=bg.getText();
String s_add=add.getText();
String s_date=date.getText();
PreparedStatement st=null;
Connection con = null;
Class.forName("org.hsqldb.jdbcDriver");
con = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/", "SA", "");
st=con.prepareStatement("Insert into EmpReg (emp_name,emp_code,emp_ph,emp_bg,emp_add,emp_date,b_id) values(?,?,?,?,?,?,?)");
//---------------------parameters and respective values, passed to the SQL statement
st.setString(1,s_name);
st.setInt(2,s_code);
st.setString(3,s_ph);
st.setString(4,s_bg);
st.setString(5,s_add);
st.setString(6,s_date);
st.setString(7,s_dept);
st.execute();
JOptionPane.showMessageDialog(null,"Data is inserted into the database");
JOptionPane.showMessageDialog(code, "employee code"+ empcount+"");
con.close();
}
catch(Exception Ee){
System.out.println(Ee);
}
}
}
});
The standard SQL way of doing this, is having an "autoincrement" primary key (emp_code), for hsqldb see IDENTITY.
In the SQL INSERT statement leave out the primary key. Now the database generates a unique new key.
After the execution, you can retrieve the generated primary key from the statement with getGeneratedKeys.
This ensures that two parallel processes will not mess up the primary keys.
Why don't you create a field in your DB, that is set to autoIncrementTrue and maybe use it as ID as well. You can also use this field as Employee-Number.
You can check this Link for more Information: http://www.w3schools.com/sql/sql_autoincrement.asp
The generated number will increment every time you insert a new Employee.
You could use a DB like Oracle, MySQL, PostGre and use a Sequence or auto generated ID Column to do that for you
My problem is i have set a table auto commit false. I need to get the max id from that table(the currently inserted value of auto increment id). But i am getting the id of the previous committed process. Is it possible to get the value
My real problem is i need to insert into table some values, And need to take the id of the last inserted record from the first table and insert it to the second. The second insertion includes some image upload as well(as part of the code). so it take some delay or can have exceptions. I need to undo all insertions(both in the first and second) by occurring any exceptions. I tried to use commit-roll back method for this. But its not properly working as i mentioned above. main portion of my code is written below
try
{
//getting connection and setting auto commit false
dbHandler dbGetConnect=new dbHandler();
Connection conRegPlot=null;
conRegPlot=dbGetConnect.getconn();
conRegPlot.setAutoCommit(false);
String qryInsertPlot="INSERT INTO property_table(name,message,owner,locality,lattitude,longitude,country,state,city,type,catagory,created,modified,creted_date,zoompoint,mob_no,title,img_path,expire_date,lease_term) VALUES('none','"+description+"','"+sessionUserId+"','"+locality+"','"+lattitude+"','"+longitude+"','"+country+"','"+state+"','"+city+"','"+type+"','"+catagory+"',NOW(),NOW(),CURDATE(),'"+zoom+"','"+mob_no+"','"+title+"','NOT IN USE',"+expireDate+",'"+termsAndConditions+"')";//insertion into the first table
Statement stCrs=conRegPlot.createStatement();
int resp=stCrs.executeUpdate(qryInsertPlot);
String qryGetMaxProperty="SELECT MAX(l_id)"+
" FROM property_table"+
" WHERE stat='active'"+
" AND CURDATE()<=expire_date";
propertyId1=dbInsertPropert.returnSingleValue(qryGetMaxProperty);// get the max id
String qryInsertImage="INSERT INTO image_table(plot_id,ownr_id,created_date,created,modified,stat,img_path) VALUES('"+propertyId1+"','"+sessionUserId+"',CURDATE(),NOW(),NOW(),'active','"+img_pth+"')";
Statement stImg=conRegPlot.createStatement();
stImg.executeUpdate(qryInsertImage);// inserting the image
conRegPlot.commit();
}
catch(Exception exc)
{
conRegPlot.rollback();
}
finally{
conRegPlot.close();
}
Since
And need to take the id of the last inserted record from the first
table and insert it to the second.
You could the use of the new JDBC 3.0 method getGeneratedKeys() for get the generated ID. In ahother hand, you should use PreparedStatement for avoid SQL Injection.
PreparedStatement ps = null;
try {
conn = getConnection();
ps = conn.prepareStatement(myQuery, PreparedStatement.RETURN_GENERATED_KEYS);
ps.setInt(1, anInteger);
...
int rows = ps.executeUpdate();
if (rows == 1) {
ResultSet keysRS = ps.getGeneratedKeys();
if (keysRS.next())
int id = keysRS.getInt(1) // Get generated id
For MySQL, see more in http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-last-insert-id.html#connector-j-examples-autoincrement-getgeneratedkeys