I've found suggestions online to store the queried data into an ArrayList and then to convert the ArrayList into an Array. Below is the code that I have and it appears that I'm not doing this correctly. The SQL syntax is correct (I tested in my MySQL). Any suggestions on how to correct my code would be helpful, thanks!
public static void dxNameExerciseID(){
//String dxName = name;
//String result = null;
try{
con = DriverManager.getConnection(url, user, password);
pst = con.prepareStatement("SELECT * FROM exercise,condition_exercise,diagnosis WHERE exercise.exercise_id = condition_exercise.exercise_id_fk AND condition_exercise.diagnosis_id_fk = diagnosis.diagnosis_id AND diagnosis.diagnosis_name = 'Adductor Strain';");
rs = pst.executeQuery();
ArrayList<String> list= new ArrayList<String>();
while (rs.next()) {
list.add(rs.getString("exercise_id"));
String[] result = new String[list.size()];
result = list.toArray(result);
for(int i =0; i<result.length; i++){
System.out.println(result[i]);
}
}
}catch(SQLException ex){
}finally {
try {
if (rs != null){
rs.close();
}
if (pst != null){
pst.close();
}
if (con != null){
con.close();
}
}catch(SQLException ex){
}
}
//return result;
}
This should work better. See how you first create your ArrayList of String by iterating over your ResultSet, and once your list is complete you can create the Array of Strings.
ArrayList<String> list= new ArrayList<String>();
while (rs.next()) {
list.add(rs.getString("exercise_id"));
}
String[] result = new String[list.size()];
result = list.toArray(result);
for(int i =0; i<result.length; i++){
System.out.println(result[i]);
}
BTW: your finally block is unsafe. If rs.close() fails you won't close your connection.
Poor code in every way. Catch blocks should never be empty. You close your resources incorrectly. If something goes wrong, how will you know? Pass the connection in, don't make the method responsible for getting it. Use PreparedStatement. This code should be thrown away so you can start again.
This should work - You were creating Array on each iteration which was the reason of your problem
while (rs.next()) {
list.add(rs.getString("exercise_id"));
}
String[] result = new String[list.size()];
result = list.toArray(result);
for(int i =0; i<result.length; i++){
System.out.println(result[i]);
}
Some of your code should be refactored
ArrayList<String> list= new ArrayList<String>();
while (rs.next()) {
list.add(rs.getString("exercise_id"));
}
String[] result = new String[list.size()];
result = list.toArray(result);
for(int i =0; i<result.length; i++){
System.out.println(result[i]);
}
Related
actually I have 10-30 dummies to get the value from txtCC, but i'd only used 3 dummies for example below..
So how do I get each values and save it directly to my database without using dummy? It's a big deal coz' my code was too large to compile using those dummies..
THANKS for any help..
private void bSaveActionPerformed(java.awt.event.ActionEvent evt)
{
// Save to database
String cc = txtCC.getText();
String delimiter = ",";
String[] temp;
temp = cc.split(delimiter);
for(int i = 0; i < temp.length; i++)
if(i==0) {
txtC1.setText(temp[0]);
txtC2.setText("0");
txtC3.setText("0"); }
else if (i==1) {
txtC1.setText(temp[0]);
txtC2.setText(temp[1]);
txtC3.setText("0"); }
else if (i==2) {
txtC1.setText(temp[0]);
txtC2.setText(temp[1]);
txtC3.setText(temp[2]); }
try {
String cc1 = txtC1.getText(); int CC1 = Integer.parseInt(cc1);
String cc2 = txtC2.getText(); int CC2 = Integer.parseInt(cc2);
String cc3 = txtC3.getText(); int CC3 = Integer.parseInt(cc3);
int opt = JOptionPane.showConfirmDialog(null,"Are you sure you want to save this record? ");
if (opt == 0){
if(!txtC1.getText().equals("0")) {
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String sql = "Select * from tbl_liqinfo";
rs = stmt.executeQuery(sql);
rs.next();
rs.moveToInsertRow();
rs.updateInt("CC", CC1);
rs.insertRow();
rs.close();
}
if(!txtC2.getText().equals("0")) {
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String sql = "Select * from tbl_liqinfo";
rs = stmt.executeQuery(sql);
rs.next();
rs.moveToInsertRow();
rs.updateInt("CC", CC2);
rs.insertRow();
rs.close();
}
if(!txtC3.getText().equals("0")) {
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String sql = "Select * from tbl_liqinfo";
rs = stmt.executeQuery(sql);
rs.next();
rs.moveToInsertRow();
rs.updateInt("CC", CC3);
rs.insertRow();
rs.close();
}
}
}
catch (SQLException err){
JOptionPane.showMessageDialog(FrmEmpLiquidation.this, err.getMessage());
}
}
Instead of using dummies, create simple small methods and make use of it. This will reduce you line of code. and also easy to understand.
private void bSaveActionPerformed(java.awt.event.ActionEvent evt){
// Save to database
String cc = txtCC.getText();
String delimiter = ",";
String[] temp;
temp = cc.split(delimiter);
for(int i = 0; i < temp.length; i++)
insertData(temp[i]);
}
public void insertData(final String data){
txtC1.setText(data);
try {
String cc1 = txtC1.getText(); int CC1 = Integer.parseInt(cc1);
int opt = JOptionPane.showConfirmDialog(null,"Are you sure you want to save this record? ");
if (opt == 0){
if(!txtC1.getText().equals("0")) {
stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String sql = "Select * from tbl_liqinfo";
rs = stmt.executeQuery(sql);
rs.next();
rs.moveToInsertRow();
rs.updateInt("CC", CC1);
rs.insertRow();
rs.close();
}
}
}
catch (SQLException err){
JOptionPane.showMessageDialog(FrmEmpLiquidation.this, err.getMessage());
}
}
I am trying to convert ResultSet to String[][] in Java webservice. It sounds very stupid to convert the Resultset to Strin[][]. The reason I am trying to do this is because Java webservice is called from .Net and it doesnt understand the ResultSet. I hoped it would had accepted the ResultSet as a DataTable but it didnt work out.
One of my problems is that the server I am trying to test my Java webservice is terrible and I cannot work very efficiently, so I cannot test everything.
this is my java webservice. I am trying to convert it to String[][] but it returns null. I think I am doing something wrong when I try to fill the String[][].
Is it correct way to get the rowCount and columnCount of ResultSet? what am I doing wrong?
public String[][] getValues()
{
String[][] arr;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/MLS_J", "sa", "12345");
java.sql.Statement stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
java.sql.ResultSet rslt = stmt.executeQuery("SELECT * FROM S_USERS");
// to get row count and column count
/////////////////////////////////////
int rowSize = 0;
try {
rslt.last();
rowSize = rslt.getRow();
rslt.beforeFirst();
}
catch(Exception ex) {
}
ResultSetMetaData rsmd = rslt.getMetaData();
int columnSize = rsmd.getColumnCount();
/////////////////////////////////////
arr = new String[rowSize][columnSize];
int i =0;
while(rslt.next() && i < rowSize)
{
for(int j=0;j<columnSize;j++){
arr[i][j] = rslt.getString(j);
}
i++;
}
rslt.close();
stmt.close();
conn.close();
return arr;
} catch (Exception e) {
return null;
}
}
it is your problem
java resultset starts from 1.. so change your getString method like this. And remain all codes fine.
while(rslt.next() && i < rowSize)
{
for(int j=0;j<columnSize;j++){
arr[i][j] = rslt.getString(j+1);
}
i++;
}
A simple way to get the row count is to use COUNT(*) for your case...
java.sql.ResultSet rslt = stmt.executeQuery("SELECT COUNT(*) FROM S_USERS");
I'm having a strange problem with the below code, it works fine when its run without the if else statements, but displays no results in the jtable when if else is used. Is there something stupid I'm missing here?
try {
Class.forName(dbClass);
Connection con = DriverManager.getConnection (dbUrl,dbUsername, dbPassword);
Statement stmt = con.createStatement();
String userQuery = "SELECT p_id AS 'Patient ID', forename AS 'Forename', surname AS 'Surname', address AS 'Address' FROM Patient WHERE surname LIKE '%"+s+"%'";
ResultSet userResult = stmt.executeQuery(userQuery);
if(!userResult.next())
{
JOptionPane.showMessageDialog(null, "No Results.");
{
else{
ResultSetMetaData rsMetaData =userResult.getMetaData();
DefaultTableModel dtm = new DefaultTableModel();
int cols = rsMetaData.getColumnCount();
Vector colName = new Vector();
Vector dataRows = new Vector();
for (int i=1; i<cols; i++){
colName.addElement(rsMetaData.getColumnName(i));
}
dtm.setColumnIdentifiers(colName);
while(userResult.next()){
dataRows = new Vector();
for(int j = 1; j<cols; j++){
dataRows.addElement(userResult.getString(j));
}
dtm.addRow(dataRows);
}
searchTable.setModel(dtm);
con.close();
}
} //end try
catch(ClassNotFoundException e) {
JOptionPane.showMessageDialog(null, "Database Error.");
e.printStackTrace();
}
catch(SQLException e) {
JOptionPane.showMessageDialog(null, "Database Error.");
e.printStackTrace();
}
I'm using netbeans for the GUI.
Thanks
The connection object (con) should be closed outside if/else block.
Beside, the userResult.next() was called twice in the else statement block..
You may fix it by replacing while() by do while loop:
do {
dataRows = new Vector();
for (int j = 1; j < cols; j++) {
dataRows.addElement(userResult.getString(j));
}
dtm.addRow(dataRows);
}
while (userResult.next());
Please include finally to handle closing the connection and removing the other resources.
Below is a generic class I wrote that calls a stored procedure on the server:
public class StoredProc {
Connection con = null;
ResultSet rs = null;
CallableStatement cs = null;
public StoredProc(String jdbcResource, String storedProcName){
this(jdbcResource, storedProcName, new String[0], new String[0]);
}
public StoredProc(String jdbcResource, String storedProcName, String[] params,String[] paramTypes){
Connection con = new databaseConnection(jdbcResource).getConnection();
//Get length of parameters and sets stored procs params (?, ?, ...etc)
String procParams = "";
int paramSize = params.length;
if(paramSize != 0){
for(int i = 0; i < paramSize; i++){
if(i == paramSize){
procParams += "?";
}else{
procParams += "?, ";
}
}
}
try{
CallableStatement cs = this.con.prepareCall("{?=call "+storedProcName+" ("+procParams+")}");
for(int j = 0; j < params.length; j++){
if (paramTypes[j].equalsIgnoreCase("Int")) {
int x = 0;
try{
x = Integer.parseInt(params[j]);
} catch(Exception e) {}
cs.setInt(j, x);
} else if (paramTypes[j].equalsIgnoreCase("Boolean")) {
boolean x = false;
try{
x = (params[j].equalsIgnoreCase("True")) || (params[j].equalsIgnoreCase("T")) || (params[j].equalsIgnoreCase("1")) || (params[j].equalsIgnoreCase("Yes")) || (params[j].equalsIgnoreCase("Y"));
} catch(Exception e) {}
cs.setBoolean(j, x);
} else if (paramTypes[j].equalsIgnoreCase("String")) {
cs.setString(j, params[j]);
}
}
}catch(Exception e){
System.out.println("---------------------------------------------");
System.out.println("Problem constructing callableStatement: "+e);
System.out.println("---------------------------------------------");
}
}
public ResultSet runQuery(){
try{
rs = cs.executeQuery();
}catch(SQLException e){
System.out.println("---------------------------------------------");
System.out.println("Problem executing stored procedure: "+e);
System.out.println("---------------------------------------------");
}
return rs;
}
public void runUpdate(){
try{
cs.executeUpdate();
}catch(SQLException e){
System.out.println("---------------------------------------------");
System.out.println("Problem executing stored procedure: "+e);
System.out.println("---------------------------------------------");
}
}
} //end of class
for some reason I'm getting a NullPointerException on the line I'm trying to construct a CallableStatement --> CallableStatement cs = this.con.prepareCall("{?=call "+storedProcName+" ("+procParams+")}");
The callable statement should look like this at run time:
cs = this.con.prepareCall({?=call getUnlinkedDirectdeposits()});
The stored proc is called this in the database: [dbo].[getUnlinkedDirectdeposits]
Any help would be appreciated!
Thanks in advance,
You are using the wrong "con" variable. In your method you're initialising a variable (local to the method) called con:
Connection con = new databaseConnection(jdbcResource).getConnection();
But then you use this.con, which is the con field of the StoredProc object you're currently executing in. Since it was never initialised, you get a NullPointerException.
Your Connection field is null!
You create a new Connection instance in StoredProc instead of assigning it to the field con of your class. But when trying to created the CallableStatement your are using the this.con which has not been set before.
I used the following codes to update column Clob in oracle, it seems to be okay and work properly, after performance testing, it reported that need consumed more than 200ms while the length of string is more than 130000. Is it any good way to improve it?
private void updateClobDetailsField(Map<Integer, String> idToDetails){
long s1 = System.currentTimeMillis();
Connection conn = null;
PreparedStatement pStmt = null;
ResultSet rset = null;
Map<Integer, Clob> idToDetailsClob = new HashMap<Integer, Clob>();
int BATCH_SIZE = CMType.BATCH_UPDATE_MAXSIZE;
try
{
conn = getConnection();
ServerAdapter adapter = ServerAdapter.getServerAdapter();
List<Integer> IDList = new ArrayList<Integer>();
for(Integer id : idToDetails.keySet()){
IDList.add(id);
}
List<Integer> tempIDList = new ArrayList<Integer>(IDList);
while(!tempIDList.isEmpty()){
int size = tempIDList.size() < BATCH_SIZE ? tempIDList.size() : BATCH_SIZE;
List<Integer> currentBatch = tempIDList.subList(0, size);
String inClause = SQLHelper.prepareInClause("ID",currentBatch.size());
pStmt = conn.prepareStatement("SELECT ID, DETAILS FROM PROGRAM_HISTORY WHERE " + inClause);
for(int i = 0; i < currentBatch.size(); i++){
pStmt.setInt(i+1, (currentBatch.get(i)));
}
rset = pStmt.executeQuery();
while(rset.next()){
int id = rset.getInt(1);
Clob detailsClob = rset.getClob(2);
Writer writer = adapter.getCharacterOutputStream(detailsClob);
String details = idToDetails.get(id);
if (details != null) {
writer.write(details);
}
writer.flush();
writer.close();
idToDetailsClob.put(id, detailsClob);
}
currentBatch.clear();
BaseSQLHelper.close(pStmt, rset);
}
int counter = 0;
pStmt = conn.prepareStatement("UPDATE PROGRAM_HISTORY SET DETAILS = ? WHERE ID = ?");
for(int i=0; i<IDList.size(); i++){
int index = 1;
Clob detailsClob = (Clob) idToDetailsClob.get(IDList.get(i));
pStmt.setClob(index++, detailsClob);
pStmt.setInt(index++, IDList.get(i));
pStmt.addBatch();
counter++;
if(counter % BATCH_SIZE == 0) {
pStmt.executeBatch();
pStmt.clearBatch();
counter = 0;
}
}
if(IDList.size() % BATCH_SIZE > 0) {
pStmt.executeBatch();
}
}
catch (SQLException se)
{
se.printStackTrace();
}
catch (IOException se)
{
se.printStackTrace();
}
finally
{
cleanup(conn, pStmt, null);
}
System.out.println(System.currentTimeMillis()-s1);
}
If I understand your code correctly, you are appending text to your details clob column.
Doing it in PL/SQL would be faster since you wouldn't have to fetch the clob across the network. For example you could prepare this statement:
DECLARE
l_details CLOB;
BEGIN
SELECT details INTO l_details FROM program_history WHERE ID = ?;
dbms_lob.append(l_details, ?);
END;
and bind currentBatch.get(i) and idToDetails.get(id).
Notice that you don't need an additional update with PL/SQL.
Execute your query with an updatable ResultSet so that you can update the data as you scroll through without separate update statements being executed.
You need to create your prepared statement with the resultSetConcurrency set to ResultSet.CONCUR_UPDATABLE. Check out the oracle documentation on dealing with streams for the various ways you can handle the clob data.