I'm trying to insert into a database, but with the added bonus of checking if there is duplicate data based on 5 fields.
For example I want to insert a line of data but for every ID, it will check 4 other fields, if all 5 fields match I do not want to insert. Other than that, an insert.
So far I have made the sql statement. I tried my query on a database dummy to see if it works and it does but when I run it in java with all the prepared statements, it gives me an error that says "Must declare the scalar variable". Here is my code and I do not know where to declare or what I must declare. Does it depend on the configuration of the database?
System.out.println("connection created successfully using properties file");
PreparedStatement pstmt2 = null;
PreparedStatement pstmt3 = null;
PreparedStatement pstmt5 = null;
PreparedStatement pstmt6 = null;
ResultSet rs = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(
"C:\\Users\\darroyo\\Documents\\pruebasx.txt"));
} catch (FileNotFoundException e1) {
logger.error(e1.getMessage());
}
String line = null;
try {
line = reader.readLine();
} catch (IOException e1) {
logger.error(e1.getMessage());
}
String query = " insert into FRONTMC.HECHO (folio_hecho, folio_orden,"
+ "clave_sentido, titulos_hecho, precio, importe, liquidacion, contraparte, id_estatus, isin, contrato,"
+ "secondary_exec_id, exec_id, F11_ClOrdID, fecha_recepcion, fecha_sentra,emisora,serie)"
+ " select ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,convert(varchar(30),cast(? as datetime),120),convert(varchar(30),cast(? as datetime),120),?,?"
+" from FRONTMC.HECHO WHERE NOT EXISTS (SELECT * FROM FRONTMC.HECHO WHERE ISIN = ?"
+ "AND EMISORA = ? AND SERIE = ? AND CLAVE_SENTIDO = ? AND SECONDARY_EXEC_ID =?";
PreparedStatement preparedStmt = null;
try {
preparedStmt = con.prepareStatement(query);
} catch (SQLException e1) {
logger.error(e1.getMessage());
}
Map<Integer,String> hm1 = new HashMap<Integer,String>();
try {
do {
try{
String[] tokens = line.split("");
for (int i = 0; i != tokens.length; i++) {
int dataIndex = tokens[i].indexOf('=') + 1;
String data = tokens[i].substring(dataIndex);
hm1.put(new Integer(i),data);
}
String query2 = "select emisora from FRONTMC.EMISORA_CUSTODIO_SIGLO where isin = ?";
String query5 = " insert into FRONTMC.HECHO (emisora)"
+ " values ( ?)";
pstmt2 = con.prepareStatement(query2);
pstmt5 = con.prepareStatement(query5);
String query3 = "select serie from FRONTMC.EMISORA_CUSTODIO_SIGLO where isin = ?";
String query6 = " insert into FRONTMC.HECHO (emisora)"
+ " values ( ?)";
pstmt3 = con.prepareStatement(query3); // create a statement
pstmt6 =con.prepareStatement(query6);
setParameterString(preparedStmt,1, hm1.get(23));
setParameterString(preparedStmt,2, hm1.get(19));
setParameterString(preparedStmt,3, hm1.get(15));
setParameterString(preparedStmt,4, hm1.get(30));
setParameterString(preparedStmt,5, hm1.get(16));
setParameterString(preparedStmt,6, hm1.get(18));
setParameterString(preparedStmt,7, hm1.get(8));
setParameterString(preparedStmt,8, hm1.get(33));
setParameterString(preparedStmt,9, hm1.get(27));
setParameterString(preparedStmt,10, hm1.get(17));
setParameterString(preparedStmt,11, hm1.get(26));
setParameterString(preparedStmt,12, hm1.get(23));
setParameterString(preparedStmt,13, hm1.get(10));
setParameterString(preparedStmt,14, hm1.get(14));
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat sdf2 = new SimpleDateFormat("dd/MM/yyyy");
String ds2 = null;
ds2 = sdf2.format(sdf1.parse(hm1.get(6)));
String newfecha1 = ds2;
setParameterString(preparedStmt,15, newfecha1);
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat sdf4 = new SimpleDateFormat("dd/MM/yyyy");
String ds4 = null;
ds4 = sdf4.format(sdf3.parse(hm1.get(6)));
String newfecha3 = ds4;
setParameterString(preparedStmt,16, newfecha3);
pstmt2.setString(1, hm1.get(17));
rs = pstmt2.executeQuery();
while (rs.next()) {
String emisora = rs.getString(1);
pstmt5.setString(1,emisora);
setParameterString(preparedStmt,17, emisora);
pstmt3.setString(1, hm1.get(17));
rs = pstmt3.executeQuery();
while (rs.next()) {
String serie = rs.getString(1);
pstmt6.setString(1,serie);
System.out.println(serie);
setParameterString(preparedStmt,18, serie);
setParameterString(preparedStmt,19, hm1.get(17));
setParameterString(preparedStmt,20, emisora);
setParameterString(preparedStmt,21, serie);
setParameterString(preparedStmt,22, hm1.get(15));
setParameterString(preparedStmt,23, hm1.get(23));
preparedStmt.execute();
}
}}catch(Exception ab){
new Thread(new Runnable(){
#Override
public void run(){
errorcon2();
}
}).start();
logger.error(ab.getMessage());
System.out.println(ab.getMessage());
ab.printStackTrace();
}
}while ((line = reader.readLine()) != null);}
catch(Exception a){
logger.error(a.getMessage());
}
new Thread(new Runnable(){
#Override
public void run(){
exitomsj();
}
}).start();
Here is the exception I get: Mistranslation it is not scalable, it is scalar.
com.microsoft.sqlserver.jdbc.SQLServerException: Debe declarar la variable escalar "#P18AND".
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:217)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1655)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:440)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:385)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7505)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2445)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:191)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:166)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:367)
at swt.swtapp2$2.mouseDown(swtapp2.java:488)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:193)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4418)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4236)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3824)
at org.eclipse.jface.window.Window.runEventLoop(Window.java:818)
at org.eclipse.jface.window.Window.open(Window.java:794)
at swt.swtapp2.main(swtapp2.java:610)
You are missing a space.
+ "AND EMISORA = ? AND ...
should be
+ " AND EMISORA = ? AND ...
Related
I'd like to insert ID(int), title(varchar), plot(varchar), release_date(date), target(varchar) into exsiting database.
Here is the code which showed no data at all.
How can I add a date type value into a connected database?
else if (e.getSource() == this.insert2) {
String n = this.IDField.getInt();
String m = this.titleField.getText();
String f = this.plotField.getText();
String p = this.release_dateField.getText();
String t = this.targetField.getText();
String[] name = {"MOVIE_ID","title","plot","release_date","main_target"};
this.dt = new DefaultTableModel(name, 0);
/**try~catch*/
try{
stmt.executeUpdate("insert into DB2020_MOVIEINFO values('" + n + "', '" + m + "', '" + f + "', '" + p + "', '" + t + "')");
ResultSet rset_mv = stmt.executeQuery("SELECT * FROM DB2020_MOVIEINFO");
while (rset_mv.next()) {
Object[] data = {rset_mv.getString(1), rset_mv.getString(2), rset_mv.getString(3), rset_mv.getString(4), rset_mv.getString(5)};
dt.addRow(data);
}
}
catch(SQLException se) {
se.printStackTrace();
}
this.jt = new JTable(dt);
jt.getTableHeader().setBackground(Color.decode("#b76e79"));
jt.setSelectionBackground(Color.decode("#f7f6f0"));
this.jsp = new JScrollPane(jt);
jt.setPreferredScrollableViewportSize(new Dimension(800,600));
this.add(centerPanel,BorderLayout.CENTER);
this.centerPanel.removeAll();
this.centerPanel.updateUI();
this.centerPanel.add(jsp);
this.centerPanel.setVisible(true);
}
new code I applied after Mureinik's advise. (I extracted date-part)
else if (e.getSource() == this.insert2) {
Int id = this.IDField.getInt();
String title = this.titleField.getText();
String plot = this.plotField.getText();
String target = this.targetField.getText();
String[] name = {"MOVIE_ID","title","plot","main_target"};
this.dt = new DefaultTableModel(name, 0);
/**try~catch*/
try (PreparedStatement ps =
conn.prepareStatement("insert into DB2020_MOVIEINFO values(?, ?, ?, ?)") {
ps.setInt(1, id); // id should be an int
ps.setString(2, title);
ps.setString(3, plot);
ps.setString(4, target);
}
catch(SQLException se) {
se.printStackTrace();
}
this.jt = new JTable(dt);
jt.getTableHeader().setBackground(Color.decode("#b76e79"));
jt.setSelectionBackground(Color.decode("#f7f6f0"));
this.jsp = new JScrollPane(jt);
jt.setPreferredScrollableViewportSize(new Dimension(800,600));
this.add(centerPanel,BorderLayout.CENTER);
this.centerPanel.removeAll();
this.centerPanel.updateUI();
this.centerPanel.add(jsp);
this.centerPanel.setVisible(true);
}
Instead of trying to force these datatypes to strings, you could use a PreparedStatement and let the JDBC driver do the heavy lifting for you. As a side effect, this will also help protect you application from SQL Injection attacks:
try (PreparedStatement ps =
conn.prepareStatement("insert into DB2020_MOVIEINFO values(?, ?, ?, ?, ?)) {
ps.setInt(1, id); // id should be an int
ps.setString(2, title);
ps.setString(3, plot);
ps.setDate(4, releaseDate); // releaseDate should be java.sql.Date
ps.setString(5, target);
}
I have found below code buggy as it degrades the performance of extjs3 grid, i am looking for possibilities of optimization at query or code level, as per my analysis, if we extract out the query there are two nested inner queries which are responding slow, in addition, the code inside while loop trying to find the unique id, can't we have distinct in query, or joins rather than inner queries.
Please suggest me the best practice to follow in order to achieve optimization.
public boolean isSCACreditOverviewGridVisible(String sessionId) {
Connection conn = null;
ResultSet rs = null;
PreparedStatement ps = null;
boolean result = false;
try {
CommonUtility commUtil = new CommonUtility();
List<String> hmIds = new ArrayList<String>();
Map<String, String> tmStockMap = new TreeMap<String, String>();
Set<String> setRecentCertificate = new HashSet<String>();
String managerAccountId = sessionInfo.getMembershipAccount();
String stockQuery = " select memberId , RootCertficateId from stockposition sp where sp.stocktype = 'TR' and sp.memberId "
+ " IN ( select hm2.accountId from "
DATALINK
+ ".holdingmembers hm2 "
+ " where hm2.holdingId = ( select holdingId from "
DATALINK
+ ".holdingmembers hm1 where hm1.accountId = ? )) "
+ " order by sp.createdDate desc ";
conn = getChildDBConnection();
if (null != conn) {
ps = conn.prepareStatement(stockQuery);
ps.setString(1, managerAccountId);
rs = ps.executeQuery();
if (null != rs) {
while (rs.next()) {
String memberId = rs.getString("memberId");
String rootCertficateId = rs
.getString("RootCertficateId");
if (tmStockMap.containsKey(rootCertficateId)) {
continue;
}
hmIds.add(memberId);
tmStockMap.put(rootCertficateId, memberId);
}
}
rs.close();
ps.close();
if (null != hmIds && !hmIds.isEmpty()) {
String inIds = commUtil.getInStateParam(hmIds);
String mostRecentLicense = "Select RootCertificateId , memberaccountid from "
+ OctopusSchema.octopusSchema
+ ".certificate c where c.memberaccountid IN ("
+ inIds
+ ") and c.isrootcertificate=0 and c.certificationstatusid > 1 order by c.modifieddate desc";
ps = conn.prepareStatement(mostRecentLicense);
rs = ps.executeQuery();
if (null != rs) {
while (rs.next()) {
String rootCertficateId = rs
.getString("RootCertificateId");
String memberaccountid = rs
.getString("memberaccountid");
if (setRecentCertificate.contains(memberaccountid)) {
continue;
}
setRecentCertificate.add(memberaccountid);
if (tmStockMap.containsKey(rootCertficateId)) {
result = true;
break;
}
}
}
rs.close();
ps.close();
} else {
result = false;
}
}
} catch (Exception e) {
LOGGER.error(e);
} finally {
closeDBReferences(conn, ps, null, rs);
}
return result;
}
QUERY:
select RootCertficateId,memberId from stockposition sp where sp.stocktype = 'TR' and sp.memberId
IN ( select hm2.accountId from
DATALINK.holdingmembers hm2
where hm2.holdingId = ( select holdingId from
DATALINK.holdingmembers hm1 where hm1.accountId = '4937' ))
order by sp.createdDate DESC;
One quick approach would be a substition of your IN by EXISTS. If your inner queryes return a lot of rows, it would be a lot more efficient. It depends if your subquery returns a lot of results.
SQL Server IN vs. EXISTS Performance
The update button on my simple stock management system is not updating the stock. When clicked it shows the product updated dialog but nothing happens. It is throwing no errors and i cant find the problem.
It was working when i only had 5 rows but when i added the category and quantity row it stopped.
private void btn_updateActionPerformed(java.awt.event.ActionEvent evt) {
if(checkInputs() && txt_id.getText() != null)
{
String UpdateQuery = null;
PreparedStatement ps = null;
Connection con = getConnection();
//update without image
if(ImgPath == null)
{
try {
UpdateQuery = "UPDATE products SET name = ?, price = ?"
+ ", add_date = ?, category = ?, quantity = ?, WHERE id = ?";
ps = con.prepareStatement(UpdateQuery);
ps.setString(1, txt_name.getText());
ps.setString(2, txt_price.getText());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String addDate = dateFormat.format(txt_AddDate.getDate());
ps.setString(3, addDate);
ps.setInt(4, Integer.parseInt(txt_id.getText()));
String value = combo_category.getSelectedItem().toString();
ps.setString(5, value);
ps.setString(6, txt_quantity.getText());
ps.executeUpdate();
Show_Products_In_JTable();
JOptionPane.showMessageDialog(null, "Product Updated");
} catch (SQLException ex) {
Logger.getLogger(Main_Window.class.getName()).log(Level.SEVERE, null, ex);
}
}
//update with Image
else{
try{
InputStream img = new FileInputStream(new File(ImgPath));
UpdateQuery = "UPDATE products SET name = ?, price = ?"
+ ", add_date = ?,image = ?, category = ?, quantity = ?, WHERE id = ?";
ps = con.prepareStatement(UpdateQuery);
ps.setString(1, txt_name.getText());
ps.setString(2, txt_price.getText());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String addDate = dateFormat.format(txt_AddDate.getDate());
ps.setString(3, addDate);
ps.setBlob(4, img);
String value = combo_category.getSelectedItem().toString();
ps.setString(5, value);
ps.setInt(6, Integer.parseInt(txt_id.getText()));
ps.executeUpdate();
Show_Products_In_JTable();
JOptionPane.showMessageDialog(null, "Product Updated");
}catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
}else{
JOptionPane.showMessageDialog(null, "One or More Fields Are Empty Or Wrong");
}
}
At first sight
quantity = ?, WHERE id = ?
shoule be
quantity = ? WHERE id = ?
I am using the below code to retrive the order data from db2 and it works fine when i am passing only the BranchNumber and used the getWildcards() function since sometime i am passing multiple branch numbers .
public List<Order> getallorders(List<Branch> BranchNumber) throws SQLException {
List<Order> orders = new ArrayList<Order>();
try {
StringBuilder sb = new StringBuilder();
sb.append("SELECT ORDER_NUMBER as ordernumber,SERVICE_TYPE as service"
+ "FROM ORDER WHERE "
+ "BRANCH IN(");
sb.append(getWildCards(BranchNumber.size())).append(")").append(" WITH UR");
String query = sb.toString();
PreparedStatement statement = connection.prepareStatement(query);
for(int i=0 ; i<BranchNumber.size() ;i++)
{
statement.setInt(i+1,BranchNumber.get(i).getBranch());
}
ResultSet resultSet = statement.executeQuery();
{
while (resultSet .next()) {
Order order1 = new Order();
order1.setOrdernumber(resultSet.getInt("ordernumber"));
orders.add(order1);
}
}
}
catch (SQLException e) {
e.printStackTrace();
}
return orders;
}
private String getWildCards(int size) {
// TODO Auto-generated method stub
StringBuilder sb = new StringBuilder();
for(int i =0 ; i<size ; i++)
{
sb = (i == 0) ? sb.append("?")
: sb.append(",").append("?");
}
return sb.toString();
}
Now i need to pass the startDate and endDate inside the function to retrieve the data but the preparedstatement is not formatting the select query with the passed value .
public List<Order> getallorders(List<Branch> BranchNumber,String startDate,String endDate) throws SQLException {
List<Order> orders = new ArrayList<Order>();
try {
StringBuilder sb = new StringBuilder();
sb.append("SELECT ORDER_NUMBER as ordernumber,SERVICE as service"
+ "FROM ORDER WHERE "
+ "BRANCH IN(");
sb.append(getWildCards(BranchNumber.size())).append(")");
sb.append("AND ORDERDATE BETWEEN ? and ? WITH UR");
String query = sb.toString();
PreparedStatement statement =
connection.prepareStatement(query);
for(int i=0 ; i<BranchNumber.size() ;i++)
{
statement.setInt(i+1,BranchNumber.get(i).getBranch());
}
ResultSet resultSet = statement.executeQuery();
{
while (resultSet .next()) {
Order order1 = new Order();
order1.setOrdernumber(resultSet.getInt("ordernumber"));
orders.add(order1);
}
}
}
catch (SQLException e) {
e.printStackTrace();
}
return orders;
}
Can someone please explain me what i am doing wrong here and how i can get the expected preparedstatement,below is the formatted query coming in my log and error message recorded,
SELECT ORDER_NUMBER as ordernumber,SERVICE_TYPE as service FROM .ORDER WHERE
BRANCH_NUMBER IN(?) + AND ORDERDATE BETWEEN ? AND ? WITH UR
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-104,
SQLSTATE=42601, SQLERRMC=ORDER DATE BETWEEN ? AND;H_NUMBER IN(?) + AND;
<order_siblings_by>, DRIVER=3.63.75
at com.ibm.db2.jcc.am.fd.a(fd.java:679)
Each ? in the PrepareStatement should be assigned a value. Here is an example adopted from here :
String updateString =
"update " + dbName + ".COFFEES " +
"set SALES = ? where COF_NAME = ?";
PreparedStatement updateSales = con.prepareStatement(updateString);
updateSales.setInt(1, 500); //set value to first `?`
updateSales.setString(2, "roasted"); //set value to second `?`
I've read H2 docs about storing objects in database. There is special SQL type OTHER and methods setObject and getObject. I've tried this code:
PreparedStatement statement = null;
try {
statement = connection.prepareStatement("CREATE TABLE PUBLIC.foo (name VARCHAR(64) NOT NULL, data OTHER NULL);");
statement.execute();
} finally {
statement.close();
}
statement = null;
try {
statement = connection.prepareStatement("INSERT INTO PUBLIC.foo (name, data) VALUES(?,?);");
statement.setString(1, "lololo");
statement.setObject(2, new String[]{"foo", "bar"});
statement.execute();
}finally {
statement.close();
}
But I've got the exception:
org.h2.jdbc.JdbcSQLException: Ше�тнадцатирична� �трока �одержит неше�тнадцатиричные �имволы: "(foo, bar)"
Hexadecimal string contains non-hex character: "(foo, bar)"; SQL statement:
INSERT INTO PUBLIC.foo (name, data) VALUES(?,?) -- (?1, ?2) [90004-191]
What is wrong?
I believe this is what you were look for (Even I was).
You just need to create a column in your table with type as 'other'.
See 'create table testobj2(obj other)'
Look at my Sample code :
static String DB_DRIVER = "org.h2.Driver";
static String DB_CONNECTION = "jdbc:h2:./test2";
static String DB_USER = "";
static String DB_PASSWORD = "";
public static void benchmarkH2Inserts() {
try {
Class.forName(DB_DRIVER);
Connection dbConnection = DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
String createQry = "create table testobj2(obj other)";
String insertQuery = "insert into testobj2(obj) values(?)";
String selectQuery = "select * from testobj2";
// dbConnection.setAutoCommit(false);
dbConnection.prepareStatement(createQry).executeUpdate();
long lStartTime = System.nanoTime();
for(int i=0; i<10000; i++) {
dbConnection.setAutoCommit(false);
CloudElement_Circuit obj = new CloudElement_Circuit();
obj.setNrm8DesignId(1230L);
PreparedStatement preparedStatement = dbConnection.prepareStatement(insertQuery);
preparedStatement.setObject(1,obj);
preparedStatement.execute();
dbConnection.commit();
}
long lEndTime = System.nanoTime();
long output = lEndTime - lStartTime;
System.out.println("benchmarkH2Inserts() : Elapsed time in nanoseconds: " + output);
System.out.println("benchmarkH2Inserts() : Elapsed time in milliseconds: " + output / 1000000);
//Selecting
PreparedStatement preparedStatement = dbConnection.prepareStatement(selectQuery);
ResultSet rs = preparedStatement.executeQuery();
while(rs.next()) {
CloudElement_Circuit obj = (CloudElement_Circuit) rs.getObject("obj");
System.out.println("Fetched Object : " + obj.getNrm8DesignId());
}
dbConnection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Note that 'CloudElement_Circuit' is a Serialized class.
Look at 'OTHER Type' here : http://www.h2database.com/html/datatypes.html
H2 Example : https://www.javatips.net/blog/h2-database-example
Try this approach
List<String> genre = new ArrayList<String>();
String comma="";
StringBuilder allGenres = new StringBuilder();
for (String g: genre) {
allGenres.append(comma);
allGenres.append(g);
comma = ", ";
}
Then you can pass it like this
preparedStmt.setString (2, allGenres.toString());