CSV reading in java - java

Im having trouble reading from a CSV file
final String DELIMITER = ",";
Scanner fileScan = null;
Scanner dataSetScan = null;
String dataSet = null;
String sql = "";
File users = new File("user.txt");
String nickname = "";
String lastname = "";
String firstname = "";
String cartype = "";
String personimage = "";
String carimage = "";
int user_id = 0;
try {
fileScan = new Scanner(users);
} catch (Exception e) {
System.out.println(e);
}
while(fileScan.hasNext()){
dataSet = fileScan.nextLine();
dataSetScan = new Scanner(dataSet);
dataSetScan.useDelimiter(DELIMITER);
nickname = dataSetScan.next();
lastname = dataSetScan.next();
firstname = dataSetScan.next();
cartype = dataSetScan.next();
personimage = dataSetScan.next();
carimage = dataSetScan.next();
sql += "INSERT INTO users VALUES (";
sql += user_id++ + ", ";
sql += "'" + nickname + "', ";
sql += "'" + lastname + "', ";
sql += "'" + firstname + "', ";
sql += "'" + cartype + "', ";
sql += "'" + personimage + "', ";
sql += "'" + carimage + "' ";
sql += ");\n";
}
The above code wont work on the example file
alice,Wonder-Land,Alice,red Vauxhall Corsa,alice.jpg,alice_car.jpg
bob,Kett,Robert,,,
charlie,Carlos,Don,,,
However, it works just fine when there is a comma at the end of the line. (hvaing a comma here is not an option)
What can i do to make this work? It must be to do with my delimeter i think
Thank you

I wouldn't recommend using your own parser for CSV. CSV is surprisingly complex with little gotchas everywhere.
For instance, in CSV, it is legal to quote a column value with a comma in it
3 columns in this file
abc,"value1,value2",def
I recommend this library for java, it's very easy to use.
http://opencsv.sourceforge.net/
EDIT - May 2013
Since writing this post, I have switched to this library, which supports the CSV "standard" better and is actively developed.
http://supercsv.sourceforge.net/

Are you getting a NoSuchElementException from the following line?
carimage = dataSetScan.next();
If so you just need to wrap that with a hasNext check and perform a null check when you build your string.
if(dataSetScanner.hasNext()){
carimage = dataSetScan.next();
}
else{
carimage = null;
}
...
sql += carimage == null ? "NULL" : "'" + carimage + "' ";

I would recommend testing each token before inserting it,
But to answer your question, add an if condition before the last dataSetScan.next() call like so:
if (dataSetScan.hasNext()){
carimage = dataSetScan.next();
}

Related

How to change dynamic object query to criteria builder or better performence

Hello I wrote a join query but I do not have a relational annotations on my entities. I like to change my query for a better performance. Is there any other way to do it
#Override
public List<Object[]> search(String code, String name, String username, String shopName, String startDate, String endDate) {
Query query = null;
StringJoiner stringJoiner = new StringJoiner(" AND ");
stringJoiner.add("SELECT sthLogin.sthId, sth.sthMobileNumber, sth.createdDate, sth.expiryDate, sth.brandingName, sth.shopName" +
" FROM tbl_sth_login_credentials sth INNER JOIN tbl_maintain_sth_profile sth ON sth.Id = sth.sthPrimaryId WHERE sth.deletionStatus = 'N' ");
if(StringUtils.isNotEmpty(sthCode))
stringJoiner.add("stlogin.code = '" + sthCode + "'");
if(StringUtils.isNotEmpty(sthName))
stringJoiner.add("sth.brandingName = '" + sthName + "'");
if(StringUtils.isNotEmpty(username))
stringJoiner.add("sthLogin.sthMobileNumber = '" + username + "'");
if(StringUtils.isNotEmpty(shopName))
stringJoiner.add("sth.shopName = '" + shopName + "'");
if(StringUtils.isNotEmpty(shopName) && StringUtils.isNotEmpty(endDate))
stringJoiner.add("sth.createdDate BETWEEN '" + startDate + "' AND '" + endDate + "' ");
query = entityManager.createNativeQuery(stringJoiner.toString());
return query.getResultList();

For loop inside SQL Create Table query

I am trying to Create a table Model (i, y1, y2 .... yd) in Vertica using JAVA. Column i is integer and all others are REAL. I used the following code to create it. However it is showing syntax error at or near null. Does anybody know what that means? The connection works for the program.
public void createMODEL(int d)
{
int x;
try
{
Statement stmt = conn.createStatement();
String createquery = "CREATE TABLE MODEL ( "
+ "i integer primary key ";
for (x=1;x<=d;x++) createquery+= " , " + Y[x] + " REAL ";
createquery += ")";
stmt.executeUpdate(createquery);
}
catch (Exception e)
{
System.out.println("Error while executing create model query");
System.out.print(e);
System.exit(0);
}
}
Y is defined as follows -
String Y[]=new String[100];
I guess you should check if Y[x] is not null:
Statement stmt = conn.createStatement();
String createquery = "CREATE TABLE MODEL ( "
+ "i integer primary key ";
for (x=1;x<=d;x++) {
if (Y[x] != null) createquery+= " , " + Y[x] + " REAL ";
}
createquery += ")";
stmt.executeUpdate(createquery);
This works for me for MySQL. Try this.
String Y[] = new String[100];
Y[0] = "h";
Y[1] = "ha";
Y[2] = "hat";
Y[3] = "hati";
Y[4] = "hatim";
System.out.println("Your columns array : " + Arrays.deepToString(Y));
String createquery = "CREATE TABLE MODEL ( " + "i integer primary key ";
for (int i = 0; i < Y.length; i++) {
if (Y[i] != null)
createquery += " , " + Y[i] + " REAL ";
}
createquery += ");";
System.out.println("Your create query : " + createquery);

Java - how to insert data into data base from txt file

I am wondering how to read in a file and insert into a table in my data base. I written this:
String customerFile = "customer.txt";
Connection myConnect = ....
Statement mySt = myConnect.createStatement();
mySt.executeUpdate(..create customer table..);
int SSN;
String CNAME;
String GENDER;
int AGE;
String PROFESSION;
String line;
String[] tokens;
FileReader file1 = new FileReader(customerFile);
BufferedReader buffer1 = new BufferedReader(file1);
//throw away first line
line = buffer1.readLine();
//continue with rest of file
while((line = buffer1.readLine()) != null)
{
tokens = line.split(",");
SSN = Integer.parseInt(tokens[0]);
CNAME = tokens[1];
GENDER = tokens[2];
AGE = Integer.parseInt(tokens[3]);
PROFESSION = tokens[4];
String insertString = "insert into customer values ( " + SSN + ", " + CNAME + "," +
GENDER + ", " + AGE + ", " + PROFESSION +")";
mySt.executeUpdate(insertString);
}
I thought this was the right way to insert into a table. However, the issue I am having with is that the variables aren't being read in the right way.
Example rows:
3648993,Emily,male,63,Consulting
5022334,Barbara,male,26,Finance
With the example above, I would want to have a table with 2 rows and 5 columns but the code I put on top gave me an error when it reaches the name. I am not sure where the issue is.
You should replace insertString with
myConnect = getConnection();
myConnect.setAutoCommit(false);
File file = new File(fileName);
fis = new FileInputStream(file);
pstmt = myConnect.prepareStatement("insert into customer( " + SSN + ", " + CNAME + "," +
GENDER + ", " + AGE + ", " + PROFESSION +") values (?,?,?,?,?)");
pstmt.setString(1, SSN);
pstmt.setString(2, AGE);
....
pstmt.executeUpdate();
myConnect.commit();
Source : Insert text file into MySQL
Make sure you put quotes around string fields, so instead of:
String insertString = "insert into customer values ( " + SSN + ", " + CNAME + "," +
GENDER + ", " + AGE + ", " + PROFESSION +")";
do:
String insertString = "insert into customer values ( " + SSN + ", '" + CNAME + "','" +
GENDER + "', " + AGE + ", '" + PROFESSION +"')";
Normally I do such things in two steps:
1) create a java class representing just one row of the textfile. This class is instantiated with a line from the txt-file and this single row is parsed and the fields are created, so I have for every single field a getter and a setter having the right fieldtype. within this class I'm able to perform tests and corrective actions if a field is wrong or even empty.
2) I create a Writer-class that reads the textfile line by line and writes every single line into the db, mostly starting with the second line, because the first line contains the header. I strictly use PreparedStatement and use batchwriting, at the end, when file looping is finished, write the batch to the DB with PreparedStatement.executeBatch() and then I close down all DB-objects.

Getting rid of comma

Im newbie in java and need help with getting rid of a comma in an sql query. anyone who can guide me in the right direction?
query = "UPDATE " + tablename + " SET ";
for(int i=0; i< columnnames.size(); i++)
{
query+= "'" + columnnames.get(i) + "' = '" + row[i] + "',";
}
query = StripLastComma(query); //Not sure how to do this in Java.
query +="' WHERE " + FirstColumn + " = '" + rowstandard + "'";
You can do this:
query = query.substring(0, query.length()-1);
at the place of "//Not sure how to do this in Java.".
But also:
1) As Makoto wrote use PreparedStatement. Also read a bit
about SQL injection and how to protect yourself from it.
2) Using StringBuilder instead of String would be better for your case.
That's because, it seems you use String and it is immutable.
So when deleting the last comma, you're actually creating a
whole new String object which is really not needed as other pointed
out in their comments.
Disregarding the already mentionned SQL injection problem, I would use a StringBuilder and do it like this to avoid that last comma.
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.append("UPDATE " + tablename + " SET ");
for(int i = 0; i < columnnames.size(); i++) {
if (i != 0) {
queryBuilder.append(",");
}
queryBuilder.append("'" + columnnames.get(i) + "' = '" + row[i] + "'");
}
queryBuilder.append("' WHERE " + FirstColumn + " = '" + rowstandard + "'");
query = queryBuilder.toString();
Firstly, you have a bug: you are quoting your column names when you should not.
The comma issue is easiest handled by making the logic different for the first iteration and putting the comma before the content, which neatly handles the edge case of there being only one column:
if (i > 0)
query += ",";
query += columnnames.get(i) + " = '" + row[i] + "'";
Your code is vulnerable to SQL injection, but if the only client is your own code (ie you know the new values of the columns are "safe") it's OK.

Inserting mysql entry if doesn't exist, updating if it does exist java

I'm wanting to insert an entry if it does not exist otherwise update the entry, I couldn't use the ON DUPLICATE KEY UPDATE, I got confused with the syntax. So I tried to do something like this:
final String QUERY = "REPLACE INTO skills SET VALUES (" + insert(player) + ") WHERE playername = '" + player.getUsername() + "'";
statement.execute(QUERY);
statement.close();
connection.close();
}
private static String insert(Player player) {
String stringToReturn = "'" + player.getUsername() + "',";
for (int index = 0; index < 25; index++) {
stringToReturn += player.getSkills().getLevels()[index] + "," + ((int) player.getSkills().getXp()[index]) + ",";
}
stringToReturn = stringToReturn.substring(0, stringToReturn.length() - 1);
return stringToReturn;
}
But that's incorrect syntax so I was wondering how I could do this?
playername is primary key
I think the correct syntax to make ON DUPLICATE KEY UPDATE work for you is:
"INSERT INTO skills (playerName, otherColumn)
VALUES ('" + player.getUsername() + "', '" + insert(player) +"')
ON DUPLICATE KEY UPDATE otherColumn = VALUES(otherColumn)";

Categories