For my project i try to get all foreign key in my table using DatabaseMetada Object form jdbc but when i execute the following code the result set is always empty even if my table contain foreign key ?
ResultSet v_resultPrimaryKey = p_metadata.getImportedKeys(null, Tools.getDBName(), "bookmarks_tags");
if (v_resultPrimaryKey.next()) {
System.out.println("test");
v_resultPrimaryKey.beforeFirst();
v_resultPrimaryKey.beforeFirst();
while (v_resultPrimaryKey.next()) {
if (p_att.equals(v_resultPrimaryKey.getString("FKCOLUMN_NAME"))) {
v_fk = v_resultPrimaryKey.getString("PKTABLE_NAME") + "."
+ v_resultPrimaryKey.getString("PKCOLUMN_NAME");
v_fkName = v_resultPrimaryKey.getString("FK_NAME");
}
}
if(!v_fk.equals("")){
v_foreignKey = new ForeignKey(v_fkName, v_fk);
}
}
stumbled upon this and this may help in case anyone may see it
DatabaseMetaData p_metadata= connection.getMetaData();
ResultSet v_resultPrimaryKey = p_metadata.getImportedKeys(null, Tools.getDBName(), "bookmarks_tags");
if (v_resultPrimaryKey.next()) {
System.out.println("test");
v_resultPrimaryKey.beforeFirst();
v_resultPrimaryKey.beforeFirst();
while (v_resultPrimaryKey.next()) {
if (p_att.equals(v_resultPrimaryKey.getString("FKCOLUMN_NAME"))) {
String v_fk = v_resultPrimaryKey.getString("PKTABLE_NAME") + "."
+ v_resultPrimaryKey.getString("PKCOLUMN_NAME");
String v_fkName = v_resultPrimaryKey.getString("FK_NAME");
}
}
if(!v_fk.equals("")){
v_foreignKey = new ForeignKey(v_fkName, v_fk);
}
}
Related
I am trying to update several records from spring jdbc but this is not working what am i doing wrong?
does not respond when I make a request, but the data in the array is arriving, try without array and the same thing happens.
I am sending an array of objects to be able to update but I get to the method cstmt.executeQuery(); it does not execute and it waits and does not go any further.
#PostMapping(path = "/updateEstadoPlanesServicios", produces = MediaType.APPLICATION_JSON)
public String updateEstadoPlanesServicios(#RequestBody String lista) {
ServiciosPlanesUpdateDTO[] fromJson = gson.fromJson(lista, ServiciosPlanesUpdateDTO[].class);
return gson.toJson(consultaPlanesComisionPortal.estadoPlanesServicios(fromJson));
}
#Transactional(rollbackFor = { Exception.class })
public replyDTO estadoPlanesServicios(ServiciosPlanesUpdateDTO[] list) {
System.out.println("data: "+list.toString());
replyDTO re = new replyDTO();
int count = 0;
try {
StringBuilder update = new StringBuilder();
update.append("UPDATE Detalleproductoservicio ");
update.append(" SET loginregistro = ?, estado = 'D', fechasys = sysdate ");
update.append(" WHERE codigo_Servicio = ? and codigo_planproductoservicio = ? and NIT = ?");
try (Connection conexion = obtenerConexion.obtenerConexion(0);
PreparedStatement cstmt = conexion.prepareStatement(update.toString())) {
conexion.setAutoCommit(false);
for(ServiciosPlanesUpdateDTO elements: list) {
//System.out.println(elements.toString());
System.out.println("1 element:"+elements.getLoginRegistro());
System.out.println("2 element:"+elements.getCodigoServicio());
System.out.println("3 element:"+elements.getCodigoPlanProductoServicio());
System.out.println("4 element:"+elements.getNit());
cstmt.setString(1, elements.getLoginRegistro().trim());
cstmt.setInt(2,Integer.parseInt( elements.getCodigoServicio().trim()));
cstmt.setString(3, elements.getCodigoPlanProductoServicio().trim());
cstmt.setString(4, elements.getNit().trim());
count = cstmt.executeUpdate();
//cstmt.execute();
//count++;
//cstmt.addBatch();
//cstmt.executeBatch();
//
}
conexion.commit();
if(count > 0) {
re.setMessage("Status ok,"
+"count: "+count);
re.setExitoso(true);
}else {
re.setExitoso(false);
re.setMessage("failed");
}
}
} catch (Exception e ) {
re.setExitoso(false);
re.setMessage(e.getMessage());
}
return re;
}
this is working I found the problem apparently the database conflicts when I have Oracle SQL Developer open and I make the request by postman this is a little weird but I closed Oracle Developer and it worked.
I have a String SELECT *FROM USERS WHERE ID = '#userid#' AND ROLE = '#role#'
Now i have replace any string between #...# , with a actual value .
Expected output SELECT *FROM USERS WHERE ID = '4' AND ROLE = 'Admin'
This replace will happen from a method , i have written this logic
public String replaceQueryKeyWithValueFromKeyValues(String query, int reportId) {
try {
REPMReportDao repmReportDao = new REPMReportDao();
int Start = 0;
int end;
if (query.contains("#")) {
boolean specialSymbolFound = false;
for (int i = 0; i < query.length(); i++) {
if (query.charAt(i) == '#') {
if (!specialSymbolFound) {
Start = i + 1;
specialSymbolFound = true;
} else {
specialSymbolFound = false;
end = i;
query = query.replace(query.substring(Start - 1, end + 1), repmReportDao.getReportManagerKeyValue(query.substring(Start - 1, end + 1).replaceAll("#", ""), reportId));
}
}
}
return query;
} else {
return query;
}
} catch (Exception e) {
logger.log(Priority.ERROR, e.getMessage());
return e.getMessage();
}
}
It works fine , but in the case if a single '#' symbol exist instead of start and end it will fail.
Like :
SELECT *FROM USERS WHERE emailid = 'xyz#gmail.com' AND ROLE = '#role#'
Here it should replace the only role '#role#' and should left email as it is.
Expected Output => SELECT *FROM USERS WHERE emailid = 'xyz#gmail.com' AND ROLE = 'Admin'
Complete example with mocked data returned by getReportManagerKeyValue:
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StackOverflow54842971 {
private static Map<String, String> map;
public static void main(String[] args) {
// preparing test data
map = new HashMap<>();
map.put("role", "Admin");
map.put("userid", "666");
// original query string
String query = "SELECT * FROM USERS WHERE ID = '#userid#' AND emailid = 'xyz#gmail.com' AND ROLE = '#role#' ";
// regular expression to match everything between '# and #' with capture group
// omitting single quotes
Pattern p = Pattern.compile("'(#[^#]*#)'");
Matcher m = p.matcher(query);
while (m.find()) {
// every match will be replaced with value from getReportManagerKeyValue
query = query.replace(m.group(1), getReportManagerKeyValue(m.group(1).replaceAll("#", "")));
}
System.out.println(query);
}
// you won't need this function
private static String getReportManagerKeyValue(String key) {
System.out.println("getting key " + key);
if (!map.containsKey(key)) {
return "'null'";
}
return map.get(key);
}
}
It's considered very bad practice to use string substitution to generate database queries, because you leave your code open to SQL Injection attacks. I can't tell from the small code sample you've provided, but the vast majority of large-scale Java projects use the Spring Framework, which allows you to use either JdbcTemplate or (my preference) NamedParameterJdbcTemplate. Both will allow you to substitute variables in a safe manner.
I have an application with a list of people and you can change the info of one certain person when you click on a button. So I am trying to update my database but it says that I do not have a value for the 7th parameter, however I do have 7 values. When I print it, it does give me 7 values. It doesn't have a problem with the null (in my if else) because I already tried it without that.
This is my msql
CREATE TABLE Persoon(
persoonId int(3) NOT NULL AUTO_INCREMENT,
leeftijd int(3),
voornaam varchar(40) NOT NULL,
achternaam varchar (40) NOT NULL,
datum date,
locatieId int(3),
filmId int(3) NOT NULL,
PRIMARY KEY (persoonId),
FOREIGN KEY (filmId) references Film(filmId),
FOREIGN KEY (locatieId) references Locatie(locatieId));
My java code
private void btnWijzigenActionPerformed(java.awt.event.ActionEvent evt) {
Object geselecteerdeObject = lstPersonen.getSelectedValue();
Persoon geselecteerdePersoon = (Persoon) geselecteerdeObject;
if(txtLeeftijd.getText() != ""){
try {
String string = txtDatum.getText();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date datumString = format.parse(string);
Persoon nieuwePersoon = new Persoon(geselecteerdePersoon.getPersoonId(),Integer.parseInt(txtLeeftijd.getText()), txtVoornaam.getText(), txtAchternaam.getText(),datumString,geselecteerdePersoon.getLocatieId(),geselecteerdePersoon.getFilmId());
System.out.println("1p "+geselecteerdePersoon.getPersoonId() + " 2p " +Integer.parseInt(txtLeeftijd.getText()) + " 3p "+txtVoornaam.getText() + " 4p " + txtAchternaam.getText() + " 5p " + datumString + " 6p "+ geselecteerdePersoon.getLocatieId()+ " 7p " +geselecteerdePersoon.getFilmId());;
PersoonDao.updatePersoon(nieuwePersoon);
} catch (ParseException ex) {
Logger.getLogger(HoofdGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
else{
Persoon nieuwePersoon = new Persoon(geselecteerdePersoon.getPersoonId(),0, txtVoornaam.getText(), txtAchternaam.getText(),null,geselecteerdePersoon.getLocatieId(),geselecteerdePersoon.getFilmId());
PersoonDao.updatePersoon(nieuwePersoon);
}
updatePersoonsLijst();
}
My method updatePersoonsLijst
public void updatePersoonsLijst() {
mijnModel.clear();
ArrayList<Persoon> lijstVanPersonen = PersoonDao.getPersonen();
for (Persoon huidigePersoon : lijstVanPersonen) {
mijnModel.addElement(huidigePersoon);
}
}
And my updatePersoon
public static int updatePersoon(Persoon nieuwePersoon) {
int aantalAangepasteRijen = 0;
try {
aantalAangepasteRijen = Database.voerSqlUitEnHaalAantalAangepasteRijenOp("UPDATE Persoon SET leeftijd=?,voornaam=?,achternaam=?,datum=?,locatieId=?,filmId=? WHERE persoonId=?", new Object[] { nieuwePersoon.getLeeftijd(),nieuwePersoon.getVoornaam(), nieuwePersoon.getAchternaam(), nieuwePersoon.getDatum(), nieuwePersoon.getLocatieId(),nieuwePersoon.getFilmId() });
} catch (SQLException ex) {
ex.printStackTrace();
// Foutafhandeling naar keuze
}
return aantalAangepasteRijen;
}
Your update statement is missing last parameter personid - your last is filmid currently.
aantalAangepasteRijen = Database.voerSqlUitEnHaalAantalAangepasteRijenOp("UPDATE Persoon
SET leeftijd=?,voornaam=?,achternaam=?,datum=?,locatieId=?,filmId=?
WHERE persoonId=?", new Object[]
{ nieuwePersoon.getLeeftijd(),
nieuwePersoon.getVoornaam(),
nieuwePersoon.getAchternaam(),
nieuwePersoon.getDatum(),
nieuwePersoon.getLocatieId(),
nieuwePersoon.getFilmId()
// persoonId missing!!
});
First, I'll give the codes I'm dealing with.
Action code for the "Save" Button.
private void saveBtActionPerformed(java.awt.event.ActionEvent evt) {
try {
Production production=new Production(batchNoValueLabel.getText(), productIDCombo.getSelectedItem(), rawMaterialUsedCombo.getSelectedItem(), dateValueLabel.getText(), rawMaterialBatchCombo.getSelectedItem(), weightInitialSpinner.getValue(), beforeWeightSpinner.getValue(), afterWeightSpinner.getValue(), finalWeightSpinner.getValue(), packingWeightSpinner.getValue(), noOfUnitSpinner.getValue(), wastageSpinner.getValue());
int res=ProductionController.addBatch(production);
if(res==1){
JOptionPane.showMessageDialog(this, "New Batch Added!");
String nextid = IDGeneration.getNextid("B", "production", "productionBatchID");
batchNoValueLabel.setText(nextid);
productIDCombo.removeAllItems();
ArrayList<String> getProductsDetails = ProductsController.getProductID();
for (String detail : getProductsDetails) {
productIDCombo.addItem(detail);
}
}else{
JOptionPane.showMessageDialog(this, "New Product Adding Failed!");
}
} catch (ClassNotFoundException | SQLException ex) {
Logger.getLogger(ProductsForm.class.getName()).log(Level.SEVERE, null, ex);
}
}
Then, the Model Class. (Getters and Setters are there, not pasted here)
public Production(String productionBatchID, Object finishedMaterialID, Object rawMaterialID, String productionDate, Object rawMatBatchID, Object initialWeight, Object beforeWeight, Object afterWeight, Object finalWeight, Object packingWeight, Object noOfUnits, Object wastage) {
this.productionBatchID = productionBatchID;
this.finishedMaterialID = (String) finishedMaterialID;
this.rawMaterialID = (String) rawMaterialID;
this.productionDate = productionDate;
this.rawMatBatchID = (String) rawMatBatchID;
this.initialWeight = (int) initialWeight;
this.beforeWeight = (int) beforeWeight;
this.afterWeight = (int) afterWeight;
this.finalWeight = (int) finalWeight;
this.packingWeight = (int) packingWeight;
this.noOfUnits = (int) noOfUnits;
this.wastage = (int) wastage;
}
And, finally the controller class.
public class ProductionController {
public static int addBatch(Production production) throws ClassNotFoundException, SQLException {
Connection conn=DBConnection.getConnection();
Statement stm=conn.createStatement();
String sql="insert into production (productionBatchID, finishedMaterialID, rawMaterialID, productionDate, rawMatBatchID, initialWeight, beforeWeight, finalWeight, packingWeight, noOfUnits, wastage) values ('"+production.getProductionBatchID()+"','"+production.getFinishedMaterialID()+"','"+production.getRawMaterialID()+"','"+production.getProductionDate()+"','"+production.getRawMatBatchID()+"','"+production.getInitialWeight()+"','"+production.getBeforeWeight()+"','"+production.getAfterWeight()+"','"+production.getFinalWeight()+"','"+production.getPackingWeight()+"','"+production.getNoOfUnits()+"','"+production.getWastage()+"');";
int rowCount=stm.executeUpdate(sql);
return rowCount;
}
}
And still, when I enter data in the GUI and try to send the data to the database, it gives out "java.sql.SQLException: Column count doesn't match value count at row 1" error. How to solve this? Oh, and here's the MySQL Table:
create table production(productionBatchID VARCHAR(4) NOT NULL,finishedMaterialID VARCHAR(4) NOT NULL,rawMaterialID VARCHAR(4) NOT NULL,productionDate VARCHAR(15),rawMatBatchID VARCHAR(4),initialWeight INT(5),beforeWeight INT(5),afterWeight INT(5),finalWeight INT(5),packingWeight INT(5),noOfUnits INT(5),wastage INT(5),CONSTRAINT PRIMARY KEY (productionBatchID))ENGINE=INNODB;
How to solve this?
Your VALUES clause has
'"+production.getAfterWeight()+"','"+production.getFinalWeight()+
But you only have finalWeight in the column list.
The error tells you this
insert into production (
productionBatchID, finishedMaterialID,
rawMaterialID, productionDate,
rawMatBatchID, initialWeight,
beforeWeight, finalWeight,
packingWeight, noOfUnits,
wastage)
values (
'"+production.getProductionBatchID()+"','"+production.getFinishedMaterialID()+"','"+
production.getRawMaterialID()+"','"+production.getProductionDate()+"','"+
production.getRawMatBatchID()+"','"+production.getInitialWeight()+"','"+
production.getBeforeWeight()+"','"+
production.getAfterWeight()+"','"+
production.getFinalWeight()+"','"+ there are 3 here
production.getPackingWeight()+"','"+production.getNoOfUnits()+"','"+
production.getWastage()+"');";
Also, parameterise your queries to mitigate SQL Injection risks please
There is mismatch in number of columns you are using in INSERT query, 'beforeWeight' is the column, whose values is missing, below is the corrected query:
String sql="insert into production (productionBatchID, finishedMaterialID, rawMaterialID, productionDate, rawMatBatchID, initialWeight, **beforeWeight**, finalWeight, packingWeight, noOfUnits, wastage) values ('"+production.getProductionBatchID()+"','"+production.getFinishedMaterialID()+"','"+production.getRawMaterialID()+"','"+production.getProductionDate()+"','"+production.getRawMatBatchID()+"','"+production.getInitialWeight()+"','"+production.getBeforeWeight()+"','"+production.getAfterWeight()+"','"+production.getBeforeWeight()+"','"+production.getFinalWeight()+"','"+production.getPackingWeight()+"','"+production.getNoOfUnits()+"','"+production.getWastage()+"');";
OK, I have a JSP running the following script section.
<% irCollection mgrq = new irCollection();
mgrq.setMgrid("Chris Novish");
mgrq.populateCollection();
int pagenum;
if (request.getParameter("p") != null) {
String pagedatum=request.getParameter("p");
pagenum = Integer.parseInt(pagedatum);
} else { pagenum = 0; }
for (int i=0;i<10;i++) {
int rownum = pagenum * 10 + i;
InquireRecord currec = mgrq.getCurRecords(rownum);
out.println(currec.getID()); %>
irCollection has an ArrayList property that stores a several InquireRecord objects. It gets this data from a database using the mgrid as (set in line 2 there) as the matching term.
But I'm getting an IndexOutOfBounds exception on what appears here as line 11.
I've done some tests, and I'm pretty sure that it's because populateCollection() isn't getting things done. I have a getSize method that gives me a size of 0.
I made a test class in Eclipse to make sure all my methods were working:
package com.serco.inquire;
public class test {
public static void main (String[] args) {
String mgr = "Chris Novish";
irCollection bob = new irCollection();
bob.setMgrid(mgr);
bob.populateCollection();
InquireRecord fred = bob.getCurRecords(1);
System.out.println(fred.getID());
}
}
That test class produces exactly what I'd expect.
Other than the names of some of the local variables, I can't see what I'm doign different in the JSP.
So... tell me, what noobish mistake did I make?
for the sake of being thorough, here's the populateCollection() method:
public void populateCollection() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String filename = "inquire.mdb";
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=";
database+= filename.trim() + ";DriverID=22;READONLY=true}";
Connection con = DriverManager.getConnection( database ,"","");
Statement s = con.createStatement();
s.execute ("SELECT * FROM inquiries WHERE manager = '" + mgrid + "'");
ResultSet rs = s.getResultSet();
int cur;
if (rs != null) {
while (rs.next()) {
cur = rs.getRow();
cur -- ;
int curID = rs.getInt("ID");
this.newIR.setID(curID);
String cursub = rs.getString("submitter");
this.newIR.setSubmitter(cursub);
this.iRecords.add(cur, this.newIR);
}
this.size = iRecords.size();
this.pages = this.size / 10;
int remain = this.size % 10;
if (remain > 0) { this.pages++; }
} else { System.out.println("no records."); }
}
catch (Throwable e) {
System.out.println(e);
}
}
Your IndexOutOfBounds exception is probably being caused by the value of rownum being passed to mgrq.getCurRecords().
Your test code proves nothing because there you're calling getCurRecords() with a constant which is probably always valid for your system and will never cause the exception.
My suggestion is to step through the code in your JSP with a debugger, or even simply to print out the value of your variables (especially pagedatum, pagenum and rownum) in your JSP code.
Is your JSP Snippet correct? It looks like you started the braces for the
for (int i=0;i<10;i++) {
but I dont see a end braces for that at all. Can you check if that is the case and if so, fix the code appropriately?