I am receiving the following error:
HTTP Status 500 - Request processing failed; nested exception is
org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar
[SELECT id, name FROM track WHERE category_id = 1 ORDER BY name]; nested exception is
java.sql.SQLException: Column 'category_id' not found.
But when I copy and paste the very select statement listed in the error into a mysql shell, I get the result, which is expected as the table track has the column category_id.
What could be a reason for this error?
Here is the table create statement for track:
CREATE TABLE track (
id SERIAL
,name VARCHAR(50)
,category_id BIGINT UNSIGNED -- This references a serial (bigint unsigned)
,CONSTRAINT track_id_pk PRIMARY KEY (id)
,CONSTRAINT track_category_id_fk FOREIGN KEY
(category_id) REFERENCES category (id)
);
Here are some lines from my dao class regarding the track table:
private static final class TrackMapper implements RowMapper<Track> {
#Override
public Track mapRow(ResultSet resultSet, int rowNum) throws SQLException {
Track track = new Track();
track.setId(resultSet.getInt("id"));
track.setName(resultSet.getString("name"));
track.setCategoryId(resultSet.getInt("category_id"));
return track;
}
}
public List<Track> getTracks(int categoryId) {
String sql = "SELECT id, name FROM track WHERE category_id = " + categoryId + " ORDER BY name";
return jdbcTemplate.query(sql, new TrackMapper());
}
Check your SQL statement -- you need to include the category_id in the column list:
String sql = "SELECT id, name, category_id FROM track WHERE category_id = " + categoryId + " ORDER BY name";
It is failing because you're trying to extract category_id from the ResultSet and it isn't there.
Related
I want to use jdbcTemplate to create table based on another table under condition. I have postgres database. When I execute this and pass parameter:
String SQL = "create table test as (select * from users where countryId =?)";
jdbcTemplate.update(SQL, new Object[] {3})
I receive table test with all columns from users table but with no rows.
However, when I execute this:
String SQL = "create table test as (select * from users where countryId =3)";
jdbcTemplate.update(SQL)
I receive test table with rows where countryId = 3, so that is what I was expecting to receive in the first solution.
Your passing of the bind variable is not correct, but it does not play any role.
You simple can not use a bind variable in a data definition statement as you immediately see in the triggered error
Caught: org.springframework.jdbc.UncategorizedSQLException:
PreparedStatementCallback; uncategorized SQLException for SQL
[create table test as (select * from users where countryId =?)];
SQL state [72000]; error code [1027];
ORA-01027: bind variables not allowed for data definition operations
So you have two options, either concatenate the statement (which is not recommended due to the danger of SQL injection)
or split the statement in two parts:
// create empty table
sql = "create table test as (select * from users where 1 = 0)";
jdbcTemplate.update(sql)
// insert data
sql = "insert into test(countryId, name) select countryId, name from users where countryId =?";
updCnt = jdbcTemplate.update(sql, new SqlParameterValue(Types.INTEGER,3));
Note that in the insert statement you can see the correct way of passing an interger value of 3 as a bind variable.
You can follow below approach as well:-
jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS employee_tmp (id INT NOT NULL)");
List<Object[]> employeeIds = new ArrayList<>();
for (Integer id : ids) {
employeeIds.add(new Object[] { id });
}
jdbcTemplate.batchUpdate("INSERT INTO employee_tmp VALUES(?)", employeeIds);
Here you may query with 2 operations to avoid SQL injection.
You are using method update from jdbcTemplate in a wrong way.
Try with this:
String SQL = "create table test as (select * from users where countryId = ?)";
jdbcTemplate.update(SQL, 3);
I'm very new to using databases and SQL in general and I'm having some trouble figuring out a function that will allow me to display records from a table in my jdbc database based on data from other tables in the database. I will illustrate below:
Example of "DEMANDS" table (column headers, "ID" is the primary key):
NAME|ADDRESS|DESTINATION|DATE|TIME|ID
Example of "DRIVERS" table ("REGISTRATION" is the primary key):
USERNAME|PASSWORD|REGISTRATION|NAME
Example of "JOURNEY" table ("JID" is the primary key,"REGISTRATION" is a foreign key)
JID|NAME|ADDRESS|DESTINATION|DISTANCE|REGISTRATION|DATE|TIME|STATUS
Below is the code that I have that is used to display tables on a jsp file:
public String retrieve(String query) throws SQLException {
select(query);
return makeTable(rsToList());//results;
}
private void select(String query){
try {
statement = connection.createStatement();
rs = statement.executeQuery(query);
//statement.close();
}
catch(SQLException e) {
System.out.println("way way"+e);
//results = e.toString();
}
}
private String makeTable(ArrayList list) {
StringBuilder b = new StringBuilder();
String[] row;
b.append("<table border=\"3\">");
for (Object s : list) {
b.append("<tr>");
row = (String[]) s;
for (String row1 : row) {
b.append("<td>");
b.append(row1);
b.append("</td>");
}
b.append("</tr>\n");
} // for
b.append("</table>");
return b.toString();
}//makeHtmlTable
private ArrayList rsToList() throws SQLException {
ArrayList aList = new ArrayList();
ResultSetMetaData metaData = rs.getMetaData();
int count = metaData.getColumnCount(); //number of column
String columnName[] = new String[count];
for (int i = 1; i <= count; i++)
{
columnName[i-1] = metaData.getColumnLabel(i);
}
aList.add(columnName);
int cols = rs.getMetaData().getColumnCount();
while (rs.next()) {
String[] s = new String[cols];
for (int i = 1; i <= cols; i++) {
s[i-1] = rs.getString(i);
}
aList.add(s);
} // while
return aList;
} //rsToList
All of this code works fine and if I pass in a query into the "Retrieve" function such as:
String query = "select * from DRIVERS";
It will display all of the records of the "DRIVERS" table.
What I am wanting to do though, is only list drivers from the driver table that are available at the time specified in the demand (meaning their registration is not currently in a record in the journey table at the same time as the demand) If possible, I would also only like to display the "NAME" and "REGISTRATION" columns as oppose to the whole record.
I would really appreciate some help with this as I've searched around for solutions for quite some time and have not been able to work out a function that will achieve the desired outcome.
Cheers,
Creation of tables script:
-- --------------------------------------------------------
--DROP Table Demands;
CREATE TABLE Demands (
Name varchar(20),
Address varchar(60),
Destination varchar(60),
Date date DEFAULT NULL,
Time time DEFAULT NULL,
Status varchar(15) NOT NULL,
id INT primary key
);
-- --------------------------------------------------------
--DROP Table Drivers;
CREATE TABLE Drivers (
username varchar(20),
password varchar(20),
Registration varchar(10),
Name varchar(20),
PRIMARY KEY (Registration)
);
-- --------------------------------------------------------
--DROP Table Journey;
CREATE TABLE Journey (
jid INT primary key
Destination varchar(60),
Distance integer NOT NULL DEFAULT 1,
Registration varchar(10) NOT NULL,
Date date NOT NULL,
Time time DEFAULT NULL
);
The following query may answer your question.
SELECT Drivers.Name, Drivers.Registration
FROM Drivers
LEFT JOIN Journey ON Journey.Registration = Drivers.Registration
LEFT JOIN Demands ON Demands.Date = Journey.Date
WHERE Demands.id IS NULL;
This joins JOURNEY and DRIVER based on the foreign key relation. It then outer-joins DEMANDS and JOURNEY based on an implicit relation that is DATE. Finally we only keep records that fail the outer join condition.
The model has a major flaw though as the relation between DEMANDS and JOURNEY is based on a field of type Date, as far as one can tell by what your provided.
So I have a mock database for a conference where I'm creating tables for the authors, papers, reviewers, etc.
The reviewers provide an email which refers to the Program Committee emails. This is the key constraint I put in place. Then I add data to the PC table and then attempt to add data to the reviewer table. This is the error I get:
Exception encountered com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`sampledb`.`review`, CONSTRAINT `review_ibfk_2` FOREIGN KEY (`email`) REFERENCES `pcmember` (`email`))
Here are the other functions:
public int loadPCMember(){
String tablename = "pcmember";
String create = "CREATE TABLE IF NOT EXISTS pcmember(email VARCHAR(100), name VARCHAR(50), PRIMARY KEY (email));";
makeTable(create);
System.out.println("made table pcmember");
//CSV Reader
String[][] content = CSVReader(tablename,2);
for(int i = 0 ; i < content.length; i++){
try{
String query = "INSERT INTO pcmember(email,name) VALUES (?,?)";
PreparedStatement ps2 = net.prepareStatement(query);
ps2.setString(1, content[i][0]);
ps2.setString(2, content[i][1]);
ps2.executeUpdate();
System.out.println((i+1)+ " done");
// Throw exception
}catch (SQLException e){System.out.println("Exception encountered");return 0;}
}
System.out.println("PC Member Done");
return 1;
}
//Load next
public int loadReview(){
String tablename = "review";
String create = "CREATE TABLE IF NOT EXISTS review(reportid INTEGER, sdate DATE, comment VARCHAR(250), recommendation VARCHAR(6), paperid INTEGER NOT NULL, email VARCHAR(100) NOT NULL, PRIMARY KEY(reportid), FOREIGN KEY (paperid) REFERENCES paper(paperid), FOREIGN KEY(email) REFERENCES pcmember(email));";
makeTable(create);
System.out.println("made table review");
//CSV Reader
String[][] content = CSVReader(tablename,6);
for(int i = 0 ; i < content.length; i++){
System.out.println("" + content[i][0] + "\t" +content[i][1] + "\t" + content[i][2] + "\t" +content[i][3] + "\t" +content[i][4] + "\t" +content[i][5]);
try{
//SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
//java.util.Date date = sdf.parse(content[i][1]);
//System.out.println(""+date);
//Date newDate = new Date(date.getTime());
//System.out.println(""+newDate);
String query = "INSERT INTO review(reportid,sdate,comment,recommendation,paperid,email) VALUES (?,?,?,?,?,?)";
PreparedStatement ps2 = net.prepareStatement(query);
ps2.setInt(1, Integer.parseInt(content[i][0]));
ps2.setDate(2, java.sql.Date.valueOf(content[i][1]));
ps2.setString(3, content[i][2]);
ps2.setString(4, content[i][3]);
ps2.setInt(5, Integer.parseInt(content[i][4]));
ps2.setString(6, content[i][5]);
ps2.executeUpdate();
System.out.println((i+1)+ " done");
// Throw exception
}catch (SQLException e){System.out.println("Exception encountered "+ e);return 0;
}//catch (ParseException e){System.out.println("Parse Exception encountered "+e);}
}
System.out.println("Review Done");
return 1;
}
I have a decent understanding of the key constraints and I'm pretty spot on with the CSV files having the same exact emails, so what could be causing this error?
I'm a SQL guy, not a Java guy. If I ask or suggest anything that doesn't make sense because of that - you know why. To be clear - based on that error message and the sql you have included it looks like you trying to insert a record into the review table that has an email address that doesn't exist in the pcmember table thus violating the foreign key constraint on the review table. This seems like a data problem with the CVSs you are using. However since you mentioned that you are confident in the data files is it possible that the it's trying to INSERT the rows into the review table before the pcmember INSERT has successfully completed?
how to use sequence in namedparameterJDBCTemplate for insertion into two tables ?
Database- orcale
springjdbcnamedparametertemplate .
my Dao is looking like this
#Override
public void insert(Message message) {
String SQL = "INSERT into mssg (mssg_id, mssg_text, mssg_channel)"
+ " values (mssg_sequence.nextval,:mssg_text,:mssg_channel)";
String SQLMessage_app = "INSERT into message_app(mssg_app_type,mssg_id)"
+ "values(:mssg_app_type,mssg_sequence.currval)";
namedParameterJdbcTemplate.update(SQL,
new BeanPropertySqlParameterSource(message));
namedParameterJdbcTemplate.update(SQLMessage_app,
new BeanPropertySqlParameterSource(message));
}
oracle tables are these
This is the first table
create table mssg (
mssg_id number(10) NOT NULL,
mssg_text varchar2(25)NOT NULL,
mssg_channel varchar(25)NOT NULL,
constraint pk_mssg_id PRIMARY KEY(mssg_id)
);
Create sequence mssg_sequence
start with 1
increment by 1
minvalue 1
maxvalue 100000;
This is the second table
CREATE TABLE MESSAGE_APP(
mssg_app_type VARCHAR2(25),
mssg_id NUMBER(10),
CONSTRAINT fk_mssg
FOREIGN KEY(mssg_id)
REFERENCES mssg(mssg_id)
ON DELETE CASCADE);
COMMIT;
iam getting this error :
org.springframework.jdbc.UncategorizedSQLException:
PreparedStatementCallback; uncategorized SQLException for SQL [INSERT
into
message_app(mssg_app_type,mssg_id)values(?,mssg_sequence.currval)];
SQL state [72000]; error code [8002]; ORA-08002: sequence
MSSG_SEQUENCE.CURRVAL is not yet defined in this session ; nested
exception is java.sql.SQLException: ORA-08002: sequence
MSSG_SEQUENCE.CURRVAL is not yet defined in this session
can anybody help me to insert data into two tables by using sequence???
Thanks in advance :)
This is my code for executing in my java program:
public static void createBooksTablesAndSetPK() {
String selectDB = "Use lib8";
String createBooksTable = "Create table IF NOT EXISTS books (ID int,Name varchar(20),ISBN varchar(10),Date date )";
String bookTablePK = "ALTER TABLE BOOKS ADD PRIMARY KEY(id)";
Statement st = null;
try (
Connection con = DriverManager.getConnection(dbUrl, "root", "2323");) {
st = con.createStatement();
st.execute(selectDB);
st.execute(createBooksTable);
st.execute(bookTablePK);
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}
I cat use IF NOT EXIST for creating databasesand tables to prevent creating duplicate database and tables and corresponding errors.
But i don't know how prevent Multiple primary key error, because program may call createBooksTablesAndSetPK() multiple times.
Error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Multiple primary key defined
The column Book_id is not existing in your case. You are creating a table with ID as the column and then updating the table with a PRIMARY KEY constraint on a column that is not existing.
Create table IF NOT EXISTS books (ID int,Name varchar(20),ISBN varchar(10),Date date )
ALTER TABLE BOOKS ADD PRIMARY KEY(BOOK_id)
Try running these statements on a MySQL command prompt (or MySql Workbench) and the see the error.
You need change the alter table command like this.
ALTER TABLE BOOKS ADD BOOK_id VARCHAR( 255 ), ADD PRIMARY KEY(BOOK_id);