I have a rather sticky situation:
I have been tasked with designing an application that will read the contents of a table from a MySQL database into a two-dimensional string array, scalable to 100.
The schema for the table is:
id = INT(11)
Username = VARCHAR(100)
Password = VARCHAR(45)
UserType = VARCHAR(10)
Full Name = VARCHAR(100)
Age = INT(11)
DOB = DATE
Location = VARCHAR(100)
Record_Created = DATETIME
The issue is that I cannot read this to a file and then to the application for security reasons (contains actual admin account information). Can anyone think of an efficient way of doing this?
.... into a two-dimensional string array, scalable to 100.
I take it that you mean the array can have up to 100 elements.
If so, then one solution is to preallocate an array of size 100 x 9, then query and read the table rows and populate the array.
A second solution is to query, read the table rows, populate a list-of-arrays, and use List.toArray to extract the list contents into a 2-D array.
A final solution is to use select ... count to find the number of rows, and use that to allocate a 2-D array with the correct size. Then proceed as per the first solution.
However, using a 2-D array is a bad idea from an O-O design perspective. Instead, you should declare a class with a field for each of the 9 columns, and then represent the table contents as an array or list of that class.
I implemented the following design for my above question:
public static String[][] Table() throws SQLException
{
String[][] Table = null;
table = conn.createStatement();
String sql = "select * from usersTable";
ResultSet rs = table.executeQuery(sql);
rs.last();
int rowNumb = rs.getRow();
ResultSetMetaData rsmd = rs.getMetaData();
int columnS = rsmd.getColumnCount();
rs.beforeFirst();
dbTable= new String[rowNumb][columnS];
int i=0;
while(rs.next() && i<rowNumb && rowNumb<100)
{
for(int j=0;j<columnS;j++)
{
Table[i][j] = rs.getString(j+1);
}
i++;
}
return Table;
}
Related
I have a Java program reading data from an Access database where the table is created dynamically each time, and the number of columns varies depending on the data populated.
The table has columns as shown below. Only columns RowID and StatusOfProcessing are fixed and will be at the end.
column1,column2,column3, ... columnN,RowID,StatusOfProcessing
Below is piece of code
String str = "SELECT TOP 50 * FROM Dynamic_table WHERE StatusOfProcessing='0'";
resultSet = stmt.executeQuery(str);
When reading data from the ResultSet, does it always have columns in the order listed above, or should I use
String str = "SELECT TOP 50 column1,column2,column3 .... columnN,RowID,StatusOfProcessing FROM Dynamic_table WHERE StatusOfProcessing='0'";
resultSet = stmt.executeQuery(str);
Can someone clarify?
SELECT * will normaly return columns in the order in which they were created, e.g., the order in which they appeared in the CREATE TABLE statement. However, bear in mind that in addition to retrieving the value of a column by its index, as in
int col1value = resultSet.getInt(1);
you can also retrieve the value in a given column by referring to its name, as in
int col1value = resultSet.getInt("column1");
Furthermore, if you need to see the actual order of the columns or verify the names and types of the columns in a ResultSet you can use a ResultSetMetaData object to get that information.
I need to get the latest entry from my database, but not the autoincrement.
This function is in my databasehandler:
public int getLatestRouteNumber()
{
int number = 0;
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT MAX("+ KEY_ROUTENUMBER + ") FROM " + TABLE_LOCATIONS;
Cursor c = db.rawQuery(query, null);
if (c.moveToFirst() && c != null) {
number = c.getInt(3);
}
return number;
}
it craches at the line where "number = c.getInt(3).
The third column in my database exists and has data in it.
The error I'm gettin is "Couldn't read row 0, col 3 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it." I only need one value in the entire database, not even an entire row.
You have only one column in cursor but trying to get value of 3rd column... Tat is the error
Change it to getInt(0);
The returned result-set has nothing to do with table columns in your case. You should use
number = c.getInt(0);
Your resultset contains just one column and one row, basically a scalar value, it doesn't matter how many columns you have in your table, what you should consider here is the value you obtain from your query In your case just one value. Use
getInt(0)
have you tried something like this :
String query = "SELECT MAX("+ KEY_ROUTENUMBER + ") as my_max FROM " + TABLE_LOCATIONS;
And :
columnIndex = c.getColumnIndexOrThrow("my_max");
number = c.getInt(columnIndex );
That's better than using indexes, indexes may be wrong if the raw query changes.
getInt (3) returns the value of the 3rd column returned by the query. Your query only had 1 column.
Change getInt (3) to getInt (0)
"c.getInt(3);" does not get the value from the column in your table, it gets it from the column in your cursor.
And you only selected one column into your cursor.
So I believe it should be "c.getInt(1);"
I have a table Users in my database with columns phone no and region. In my GUI, I have a JList from where the user can select one or more regions, and accordingly I need to send out messages to the phone numbers with matching region.
The problem I'm facing is in retrieving the phone numbers from the database.
This is my code
final JList listRegion = new JList(list);
listRegion.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
listRegion.setVisibleRowCount(3);
JScrollPane scroll = new JScrollPane(listRegion);
scroll.setBounds(113, 254, 123, 50);
frame.getContentPane().add(scroll);
I'm storing the selected list values like this
Object[] areaList = listRegion.getSelectedValues();
Now I need to retrieve all the numbers with their corresponding regions matching the regions in areaList and need to store them in an array. I have tried something like this. But it seems to be wrong.
for( int i=0; i<areaList.length ; i++){
String sql2 = "select phone_no from users where region = areaList["+i+"]";
result = statement.executeQuery(sql2);
while(result.next()){
String numbers = result.getString(1);
//System.out.println(numbers);
}
}
I am poor with arrays. Hence not able to do it. Please guide me with the correct way of doing this.
You are not able to access the areaList variable from sql. Probably you need something like (not tested):
String sql2 = "select phone_no from users where region in (";
for( int i=0; i<areaList.length ; i++){
sql2 += "\'"+ areaList[i]+"\'";
if (i<areaList.length-1)
sql2+=",";
}
sql+=")";
result = statement.executeQuery(sql2);
while(result.next()){
String numbers = result.getString(1);
//System.out.println(numbers);
}
Also note that you should use a PreparedStatement, instead building the sql manually, this way you will be protected by sql injection issues.
I have following structure figured table which name student.
Here, I want to shuffle these data according to its first column id, with receptive their data. I have try this code:
public void shuffleStudent(int[] ar) {
Random rnd = new Random();
for (int i = ar.length - 1; i >= 0; i--) {
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
}
and getting from this
int [] t= db.shuffleJokes(cur.getString(cur.getColumnIndex("id")));
or
Cursor cur = db.shuffleJokes(cur.getString(cur.getColumnIndex("id")));
But these two could not work. And problem this type
The method shuffleJokes(int[]) in the type DatabaseHelper is not applicable for the arguments (String)
My question is if my suffleStudent function is correct or not, if correct. So how to get in suffleStudent.java. Thanks in advance.
your shuffle-function looks fine, but sending in a string when the function expects an array of int doesn't make sense. I guess cur is a database cursor. You need to read the entire database in to an array, then pass this array to the shuffle-function.
A completely different approach is to add a new colum to the database table, put a random number in this colums for each record, and the select order by this column. This would do the shuffeling in the database rather than in your code, which would probably be faster. (You probably need an index though)
I'm trying my best but I am lost right now. I know that this is horrible code but can someone just try to help me with the syntax and the overall problem if you're really ambitious. Thank you.
This is the SQL schema:
create table Person(
id int primary key,
name varchar(255) not null
);
create table Band(
id int primary key,
name varchar(255),
style varchar(255)
);
create table memberOf(
person int references Person(id),
band int references Band(id),
primary key(person, band)
);
Here is my horribly written program so far:
import java.sql.*;
public class DegreeNumber {
public static void degreesOfSeparation(int origin) throws Exception {
//Loads driver.
Class.forName("com.mysql.jdbc.Driver");
// Makes connection to server
Connection c = DriverManager.getConnection
("jdbc:mysql://cursa.ccs.neu.edu/test");
//Create a new prepared Statement that makes a
temporary table that can hold people in bands
PreparedStatement temp = c.prepareStatement
("create temporary table CurrentBand (
id int primary key);
");
//Execute query, creates table above
temp.execute();
//Create prepared statement to insert people of band into table
PreparedStatement insert = c.prepareStatement
("insert into CurrentBand (id)
select m.musician
from memberOf m
where ? = m.band;");
//Get Bands in table
PreparedStatement getBands = c.prepareStatement
("select b.id
from Bands b");
ResultSet bands = getBands.executeQuery();
int bandCount = 1;
//Sets parameter to first band on list
insert.setInt(1, bands.getInt(bandCount));
//Execute bands being inserted
insert.execute();
//Gives back ResultSet with band listed
PreparedStatement returnCurrentBand = c.prepareStatement
("select * from CurrentBand");
//Execute to give back CurrentBand records
ResultSet currentBand = returnCurrentBand.executeQuery();
//Creates table to hold musicians
PreparedStatement createDegree = c.prepareStatement
("create temporary table Degrees(
id int,
name varchar(255),
degree int,
primary key (id))");
//Execute to create table
createDegree.execute();
//Insert original Person into table Degrees
PreparedStatement insertOrig = c.prepareStement
("insert into Degrees (id, name, degree)
select p.id, p.name, 0
from Person p
where p.id = ?");
insertOrig.setInt(1, origin);
insertOrig.execute();
int count = 1;
//If there are still bands left on list,
while {(!bands.isAfterLast()){
PreparedStatement thisRound = c.prepareStatement
("insert into Degrees (id, name, degree)
select p.id, p.name, ?
from Person p, memberOf m, currentBand c
where p.id = m.musician
and m.band = c.id");
thisRound.setInt (1, count);
count++;
PreparedStatement truncate = c.prepareStatement("truncate table currentBand");
truncate.execute();
bandCount++;
insert.execute();
bands.next();
}
//means all bands have been gone through, find unique people, make new table & sort and print out
PreparedStatement createFinal = c.prepareStatement
("create table Final (
name varchar(255),
degree int,
primary key (name, degree))");
createFinal.execute();
PreparedStatement makeFinal = c.prepareStatement(
("insert into Final (name, degree)
select unique (d.name, d.degree)
from Degrees d
sort by degree asc, name asc");
makeFinal.execute();
ResultSet final = c.prepareStatement("select * from Final").executeQuery();
while (final.next()) {
System.out.println("Musician Name " + final.getString("name") +
" Degree " + rs.getInt("degree"));
You terribly need a DAO. Also take a look at this thread.
The problems you are encountering are mostly due to poor abstraction and design. It's good that you realize that this isn't a great piece of code. To give you a bit of incite about exactly why this is bad, let's consider the following problems with the class you presented.
It's not Object-Oriented. It's merely
a procedure statically tucked into a
class.
It throws the generic Exception. We won't get much of a chance to
handle errors outside of its scope.
Every time you use this function (I wouldn't even call it a method),
you make a new connection to the
database. That's pretty costly.
Tables in your database aren't well represented as first-class objects in your Java program. They suffer from weak abstraction and can't have their details encapsulated. This is mostly what's contributing to your feeling that this is poor code.
This isn't a very testable function. Break this function into many methods, and pass parameters to each of them to get their work done.
It's long, making it rather incomprehensible. Aim for methods of 5-15 lines.
It uses temporary tables. That'll kill efficiency when you can well work in number.
The problem isn't well documented. I understand from the code that it has to do with bands and people, but how does this relate to degrees of freedom? Make the problem and solution obvious.
I feel that if you address these critical areas, you can refactor towards a better solution.