How to use generated id in SQL statement? - java

I am trying to add a new record to a table from Derby database. I need to use the record number in one of its fields. E.g. I need to save a path to the image in photo field. And the name of the image must corresponds its id. For example 1.jpg. I was trying this statement (file extention is not used in this example):
PreparedStatement pstmt = conn.prepareStatement("INSERT INTO Users (name, lastname, email, address, password, photo, lastvisit, status) VALUES ('" + name + "','" + lastname + "','" + email + "','" + address + "','" + DigestUtils.toMd5(password) + "', id, '" + now + "','user')");
But I get an error:java.sql.SQLSyntaxErrorException: Column 'ID' is either not in any table in the FROM list...
But this column definitely exists. What is the reason of the error?

Well the short answer imho is that you cannot do that in SQL.
In your table Users, I guess that your id column is an auto incremented primary key. What you can do is insert your record and then get the last id generated for this insert statement. Then you have to perform an update query to set the value of your photo column.
By the way, definitely learn to use placeholders in prepared statements
I'm not a specialist of Derby but browsing the doc I found how you can get the generated columns.
pstmt.execute(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet keys = pstmt.getGeneratedKeys();
keys.next();
int id = keys.getInt();

Related

JDBC Java, row column count mismatch

I keep getting this error
Caused by: org.hsqldb.HsqlException: row column count mismatch
I don't have idea why Im getting this error Im trying to resolve this problem from about 1 hour.
Im getting this error while Im trying to add new record to database with one user gonna make.
if(ae.getActionCommand()=="Save")
{
stmt.executeUpdate("INSERT INTO Table2 VALUES('" + t.getText() + "','" + t10.getText() + "','" + t2.getText() + "','" + t3.getText() + "','" + t8.getText() + "','" + t12.getText() + "','" + t11.getText()+"')" );
dbClose();
dbOpen();
Do not use insert in this form:
INSERT INTO TAB VALUES(1,2,'x')
but use explicit column list and bind variables:
INSERT INTO TAB (COL1, COL2, COL3) VALUES(?,?,?)
The problem you have is that the table has a different number of columns than defined in your VALUES clause.
The latter form of insert disables this problem as you explicitly defines what columns are inserted. The insert remains valid event if the table structure is compatible upgraded (add column).

Inserting a value to a Foreign key using java and database

i need some solution from my foreign key in inserting a FK ID the problem is when i insert the ID, and the Payment it will insert first Customer_ID and the second is default to null value and on next column it will set to the inserted and the other one is null here's my code
pStmt2 = conn.prepareStatement("insert into Audittrail_tbl (Customer_ID) values ((Select Name_ID from Customer_tbl where FName ='"+txtFName.getText()+"' and LName = '"+txtLName.getText()+"'))");
pStmt2 = conn.prepareStatement("insert into Audittrail_tbl (Payment) values ('"+txtPayment.getText()+"')");
pStmt2.executeUpdate();
Your code should be:
String sql = "insert into Audittrail_tbl (Customer_ID, Payment)" +
" select Name_ID, ?" +
" from Customer_tbl" +
" where FName = ?" +
" and LName = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, txtPayment.getText());
stmt.setString(2, txtFName.getText());
stmt.setString(3, txtLName.getText());
stmt.executeUpdate();
}
Or better yet, if Payment is an amount column:
// Using BigDecimal
stmt.setBigDecimal(1, new BigDecimal(txtPayment.getText()));
// Using Double
stmt.setDouble(1, Double.parseDouble(txtPayment.getText()));
Since that will parse the text to number in Java code, where you can better handle parse errors.
Note: Using insert-from-select, instead of insert-values with a subquery, will allow you to select multiple columns from Customer_tbl if needed.
You're doing two inserts, which creates two records. if you want to update the record created by the first query, you need to UPDATE for the second query instead.
And why use two queries? Why not
pStmt2 = conn.prepareStatement("
insert into Audittrail_tbl (Customer_ID, Payment)
values (
(Select Name_ID from Customer_tbl where FName ='"+txtFName.getText()+"' and LName = '"+txtLName.getText()+"'),
'"+txtPayment.getText()+"')");)");
Of course, that won't work as-is (I'm too lazy to check quote/bracket matching), but should give you the general idea.

SQL replace into only the first two columns in a row

What I currently have is this:
PreparedStatement ps = getSQLConnection().prepareStatement(
"REPLACE INTO " + table + " (uuid,name) VALUES(?,?)"
);
ps.setString(1, uuid.toString());
ps.setString(2, name.toLowerCase());
ps.executeUpdate();
However it is not setting only index 1 and 2, but instead clears the other column values. How can I insert into a row with only the first 2 indexes, and leave the other values untouched?
The table is created with this statement:
"CREATE TABLE IF NOT EXISTS data (" +
"`uuid` varchar(36) NOT NULL," +
"`name` varchar," +
"`owner` varchar," +
"`tags` varchar," +
"PRIMARY KEY (`uuid`));"
From the documentation:
REPLACE is a MySQL extension to the SQL standard. It either inserts, or deletes and inserts. For another MySQL extension to standard SQL—that either inserts or updates—see Section 13.2.5.3, “INSERT ... ON DUPLICATE KEY UPDATE Syntax”.

Writing to access database in Java?

I'm working on a database project about adding, editing and deleting registries to a Students table which has fields:
Last_names, Names, IcNumber, Average, Entry_mode, Career and Change
In the editing frame i have a field where user types the icnumber of the student to edit its data, asks for the new data and saves it to a "Students" data structure, and then reupdates the registry with the new data:
String stmnt = "Insert Into Students (Last_names, Names, IcNumber, Average, " +
"Entry_mode, Career, Change) Values ('" + student.getLastNames() +
"', '" + student.getNames() + "', '" + student.getIcNumber() + "', " +
student.getAverage() + ", '" + student.getEntry() + "', '" +
student.getCareer() + "', '" + student.getChange() + "') " +
"Where IcNumber = '" + field.getText() + "'";
statement.execute(stmnt);
And i get this Error message:
[Microsoft][Microsoft Access ODBC Driver] "Query input must contain at least one table or query."
I have tried a similar SQL Instruction in the adding registry area of my program without the "Where" condition and works good, anyone knows about that error?
You should use a subquery, first the SELECT part with WHERE and then the INSERT part
Something like:
if (cond){
(SELECT.....)
(INSERT INTO...)}
Why are you using where in a insert statement? Where clause is applicable in select, update and delete statements but not in insert. Also I don't see any need of the where clause in your query.
Simply use the insert statement without where clause.
Use an INSERT statement to add a new record. A WHERE clause does not belong in an INSERT statement.
If you're editing an existing record, then you should use an UPDATE statement, and a WHERE clause makes sense to identify which record to change.

Why am I getting: [Oracle][ODBC][Ora]ORA-00904: invalid identifier

Oracle keeps giving me an invalid identifier error when I clearly have identified the variable.
//get parameters from the request
String custID=request.getParameter("cust_ID");
String saleID=request.getParameter("sale_ID");
String firstName=request.getParameter("first_Name");
String mInitial=request.getParameter("mI");
String lastName=request.getParameter("last_Name");
String streetName=request.getParameter("street");
String city=request.getParameter("city");
String state=request.getParameter("state");
String zipCode=request.getParameter("zip_Code");
String DOB2=request.getParameter("DOB");
String agentID=request.getParameter("agent_ID");
String homePhone=request.getParameter("home_Phone");
String cellPhone=request.getParameter("cell_Phone");
String profession=request.getParameter("profession");
String employer=request.getParameter("employer");
String referrer=request.getParameter("referrer");
query =
"UPDATE customer"
+ " SET customer.cust_ID=custID, customer.sale_ID=saleID, customer.first_Name=firstName, customer.mI=mInitial, customer.last_Name=lastName, customer.street_Name=streetName, customer.city=city, customer.state=state, customer.zip_Code=zipCode,customer. DOB=DOB2, customer.agent_ID=agentID, customer.home_Phone=homePhone, customer.cell_Phone=cellPhone, customer.profession=profession, customer.employer=employer, customer.referrer=referrer"
+ " WHERE customer.cust_ID=custID " ;
preparedStatement = conn.prepareStatement(query);
preparedStatement.executeUpdate();
SQL TABLE
CREATE TABLE customer
(cust_ID NUMBER NOT NULL,
sale_ID NUMBER NOT NULL,
first_NameVARCHAR2(30) NOT NULL,
mI VARCHAR2(2) ,
last_Name VARCHAR2(50) NOT NULL,
street_Name VARCHAR2(50) ,
city VARCHAR2(30) NOT NULL,
state VARCHAR2(50) NOT NULL,
zip_Code VARCHAR2(5) NOT NULL,
DOB DATE ,
agent_ID NUMBER ,
home_Phone VARCHAR2(12) UNIQUE,
cell_Phone VARCHAR2(12) UNIQUE,
profession VARCHAR2(30) ,
employer VARCHAR2(30) ,
referrer VARCHAR2(30)
);
Your code is not doing what you think it is. Look at this:
query =
"UPDATE customer"
+ " SET customer.cust_ID=custID, customer.sale_ID=saleID, customer.first_Name=firstName, customer.mI=mInitial, customer.last_Name=lastName, customer.street_Name=streetName, customer.city=city, customer.state=state, customer.zip_Code=zipCode,customer. DOB=DOB2, customer.agent_ID=agentID, customer.home_Phone=homePhone, customer.cell_Phone=cellPhone, customer.profession=profession, customer.employer=employer, customer.referrer=referrer"
+ " WHERE customer.cust_ID=custID "
The content of query at this point is exactly what will be sent to the database. JSP will not magically fill in custID, saleID (etc...) for you before sending the query to the database. Because of this, Oracle has no sweet clue what custID is (it certainly isn't the name of some other column in the customer table). Hence, you receive the invalid identifier error.
I think you were trying to do this:
query =
"UPDATE customer"
+ " SET customer.cust_ID=" + custID + ", customer.sale_ID=" + saleID + ...
Like duffymo mentioned, this is asking for serious SQL-injection trouble (just think of the values that the client could submit in order to hijack your SQL via the custID field). The better way is to use parameters on a PreparedStatement:
query =
"UPDATE customer"
+ " SET customer.cust_ID=?, customer.sale_ID=? ...";
PreparedStatement statement = conn.prepareStatement(query);
statement.setString(1, custID);
statement.setString(2, saleID);
statement.executeUpdate();
I'd recommend not using scriplets in your JSPs. Learn JSTL as quickly as you can.
The answer seems pretty obvious: your parameters are all Strings, but the Oracle schema has some Data and Number types. You've got to convert to the correct type when you INSERT.
This code is begging for a SQL injection attack. You don't do any binding or validation before you INSERT. You couldn't possibly be less secure than this. I hope you don't intend to use this site for anything on the web.
A better approach would take the scriptlet code out of the JSP, use only JSTL to write it, and introduce a servlet and some other layers to help with binding, validation, security, etc.
I think in the sql query you have entered space in between customer,DOB.
customer. DOB=DOB2

Categories