I have two tables linked by another table like this:
ROLES(RoleID, RoleName)
EMPLOYEES(EmployeeID, E_Name, Address)
ROLE_EMPLOYEES(RoleID#,EmployeeID#).
I want a query that retrieves all from EMPLOYEES and RoleID from ROLES and displays on Java form.
I have tried this but does not work:
rs=st.executeQuery("SELECT EMPLOYEES.*, ROLES.* FROM EMPLOYEES JOIN ROLES");
while(rs.next()){
//MOVE THE CURSOR TO THE FIRST RECORD AND GET DATA
int employeeid=rs.getInt("EmployeeID");
String id=Integer.toString(employeeid);
String name=rs.getString("E_Name");
String addr=rs.getString("Address");
String s = rs.getString("RoleID");
jComboBox1.addItem(s.trim());
//DISPLAY THE FIRST RECORD IN THE TEXT FIELD
txtEmpNumber.setText(id);
txtEmpName.setText(name);
txtEmpAddress.setText(addr);
jComboBox1.setSelectedItem(s);
}
You may try this:
SELECT
EM.*, RL.*
FROM
EMPLOYEES EM
INNER JOIN
ROLE_EMPLOYEES REM ON REM.EmployeeID = EM.EmployeeID
INNER JOIN
ROLES RL ON RL.RoleID = REM.RoleID
Just by writing the keyword JOIN the db-engine does not know in which way it should join the data of the tables; unless you want to retrieve a cartesian product (that's not your case), you need to explicitly set the criteria by using the ON clause.
Related
I have to insert data into two tables department and employee one by one through java code. Each table has one common column dept_id which is primary key in department table and foreign key in employee table and refers from dept_id column of department table. there is one sequence dept_sequence defined on dept_id in department table.
Now, my current approach to insert data into both these tables is as below,
I use dept_sequence.nextval and dept_sequence.currval respectively for dept_id column to insert data into both these tables.
Map<String, Object> deptData = ImmutableMap.builder()
.put("DEPT_NAME", "TEXTILE")
.put("LOCATION", "PARIS")
.build();
String insertToDeptSql = "INSERT INTO DEPARTMENT(DEPT_ID, DEPT_NAME, LOCATION)
VALUES(dept_sequence.nextval, :DEPT_NAME, :LOCATION)";
namedParameterJdbcTemplate.update(insertToDeptSql , deptData);
Map<String, Object> empData = ImmutableMap.builder()
.put("EMP_NAME", "John")
.put("AGE", 15)
.build();
String insertToEmpSql = "INSERT INTO EMPLOYEE(EMP_ID, DEPT_ID, EMP_NAME, AGE)
VALUES(emp_sequence.nextval, dept_sequence.currval, :EMP_NAME, :AGE)";
namedParameterJdbcTemplate.update(insertToEmpSql, empData);
It works perfectly fine when there is one single transaction at a time. both the tables have correct dept_id values but it breaks in multi-transactional environment. the employee table do not receive same value of dept_sequence which is inserted in department table for one transaction. before inserting record into employee table, dept_sequence value is increased by a different transaction(new record insert into department table) which might be happening in a different system and employee table receive some increased value of sequence.
How we can implement this in such a way that the dept_id value remains same for in both the tables for same transaction.
NOTE: Actual data models are different, employee and department are just for example purpose so don't suggest any changes in the models and primary key, foreign key constraints as I am not allowed to do anything with actual model.
String insertToDeptSql = "INSERT INTO DEPARTMENT(DEPT_ID, EMP_ID, EMP_NAME, DEPT_NAME, LOCATION)
VALUES(dept_sequence.nextval, emp_sequence.currval, :EMP_NAME, :DEPT_NAME, :LOCATION)"
If your primary key constraint is on (dept_id, emp_id), then theoretically, you could run a separate SQL query to get dept_sequence.nextval, then pass the same value into each insert. But that is a very... unconventional use of sequences and I think there are simpler approaches.
I recommend re-evaluating the data model.
Your department table isn't storing departments. It's storing relationships of employees to departments. If employee A and employee B are in the same department, you don't have 2 departments.
What I would suggest you do is put a dept_id column on the employee table and then on the department table, drop the employee-related columns.
You'd end up with something like this:
Map<String, Object> deptData = ImmutableMap.builder()
.put("DEPT_NAME", "MECH")
.put("LOCATION", "PARIS")
.build();
String insertToDeptSql = "INSERT INTO DEPARTMENT(DEPT_ID, DEPT_NAME, LOCATION)
VALUES(dept_sequence.nextval, :DEPT_NAME, :LOCATION)";
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection
.prepareStatement(INSERT_MESSAGE_SQL);
ps.setString(1, message);
return ps;
}, keyHolder);
}
long departmentId = keyHolder.getKey().longValue();
Map<String, Object> empData = ImmutableMap.builder()
.put("EMP_NAME", "John")
.put("AGE", 15)
.put("DEPARTMENT", departmentId)
.build();
String insertToEmpSql = "INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, AGE, DEPARTMENT)
VALUES(emp_sequence.nextval, :EMP_NAME, :AGE, :DEPARTMENT)";
jdbcTemplate.update(insertToEmpSql, empData);
You can repeat the last section for each employee of a department and reuse the departmentId.
As Brandon has said, your data model isn't great. But to answer the question you're actually asking, basically, "How do I capture the just-inserted id value?" you use the RETURNING INTO clause for your first insert:
INSERT INTO EMPLOYEE(EMP_ID, EMP_NAME, AGE)
VALUES(emp_sequence.nextval, :EMP_NAME, :AGE)
RETURNING EMP_ID INTO :x
In PL/SQL this is pretty trivial. To do it through JDBC, this is captured slightly differently, though getGeneratedKeys(). See Oracle's RETURNING INTO usage in Java (JDBC, Prepared Statement)
Similar situation we handled as below
Get next sequence value of 'dept_sequence' into a variable, for example X
Use X in parent table as well as child table insert statements. Ensure both inserts are under single transaction scope
This will be clean and easy to manage parallel executions.
I have two tables in my database.One is called
Table_join and it has fields
ID , NameOfObject,Address,Date
The second table is called Connection,and it has fields:
ID,IDofGroup,IDofSubgroup.
When I am inserting new record,It can be an object without a subgroup,something like Object1 on on its own,or it can be an Object2, and Object21 that is a subgroup of Object2 - in that case in the second table Connection I would insert id of the Object2 into IDofGroup,and ID of the Object21 into IDofSubgroup.
I want to search my table,so for example when I type in Object2,in the table I wanna see Object2 and its address and date,and Object21 and its date address.When I use inner join,I only get Object21 when I search Object2,not Object2 itself.
also,when I use inner join,i only get id from object21,I need to get the name also.
My select query is
String query = "SELECT * from table_join INNER JOIN connection ON table_join.id = connection.id_IDofSubgroup WHERE NameOfObject=?";
Both Object2 and Object21 are stored in the Table_join table. That means you need to look at two different record from that table at the same time. That means you need that table in the FROM/JOIN clause twice.
Since you're returning two rows from the same table at the same time, your column names will clash, so you have to rename them in the query.
SELECT t1.ID AS MainID
, t1.NameOfObject AS MainName
, t1.Address AS MainAddress
, t1.Date AS MainDate
, t2.ID AS SubID
, t2.NameOfObject AS SubName
, t2.Address AS SubAddress
, t2.Date AS SubDate
FROM Table_join t1
JOIN Connection c ON c.IDofGroup = t1.ID
JOIN Table_join t2 ON t2.ID = c.IDofSubgroup
WHERE t1.NameOfObject = ?
i have a criteria like
public ArrayList<Student>getStudentsWithPicture(final Student student)
{
final Criteria criteria = session.createCriteria(Student.class).add(and(prepareForSelect()));
criteria.add(Subqueries.gt(1L,getDetached);//the students with a less added picture...
return new ArrayList<Student>(criteria.list());
}
i need the students with a less a picture in the table Pictures but this Database is a legacy one
they store the pictures concatening some fields for the student entity
yes a quite weird
i want something like this
SQL
select
this_.ID as y0_,
this_.C01 as y1_,
this_.C02 as y2_,
this_.C03 as y3_
from
student_table this_
where
(
and this_.C11=true
and 1>=
(
select
count(*)
from
PICTURE_TABLE this_
where
(
this_.C03='concatening'+ this_.ID+ this_.C01+this_.C02+this_.C03//the fields of the student
)
)
)
this is just a understandable example the actual query is a lot worse...
as you can see i want the students with status='true' and they have a less one match on the PICTURE_TABLE but the field C03 from the table is created by concatening the fields of the Student which i have retrieve it as well...
my detached
public DetachedCriteria getWithDetachedMatchStudentWithPictures()
{
final String concatedFields = ...........how i accomplish this??????.................
final DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Pictures.class)
.add(equals("c03",concatedFields))
.setProjection(addProjection("id"))
.setResultTransformer(transformer(Pictures.class));
return detachedCriteria;
}
my question is.
can i concate the fields at runtime..?? using Criteria A.P.I
there is some approach?
thanks a lot
Yes, we can contact multiple columns run time in hibernate.
i have concat columns in my beloved query.
Query query = session.createQuery("SELECT DISTINCT f.fileid , f.filename, f.filetype , f.folderpath , max(f.version) from FileBean f GROUP BY concat(folderpath,filename,'.',filetype)");
result = query.list();
I am trying to access a data in a table using a sub query.
The table 1 contains a foreign key to table 2 , which means i can use that key to access the data in table 2.
My problem is after i return the array list from the below shown method , the arraylist is null.
This is what i have done:
LogEntry logBookDates;
List<LogEntry> bookList =new ArrayList();
try{
PreparedStatement getSummaryStmt=con.prepareStatement("SELECT * FROM LOGENTRYTABLE WHERE DIARYCODE =(SELECT Diarycode FROM LOGBOOKTABLE WHERE STUDENTUSERNAME=? OR SUPERVISORUSERNAME=? AND PROJECT_APPROVE_STATUS=?)");
//the above statment is the sub query which i have created, i get the diary code from log book table and then access the log entry table.
getSummaryStmt.setString(1,userName);
getSummaryStmt.setString(2,userName);
getSummaryStmt.setString(3,"Accepted");
ResultSet rs=getSummaryStmt.executeQuery();
while(rs.next())
{
logBookDates=new LogEntry(rs.getString("STUDENTUSERNAME"),rs.getString("SupervisorUsername"),rs.getString("projecttitle"),rs.getString("projectDescription"),rs.getDate("startDate"),rs.getDate("enddate"),rs.getString("project_approve_status"),rs.getString("diarycode"),rs.getString("projectcode"),rs.getInt("Index"),rs.getString("log_Entry"),rs.getDate("logentry_date"),rs.getString("supervisor_comment"),rs.getString("project_progress"));
bookList.add(logBookDates);
}
}catch(Exception e){}
return bookList;
}
I have not used sub queries before and this is the first time am using them.
What seems to be the problem here ?
Thank you for your time.
Edit : Sample data of logbook table
Sample Data of logentry table
Expected output:
I don't have a screen shot of that but what i need is just to iterate through the arraylist which will be returned from the above method.
Here is the problem, the LOGENTRYTABLE table doesn't contain a column with STUDENTUSERNAME, SupervisorUsername, projecttitle, projectDescription, startDate, etc...
rs.getString("STUDENTUSERNAME"), rs.getString("SupervisorUsername"), etc...
probably, you need JOIN query
"SELECT * FROM LOGENTRYTABLE LT
INNER JOIN LOGBOOKTABLE LB ON LT.DIARYCODE=LB.DIARYCODE
WHERE LT.DIARYCODE =
(SELECT DIARYCODE FROM LOGBOOKTABLE
WHERE (STUDENTUSERNAME=? OR SUPERVISORUSERNAME=?)
AND PROJECT_APPROVE_STATUS=?)"
I have a mySql schema named Contacts that contains 4 tables: Contacts, Phone, Email, and Addresses. The Contacts table contains basic information about a person such as an id number, first name, and last name. The other tables all contain a foreign key that links it to the Contacts table so for example, John Doe in the Contacts table can have multiple phone numbers in the Phones table that are all searchable by using John Doe's id number.
My question is how do I query this schema and return all data for a single (or multiple) users. Can it be done with one SQL statement, or do I need to contact the database for each individual table based on the fact that the amount of results returned will not match for each row returned from the Contacts table. For example, I have some basic search functionality that searches the Contacts table for one or more rows based on search criteria:
public class ContactsListDAO {
//Constants
private static final String SQL_FIND_BY_SEARCH_CRITERIA = "SELECT * FROM Contacts.Contacts WHERE Id LIKE :searchString OR FirstName LIKE :searchString OR LastName LIKE :searchString";
//Variables
private DAOFactory daoFactory;
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
//Constructors
public ContactsListDAO(DAOFactory daoFactory) {
this.daoFactory = daoFactory;
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(daoFactory.getDataSource());
}
public List<Contact> findSearchResults(String searchCriteria) {
Map<String, String> namedParameters = Collections.singletonMap("searchString", searchCriteria);
RowMapper<Contact> mapper = new RowMapper<Contact>() {
#Override
public Contact mapRow(ResultSet resultSet, int row) throws SQLException {
Contact contact = new Contact(
resultSet.getInt("Id"),
resultSet.getString("FirstName"),
resultSet.getString("LastName")
);
return contact;
}
};
return namedParameterJdbcTemplate.query(SQL_FIND_BY_SEARCH_CRITERIA, namedParameters, mapper);
}
}
I am using spring to query and map the results back to a Contact bean. How would I go about modifying this SQL statement and mapping functionality to search the contacts table, get the data for each row and then based on the id of each returned row, also query the phone, email, and address tables and then map those to a List object stored in the bean? The problem is that row 1's id might find 8 phone numbers rows that match the id, but row 2's id might only find 3 phone numbers. How is this going to be stored in a ResultSet? Or will I have to query the Contacts table first and then perform a separate query for each other table (for each row returned from the first) and add that data to the bean case by case? If the first query returns 100 results, and I have to perform a query for each of those on 3 tables, I am looking at 301 trips to the database and back.
Is it possible to use one query and just return 1 result from each of the phone, email, address tables for each result found in the Contacts table? Maybe I can add a primary column or something so it only returns 1 result and then if the user clicks something to request more information about the result it can perform the other queries and gather all the info about that user.
The query i've come up with uses LEFT JOIN to search the tables:
SELECT * FROM Contacts.Contacts LEFT JOIN Contacts.Phone ON Contacts.Id = Phone.ContactId AND Phone.Primary = 1 LEFT JOIN Contacts.Email ON Contacts.Id = Email.ContactId AND Email.Primary = 1 WHERE Contacts.Id LIKE :searchString OR Contacts.FirstName LIKE :searchString OR Contacts.LastName LIKE :searchString AND Contacts.OrganizationId = :organizationId
I created a column in the Phone, Email, and Address database called Primary that contains a boolean so that on my initial query I will only return 1 result for each Contact in the database. So far this is doing what I need. Not sure if it the proper way to go about something like this?