Solved

Want to create a .sql file from a .csv file using Java

Posted on 2010-09-23
11
779 Views
Last Modified: 2013-12-29
Dear fellow Java developers:

I have a very large data set in a .csv file, which I want to use to generate an equivalent .sql file for the purpose of a sql dump in a MySQL table.  I realize there are many tools that can do the conversion, I would like to know how to do this in java.  The data in my .csv files have the column headings in the very first row, there are no spaces after the commas, and the data in the csv file is not surrounded by quotation marks(" ").  The .csv file is structured as follows:

columnA,columnB,columnC,columnD,columnE
a1,111,-111,aaa,aa
b2,222,-222,bbb,bb
c3,333,-333,ccc,cc
d4,444,-444,ddd,dd
...
i9,999,-999,iii,ii

I want to read in a .csv file, and write out a .sql file where I am inserting into a table called "sampledata", that appears like this:

INSERT INTO `sampledata` (`columnA`, `columnB`, `columnC`, `columnD`, `columnE`) VALUES
("a1", 111, -111, 'aaa', 'aa'),
("b2", 222, -222, 'bbb', 'bb'),
("c3", 333, -333, 'ccc', 'cc'),
("d4", 444, -444, 'ddd', 'dd'),
...
("i9",999,-999,"iii","ii");

Thanks in advance to all who reply.




0
Comment
Question by:fsyed
11 Comments
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
this is a very simple example. it treats everything as a string. unless you know what field is numeric or not then you can change accordingly

You could test the data value but it could be alphanumeric so still has to be in quotes.

best way is to check the matching columnHeadings and do a check on that

Sample code opens a file called c:\temp\java.csv. You change it to your filename
Then look for INSERT INTO mytable and change it to your table

Results are currently displayed in the output window

Run it first to see if this is what you are after
private void CreateCSV() {
		String strLine;
		String baseSql;

		try {
			// Open CSV File
			FileInputStream fstream = new FileInputStream("C:/temp/java.csv");
			DataInputStream datastream = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(datastream));
			strLine = br.readLine();
			
			// Make an note of columns
			String[] columnHeadings = strLine.split(",");
			
			System.out.println("Column Headings: " + strLine);
			baseSql = "INSERT INTO mytable (";
			for (int i = 0; i < columnHeadings.length; i++) {
				baseSql = baseSql + columnHeadings[i];
				if (i < (columnHeadings.length-1)) {
					baseSql = baseSql + ",";
				}
			}
			baseSql = baseSql + ") VALUES (";
			
			while ((strLine = br.readLine()) != null) {
				String newSql = baseSql;
				String[] values = strLine.split(",");
				for (int i = 0; i < values.length; i++) {
					newSql = newSql + "'" + values[i] + "'";
					if (i < (values.length-1)) {
						newSql = newSql + ",";
					}
				}
				newSql = newSql + ");";
				System.out.println(newSql);
			}
			fstream.close();
			
		} catch (Exception e) {
			// file not found exception...
			e.printStackTrace();
		}
	}

Open in new window

0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
Example of what I was talking about earlier -read java.csv, write java.sql and check for numeric fields by checking column names. You might wanna do more validation checking etc etc etc but this should get you going
private void CreateCSV() {
		String strLine;
		String baseSql;

		try {
			// Open CSV File
			FileInputStream fstream = new FileInputStream("C:/temp/java.csv");
			FileWriter fwrite = new FileWriter("C:/temp/java.sql");
			DataInputStream datastream = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(datastream));
			strLine = br.readLine();
			
			// Make an note of columns
			String[] columnHeadings = strLine.split(",");
			
			System.out.println("Column Headings: " + strLine);
			baseSql = "INSERT INTO mytable (";
			for (int i = 0; i < columnHeadings.length; i++) {
				baseSql = baseSql + columnHeadings[i];
				if (i < (columnHeadings.length-1))
					baseSql = baseSql + ",";
			}
			baseSql = baseSql + ") VALUES (";
			
			while ((strLine = br.readLine()) != null) {
				String newSql = baseSql;
				String[] values = strLine.split(",");
				for (int i = 0; i < values.length; i++) {
					// Check for numeric columns
					if (columnHeadings[i].equals("columnB") || columnHeadings[i].equals("columnC"))
						newSql = newSql + values[i];
					else
						newSql = newSql + "'" + values[i] + "'";
					if (i < (values.length-1))
						newSql = newSql + ",";
				}
				newSql = newSql + ");";
				fwrite.write(newSql);
				System.out.println(newSql);
			}
			fwrite.flush();
			fwrite.close();
			fstream.close();
			
		} catch (Exception e) {
			// file not found exception...
			e.printStackTrace();
		}
	}

Open in new window

0
 
LVL 65

Assisted Solution

by:rockiroads
rockiroads earned 475 total points
Comment Utility
ok, just saw how you wanted the data

What I did was create several INSERT INTO statements

So this change should try make the sql look like what you want.
private static void CreateCSV() {
		String strLine;
		String baseSql;

		try {
			// Open CSV File
			FileInputStream fstream = new FileInputStream("C:/temp/java.csv");
			FileWriter fwrite = new FileWriter("C:/temp/java.sql");
			DataInputStream datastream = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(datastream));
			strLine = br.readLine();
			
			// Make an note of columns
			String[] columnHeadings = strLine.split(",");
			
			System.out.println("Column Headings: " + strLine);
			baseSql = "INSERT INTO sampledata (";
			for (int i = 0; i < columnHeadings.length; i++) {
				baseSql = baseSql + columnHeadings[i];
				if (i < (columnHeadings.length-1))
					baseSql = baseSql + ",";
			}
			baseSql = baseSql + ") VALUES ";
			fwrite.write(baseSql);
			
			strLine = br.readLine();
			while (strLine != null) {
				String newSql = "(";
				String[] values = strLine.split(",");
				for (int i = 0; i < values.length; i++) {
					// Check for numeric columns
					if (columnHeadings[i].equals("columnB") || columnHeadings[i].equals("columnC"))
						newSql = newSql + values[i];
					else
						newSql = newSql + "'" + values[i] + "'";
					if (i < (values.length-1))
						newSql = newSql + ",";
				}
				strLine = br.readLine();
				if (strLine != null)
					newSql = newSql + "),";
				else
					newSql = newSql + ");";
				fwrite.write(newSql);
				fwrite.flush();
				System.out.println(newSql);
			}
			fwrite.close();
			fstream.close();
			
		} catch (Exception e) {
			// file not found exception...
			e.printStackTrace();
		}
	}

Open in new window

0
 
LVL 26

Assisted Solution

by:ksivananth
ksivananth earned 25 total points
Comment Utility
use some opensourced framework like OpenCSV for preparing csv file, it will make you job easier and less error prone.
0
 

Author Comment

by:fsyed
Comment Utility
Thanks rockiroads for your prompt reply.  Your code appears to work, as I see the results from the System.out.  It appears exactly as I want it.  However, when I try to open the file, it appears to take way to long for some unusual reason.  The written file appears to be only 51.2MB but it seems to really drain the system resources as I try to open the file.  Any idea why this is?

Thanks again for all of your help.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 10

Expert Comment

by:Hegemon
Comment Utility
I used to use XSLT for this purpose, source data being in both CSV and XML formats.
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
can you try opening in wordpad or msword and not notepad.
I noticed the line breaks (in 2nd solution) appear properly but shows as one line in notepad.

let me try again with solution 3 to see if that is the case and to tweak it
0
 
LVL 65

Accepted Solution

by:
rockiroads earned 475 total points
Comment Utility
solution 3 code update forced the new line
private void CreateCSV() {
		String strLine;
		String baseSql;

		try {
			// Open CSV File
			FileInputStream fstream = new FileInputStream("C:/temp/java.csv");
			FileWriter fwrite = new FileWriter("C:/temp/java.sql");
			String newLine = System.getProperty("line.separator");
			DataInputStream datastream = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(datastream));
			strLine = br.readLine();
			
			// Make an note of columns
			String[] columnHeadings = strLine.split(",");
			
			System.out.println("Column Headings: " + strLine);
			baseSql = "INSERT INTO sampledata (";
			for (int i = 0; i < columnHeadings.length; i++) {
				baseSql = baseSql + columnHeadings[i];
				if (i < (columnHeadings.length-1))
					baseSql = baseSql + ",";
			}
			baseSql = baseSql + ") VALUES ";
			fwrite.write(baseSql);
			
			strLine = br.readLine();
			while (strLine != null) {
				String newSql = "(";
				String[] values = strLine.split(",");
				for (int i = 0; i < values.length; i++) {
					// Check for numeric columns
					if (columnHeadings[i].equals("columnB") || columnHeadings[i].equals("columnC"))
						newSql = newSql + values[i];
					else
						newSql = newSql + "'" + values[i] + "'";
					if (i < (values.length-1))
						newSql = newSql + ",";
				}
				strLine = br.readLine();
				if (strLine != null)
					newSql = newSql + "),";
				else
					newSql = newSql + ");";
				newSql = newSql + newLine;
				fwrite.append(newSql);
				fwrite.flush();
				System.out.println(newSql);
			}
			fwrite.close();
			fstream.close();
			
		} catch (Exception e) {
			// file not found exception...
			e.printStackTrace();
		}
	}

Open in new window

0
 

Author Comment

by:fsyed
Comment Utility
I am at work right now, so I haven't had a chance to implement your chages yet, however, I noticed that you didn't use a BufferedWriter object when using FileWriter.  Does that matter?

Thanks again for your prompt replies!
0
 
LVL 65

Expert Comment

by:rockiroads
Comment Utility
Probably better to use BufferedWriter. I think that has the newline character on the write statement unlike FileWriter. I just picked FileWriter as it was something quick to use. BufferedWriter would be more efficient as that is better to use for short writes.
0
 

Author Closing Comment

by:fsyed
Comment Utility
Thanks very much rockiroads for your solution, it worked!  I really appreciate your help.  Take care.
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now