Why do I get ORA-01438 error - java

I have an EMPLOYEE table with column(primary key) EMPLOYEE_ID NUMBER(6)
And the following method to check whether an employee record exists in the table
public boolean exists(int employeeId) {
Connection con = ConnectionManager.getConnection();
boolean exists = false;
String stmt = "select EMPLOYEE_ID , FIRST_NAME , LAST_NAME , EMAIL , PHONE_NUMBER ,"
+ "HIRE_DATE , JOB_ID , SALARY , COMMISSION_PCT , MANAGER_ID , DEPARTMENT_ID "
+ " FROM EMPLOYEES where cast (EMPLOYEE_ID as Number(2)) = ?";
PreparedStatement pstmt = null;
try {
pstmt = con.prepareStatement(stmt);
pstmt.setInt(1, employeeId);
pstmt.execute(); //Returns true if the first object that the query returns is a ResultSet object
exists = pstmt.getResultSet().next();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
pstmt.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return exists;
}
Now, in the SQL statement when I use cast (EMPLOYEE_ID as Number(2)) = ? and call the exists method with input 2 employeeOperations.exists(2); I get the following error
ORA-01438: value larger than specified precision allowed for this column
Why does this error occur, even when the size of the column is large enough?
It works well with input of 4 digits or more(maximum length of employee_id present in table is 4) i.e. cast (EMPLOYEE_ID as Number(4)) = ? works.

When casting from NUMBER(6) to NUMBER(2), the records having EMPLOYEE_ID greater than 99 are causing the error (for example Oracle cannot put 100 in \d{2}).
Quick fix, use this request:
SELECT COUNT(1) FROM EMPLOYEES WHERE EMPLOYEE_ID = ?

Related

How to add integer and Varchar(20) and store as Varchar(20) in mysql

I have db named spareparts in which all values are stored as varchar(20).
I am taking input from the user through jtextfield as a number then convert into integer.
s1(which is itemcode) and s2(which is quantity to be added to actual quantity) are the input Now I want to add this input into 'quantity'(which is also varchar) as:
public class AddStockDAO{
Connection connection;
PreparedStatement preparedStatement;
ResultSet resultSet;
Statement statement;
public AddStockDAO(String s1,String s2)
{
int num=Integer.parseInt(s2);
String sql= "select "+
" cast(quantity as INT) from spareparts"+
"set quantity+= "+num+
" cast(quantity as varchar(20))"+
"where itemcode='?'";
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "")) {
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, s1);
stmt.executeUpdate();
}
} catch (SQLException ex) {
Logger.getLogger(AddProductGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
If I understand the problem correctly, you want to update the record in the DB according to the itemcode. So you just cast the existing value to number, add your additional value (with +) and cast it back.
int num = 0;
try {
num = Integer.parseInt(s2);
} catch (Exception e) {
System.out.println('Nope, that was not a number');
//Do something else?
}
String insertQuery = "UPDATE spareparts SET quantity = cast(cast(quantity as integer)+"+num+" as char(20)) where itemcode = "+s1+";";
try {
connection = DriverManager.getConnection(...); //add your data
preparedStatement = connection.prepareStatement(sql)
preparedStatement.executeUpdate();
} catch (Exception e) {
//Something broke
}
Also - You should use the class variables you've defined at the top of your class, so you don't have to recreate the connection later on.
But If you add more AddStockDAO, each of them will create new connection, so I'd suggest you create a database class where you setup a connection and just pass some data or a query to a method to run it on the existing connection.
I would not recommend this. How would you know if an Integer + Varchar(20) is more than 20 characters?
As #Connor has said, there is no way to make sure the result is less than 20 characters, so using a BigInteger field is much better, but if the field MUST be a varchar(20), I would recommend selecting that field from the database, doing the addition in java, and then storing the result back in the database.

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.

SQLEXCEPTION : Bad value for type long

EDIT: I fixed the insert off by one mistake so I deleted that part of the question but still have the Bad value for type long error.
EDIT: the create statement for the small company table
create table small_company
(
first_name varchar(20),
last_name varchar(30),
address text,
emp_id serial not null
)
;
Created from:
create table company
(
first_name varchar(20),
last_name varchar(30),
company_name text,
address text,
city varchar(30),
province text,
postal varchar(7),
phone1 text,
phone2 text,
email text,
web text
)
;
create index name_priority
on company (first_name)
;
I'm getting this error saying "Bad value for type long :"
// insert values into the "small_company" table
long insertEmp(String first_name, String last_name, String address) {
String sql = "insert into small_company values (?,?,?)";
long id = 0;
try {
Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1,first_name);
pstmt.setString(2,last_name);
pstmt.setString(3,address);
int affectedRows = pstmt.executeUpdate(); // returns number of affected rows
if (affectedRows > 0) { // means a row was affected so get the ID
try {
ResultSet rs = pstmt.getGeneratedKeys();
if (rs.next()) {
id = rs.getLong(1); // if cursor finds row with id, return it
}
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
}
}
catch (SQLException e){
System.out.println(e.getMessage());
}
return id;
}
public static void main(String[] args) {
Queries q1 = new Queries();
//q1.getRowCount("company");
//q1.displayTable();
//q1.displayCompany(); // <- what I use to display table!
//q1.findEmployee(10);
q1.insertEmp("Laura","Lane","Daily St. Planet co. NE"); //<-what I use to insert!
}
All help is greatly appreciated!
The first column in small_company is first_name and you can't use getLong() on a varchar column. You have to use getLong("emp_id") instead.
Alternatively you can tell the JDBC driver to only return the emp_id:
PreparedStatement pstmt = conn.prepareStatement(sql,new String[]{"emp_id"});
Then getLong(1) should work as well as only one column is returned (at least with an up-to-date JDBC driver).

stored procedure returns just one row of multiple rows

I will start by giving you my table content
This is my stored procedure:
ALTER PROCEDURE dbo.getFoodsForOrder
(
#orderID INT,
#ID INT OUTPUT,
#food_restaurantID INT OUTPUT,
#count INT OUTPUT,
#description VARCHAR(200) OUTPUT
)
AS
SET NOCOUNT ON
BEGIN
SELECT [ID],
[food_restaurantID],
[count],
[description]
FROM Order_Food
WHERE orderID = #orderID
END
My Problem
when I call the stored procedure from JDBC like this
Connection con = Database.getConnection();
CallableStatement callableStatement = null;
try {
callableStatement = con
.prepareCall("{call getFoodsForOrder(?,?,?,?,?)}");
callableStatement.setInt(1, getID());
callableStatement.registerOutParameter(2, java.sql.Types.INTEGER);
callableStatement.registerOutParameter(3, java.sql.Types.INTEGER);
callableStatement.registerOutParameter(4, java.sql.Types.INTEGER);
callableStatement.registerOutParameter(5, java.sql.Types.VARCHAR);
System.out.println("ID = " + getID());
boolean haveResult = callableStatement.execute();
while (haveResult) {
System.out.println("here I am");
haveResult = callableStatement.getMoreResults();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (callableStatement != null)
callableStatement.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
it just print here I am once, just once, even If (like the picture said) I have more than 15 rows are ture.
you problem will ask me if I am sure about the getID() method, Yes I am sure and even when I replace it with explicit 10 , the result doesn't change.
Something might help
when I call that stored procedure from my Visual studio , I got 17 results like this:
Any help will be appreciated
The callableStatement.execute() indicates if a result set is available.
getMoreResults() only indicates if there are is another ResultSet available, not if the "last" result set has more rows (which is - I think - pretty clear from the JavaDocs). getMoreResults() would return true if you had more than one select statement in your procedure.
If execute() indicates a ResultSet is available you need to obtain it using callableStatement.getResultSet() and then iterate over the rows returned by that.
Something like:
boolean haveResult = callableStatement.execute();
if (haveResult) {
ResultSet rs = callableStatement.getResultSet();
while (rs.next()) {
System.out.println(rs.getInt(1));
}
} else {
System.out.println("Nothing returned");
}
But as you know it returns a result set you can also call getResultSet() right away without even bothering about the return value of the execute() call.
You need to remove the OUTPUT variables from your stored procedure and no longer register them in your code. You then need to use executeQuery() to get the resultset and iterate over the resultset to get rows.
Assuming a table structure of:
CREATE TABLE [dbo].[Order_Food](
[ID] [int] IDENTITY(1,1) NOT NULL,
[OrderID] [int] NULL,
[food_restaurantID] [int] NULL,
[count] [int] NULL,
[description] [nvarchar](255) NULL,
CONSTRAINT [PK_Order_Food] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Table content:
INSERT INTO [dbo].[Order_Food]
([OrderID], [food_restaurantID], [count], [description])
VALUES (513, 2, 3, 'Description xyz'), (513, 2, 3, 'Description xyz'),
(132, 1, 2, 'Description abc');
A stored procedure as:
CREATE PROCEDURE dbo.getFoodsForOrder
(
#orderID INT
)
AS
SET NOCOUNT ON
BEGIN
SELECT [ID],
[food_restaurantID],
[count],
[description]
FROM Order_Food
WHERE orderID = #orderID
END
And query code as:
public static void main(String[] args) throws SQLException {
try (
Connection con = DriverManager.getConnection("jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=Scratchspace;integratedSecurity=true");
CallableStatement callableStatement =
con.prepareCall("{call getFoodsForOrder(?)}");
){
callableStatement.setInt(1, 513);
System.out.println("ID = " + 513);
ResultSet rs = callableStatement.executeQuery();
while (rs.next()) {
System.out.printf("%d %d %d %s%n",
rs.getInt("ID"), rs.getInt("food_restaurantID"),
rs.getInt("count"), rs.getString("description"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
On my computer this produces the output:
ID = 513
1 2 3 Description xyz
2 2 3 Description xyz

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();

Categories