I have this database table:
create table users(
id int not null auto_increment,
fn varchar(30),
ln varchar(30),
sex char,
email varchar(60),
country varchar(40),
username varchar(30),
password varchar(100),
primary key(id)
);
When I run this code, I am getting an error: Parameter index out of range (8 > number of parameters, which is 7). I also tried changing setString(1,fn) but it's not working.
try{
String INSERT="INSERT INTO users (fn,ln,,sex,email,country,username,password) VALUES (?,?,?,?,?,?,?)";
PreparedStatement pst=conn.prepareStatement(INSERT);
System.out.println("Created prepared statement");
pst.setString(2,"fn");
pst.setString(3,"ln");
pst.setString(4,"sex");
pst.setString(5,"email");
pst.setString(6,"country");
pst.setString(7,"username");
pst.setString(8,"password)");
pst.executeUpdate();
}
you have an extra comma in your query and your column count should start from 1.
String INSERT="INSERT INTO users (fn,ln,sex,email,country,username,password) VALUES (?,?,?,?,?,?,?)";
pst.setString(1,"fn");
pst.setString(2,"ln");
pst.setString(3,"sex");
pst.setString(4,"email");
pst.setString(5,"country");
pst.setString(6,"username");
pst.setString(7,"password)");
pst.executeUpdate();
You are passing 8 columns and 7 variables, count doesn't match.
Make sure if this:
String INSERT="INSERT INTO users (fn,ln,,sex,email,country,username,password) VALUES (?,?,?,?,?,?,?)";
should be like this:
String INSERT="INSERT INTO users (fn,ln,sex,email,country,username,password) VALUES (?,?,?,?,?,?,?)";
Parameter number relative to the query
pst.setString(1,"fn");
pst.setString(2,"ln");
pst.setString(3,"sex");
pst.setString(4,"email");
pst.setString(5,"country");
pst.setString(6,"username");
pst.setString(7,"password)");
pst.executeUpdate();
Corrections:
String INSERT="INSERT INTO users (fn,ln,sex,email,country,username,password) VALUES (?,?,?,?,?,?,?)";
and
short c = 0;
//using a counter variable (short or int) means
//no worries about numbering - just maintain the order below
pst.setString(++c,"fn");
pst.setString(++c,"ln");
pst.setString(++c,"sex");
pst.setString(++c,"email");
pst.setString(++c,"country");
pst.setString(++c,"username");
pst.setString(++c,"password)");
Note: ++c is pre-increment operator. It adds 1 to the current value of c (sets c to this) and uses the new value of c.
Related
This question already has answers here:
Invalid column index using PreparedStatement
(2 answers)
Closed 4 years ago.
In JDBC with Oracle DB, I want to retrieve Employees whose first name starts with a specific letter. How can I use parameter marker "?" in a like condition? setXXX() method doesn't see it when i place it in a single quotation.
ex:
PreparedStatement ps = null;
String sql="SELECT FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES WHERE FIRST_NAME like '?%'";
ps = conn.prepareStatement(sql);
ps.setString(1, firstName);
Concatenate the bound value with the wildcard:
"SELECT FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES WHERE FIRST_NAME like ? || '%'"
You could also check the first letter explicitly with something like:
"SELECT FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES WHERE SUBSTR(FIRST_NAME, 1, 1) = ?"
but that may be less efficient (unless you add a function-based index).
The normal route is to set the % in the 'setX' call, so your query becomes SELECT FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES WHERE FIRST_NAME like ? and then .setString(1, firstChar + "%");
The alternative is as #Alex Poole answered: use WHERE FIRST_NAME like (? || '%')
NB: This answer was edited: The query included an erroneous % at the end; it has been removed.
Right now I have created a sequence and a trigger to auto increment the ID value like this:
CREATE OR REPLACE TRIGGER "RTH"."TBL_USER_TRIGGER"
BEFORE INSERT ON TBL_USER
FOR EACH ROW
BEGIN
SELECT TBL_USER_SEQ.nextval
INTO :new.USR_ID
FROM dual;
END;
ALTER TRIGGER "RTH"."TBL_USER_TRIGGER" ENABLE;
Let say I have three rows:
User ID FIRSTNAME LASTNAME
====================================
1 John smith
2 James smith
3 Pat smith
When I delete the first row(1) I want the ID values to auto correct itself to correct numbers so that second row ID values becomes 1 and third row ID values becomes 2
Is it possible in oracle? or do I have do it through code as I am using Java to insert records into table when user submits a form.
Java DAO class:
public class RegistrationDAO {
public void insert(User user) {
try {
Connection con = DBConnection.getConnection();
String query = "insert into TBL_USER(USR_FIRST_NAME,USR_LST_NAME,USR_PRIMARY_EMAIL,USR_PASSWORD) values(?,?,?,?)";
PreparedStatement pst = con.prepareStatement(query);
pst.setString(1, user.getFirstName());
pst.setString(2, user.getLastName());
pst.setString(3, user.getEmail());
pst.setString(4, user.getPassword());
pst.executeUpdate();
} catch (Exception e) {
System.out.println("####Record insertion error in Registration DAO####");
System.out.println(e);
}
}
}
The simple answer is: "No, you don't want to do that." The purpose of an id is to uniquely identify each row. A sequential id also has the feature that it provides insertion order. It is not intended to change over time. Row 1 is Row 1 is Row 1.
If you want ordering, then declare the id to be the primary key and use a query such as this:
select t.*, row_number() over (order by usr_id) as seqnum
from t;
Ideally, you should not be changing USER ID values. But still if there is requirement. Then below are the steps.
Create a procedure to reset the sequence TBL_USER_SEQ. This is needed as you are resetting the USER ID values. So after resetting, whenever you insert new record, Sequence should start with proper value ( i.e. MAX USER_ID value of the table). So that there will be no gap in USER_ID
Write Delete Trigger on table which will adjust USER_ID values.
Procedure to reset sequence
CREATE OR REPLACE PROCEDURE reset_sequence_p (p_seq IN VARCHAR2, p_new_seq NUMBER)
AS
l_value NUMBER;
BEGIN
-- Select the next value of the sequence
EXECUTE IMMEDIATE 'SELECT ' || p_seq || '.NEXTVAL FROM DUAL' INTO l_value;
-- Alter the sequnce to increment by the difference
EXECUTE IMMEDIATE 'ALTER SEQUENCE ' || p_seq || ' INCREMENT BY ' || ( p_new_seq - l_value ) ;
-- Increment to next value after diference
EXECUTE IMMEDIATE 'SELECT ' || p_seq || '.NEXTVAL FROM DUAL' INTO l_value;
-- Set the increment back to 1
EXECUTE IMMEDIATE 'ALTER SEQUENCE ' || p_seq || ' INCREMENT BY ' || 1 ;
END reset_sequence_p;
Delete Trigger
CREATE OR REPLACE TRIGGER "RTH"."TBL_USER_TRIG_DEL"
BEFORE DELETE
ON TBL_USER
FOR EACH ROW
DECLARE
v_new_user_id_seq NUMBER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
-- Update USER_ID value for all remaining records greater than USER_ID that got deleted.
UPDATE TBL_USER
SET USER_ID = USER_ID - 1
WHERE USER_ID > :old.USER_ID;
-- Retrieve max USER_ID available in table.
SELECT MAX (user_id) INTO v_new_user_id_seq FROM TBL_USER;
-- Call procedure to reset sequence
reset_sequence_p ('TBL_USER_SEQ', v_new_user_id_seq);
COMMIT;
END;
NOTE : Make sure that Primary key on table is disabled before execution of Delete statement.
I hope this helps.
public static void createLoan(Loan loan){
Connection con = null;
try {
con = JDBCConnectionFactory.getInstance().getNewConnection();
String sql = "";
sql = "INSERT INTO loan (users_id, book_id, loan_date, loan_dueDate) "
+ "VALUES (?, ?, CURDATE(), DATE_ADD(CURDATE(),INTERVAL 30))";
PreparedStatement prep = con.prepareStatement(sql);
prep.setLong(1, loan.user.getDatabaseId());
prep.setLong(2, loan.book.getDatabaseId());
Why can´t I use the DATE_ADD function to set a specific date? It just returns Null.
DATEADD Method example :
SELECT OrderId,DATEADD(day,45,OrderDate) AS OrderPayDate
FROM Orders
check this one : http://www.w3schools.com/sql/func_dateadd.asp
function Date_Add has signature DATE_ADD(date,INTERVAL expr unit) you are missing the unit.
I tried with below sample data
CREATE TABLE `person` (
`ID` INT(11) NOT NULL,
`NAME` VARCHAR(100) NOT NULL,
`loanduedate` DATETIME DEFAULT NULL
) ;
INSERT INTO person VALUES(4,'shirish',DATE_ADD(CURDATE() , INTERVAL 45 DAY));
and the insert went fine.
table has below data inserted successfully
ID NAME loanduedate
------ ------- -------------------
4 shirish 2015-06-11 00:00:00
Source
DATE_ADD(date,INTERVAL expr unit)
The date argument specifies the starting date or datetime value.
expr is an expression specifying the interval value to be added or subtracted from the starting date. expr is a string; it may start with a “-” for negative intervals.
unit is a keyword indicating the units in which the expression should be interpreted.
And for you, the problem is that unit is missing you should select it from the table of unit value, like DAY.
sql = "INSERT INTO loan (users_id, book_id, loan_date, loan_dueDate) "
+ "VALUES (?, ?, CURDATE(), DATE_ADD(CURDATE(),INTERVAL 30 DAY))";
I'm trying to insert skeleton data into a database using jdbc.
So far my code is:
Statement st=con.createStatement();
String sql = "INSERT INTO student (studentid, titleid, forename, familyname, dateofbirth) "
+ "VALUES (1, 1, 'forename1', 'surname1', '1996-06-03');";
I need to create 100 entries for this and I'm not too sure how to go about doing it.
All I want is the student id, titleid, forename and familyname to increment by 1 until it reaches 100 entries with those rows filled in, date of birth doesn't need to be altered. I'm asking how to do a loop for this
General answer - You should use PrepareStatement instead of Statement and execute as batch.
Common way to insert multiple entry or execute
String sql = "INSERT INTO student (studentid, titleid, forename, familyname, dateofbirth) "
+ "VALUES (?, ?, ?, ?, ?);";
ps = connection.prepareStatement(SQL_INSERT);
for (int i = 0; i < entities.size(); i++) {
ps.setString(1, entity.get...());
...
ps.addBatch();
}
ps.executeBatch();
Important Note:
Why you should use PrepareStatement Over Statement
SQL Injection Example
There are two ways to do this. You can put your insert query inside a loop or you can put your loop inside an insert query. I have found that the better method depends on the database engine (but I've never used postresql) and the number of records you want to insert. You could bump up against the maximun query length or number of parameters or something.
The following code sample is ColdFusion, but it is intended to show the general idea of having a loop inside a query. You would have to write equivalent code in java.
<cfquery>
insert into yourtable
(field1
, field2
, etc)
select null
, null
, null
from SomeSmalllTable
where 1 = 2
<cfloop>
union
select <cfqueryparam value="#ValueForField1#">
, <cfqueryparam value="#ValueForField#">
, etc
</cfloop>
</cfquery>
I have a fragment of code in Java which inserts data into my database.
I was advised to put AUTO_INCREMENT and give each row a unique number.
But it now gives me an error:
java.sql.SQLException: Incorrect integer value: 'DEFAULT' for column
'usersID' at row 1
I assume this is because it's casting the AUTO_INCREMENT value into a string?
How do I get around this as it's not my java program that creates the unique number, but the database itself.
pst.setString(1, "DEFAULT");
String query_to_update = "INSERT INTO `evidence_db`.`mcases` ("
+ "`PID`,"
+ "`Name`) "
+ "VALUES (?,?);";
pst.setInt(1, 0);
Above was the line that I needed. Thanks to all that tried to be helpful.