I am trying to connect to VSAM files in z/OS in Java.
I have tried using VSE Redirector Connector with below code:
package test;
import java.sql.DriverManager;
import java.sql.ResultSetMetaData;
public class TestVSAM {
public static void main(String[] args) {
String vsamCatalog = "VSESP.USER.CATALOG";
String flightsCluster = "USERNAME.TEST.KSDS1";
String flightsMapName = "FLIGHTS_MAP";
String ordersCluster = "FLIGHT.ORDERING.ORDERS";
String ordersMapName = "ORDERS_MAP";
String ipAddr = "XXX.XXX.XXX.XXX";
String userID = "XXXXXX";
String password = "XXXXXX";
Integer port = 123;
try {
System.out.println("VSE IP address------------->" + ipAddr);
System.out.println("Your VSE user ID----------->" + userID);
System.out.println("Password------------->" + password);
System.out.println("Port------------->" + port);
java.sql.Connection jdbcCon;
java.sql.Driver jdbcDriver =
(java.sql.Driver) Class.forName("com.ibm.vse.jdbc.VsamJdbcDriver").newInstance();
// Build the URL to use to connect
String url = "jdbc:vsam:" + ipAddr;
// Assign properties for the driver
java.util.Properties prop = new java.util.Properties();
prop.put("port", port);
prop.put("user", userID);
prop.put("password", password);
// Connect to the driver
jdbcCon = DriverManager.getConnection(url, prop);
// Get a statement
java.sql.Statement stmt = jdbcCon.createStatement();
// Execute the query ...
java.sql.ResultSet rs = stmt.executeQuery(
"SELECT * FROM " + vsamCatalog + "\\" + flightsCluster + "\\" + flightsMapName);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
System.out.println("Key------------>" + rsmd.getColumnLabel(i));
}
rs.close();
stmt.close();
} catch (Exception e) {
System.out.println(e);
}
I'm getting this error:
My Questions:
Can we use VSE Redirector Connector to read VSAM files? If yes, then how can we resolve the above error and get connected?
Is there any other method to access VSAM files thru Java?
Have you considered something like: https://www.ibm.com/docs/en/sdk-java-technology/8?topic=jzos-zfile
Related
I am reading some data from a SQLite table by JDBC. Where the table has following columns:
[Id:Integer], [parentId:Integer], [Name:String], [Type:Integer], [Data:BLOB]
Now from the BLOB data I need to create some Unique identifier, thus the same BLOB will generate the same identifier every time. As of now I am creating a byte array from the blob and then making a toString of it. Will it guarantees the uniqueness? And Is it CPU cycle efficient? As I have a lots of such records to process. Please suggest. Following is my code for the same.
public static void scanData(String dbName) {
String url = "jdbc:sqlite:C:/dbfolder/" + dbName;
try (Connection con = DriverManager.getConnection(url);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from someTable");) {
while (rs.next()) {
Integer type = rs.getInt("Type");
if (type != null && type.equals(3)) {
Integer rowId = rs.getInt("Id");
Integer parentId = rs.getInt("ParentID");
String name = rs.getString("Name");
System.out.println("rowId = " + rowId);
System.out.println("parentId = " + parentId);
System.out.println("name = " + name);
System.out.println("type = " + type);
InputStream is = rs.getBinaryStream("Data");
if (is != null) {
byte[] arr = IOUtils.toByteArray(is);
if (arr != null) {
System.out.println("Data = " + arr.toString());
}
}
System.out.println("---------------------------");
}
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
}
** IOUtils is used of : org.apache.commons.io.IOUtils
To generate a unique identifier you can use org.apache.commons.codec.digest.DigestUtils to generate sha256 so that it will be unique for every blob type
DigestUtils.sha256Hex(new FileInputStream(file));
Convert the Blob to inputStream
blob.getBinaryStream();
I need to convert result set into csv for any database (not just postgres)
Empty csv file is being created when I use opencsv.
Here's the code of doGet method in the servlet:
final String JDBC_DRIVER = "org.postgresql.Driver";
final String DB_URL = "jdbc:postgresql://localhost:5432/postgres";
// Database credentials
final String USER = "postgres";
final String PASS = "12345";
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Database Result";
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " +
"transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n");
PreparedStatement ps = null;
Connection conn = null;
try {
// Register JDBC driver
Class.forName("org.postgresql.Driver");
// Open a connection
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// Execute SQL query
//stmt = conn.createStatement();
String sql = "SELECT * FROM users";
ps = conn.prepareStatement(sql,
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = ps.executeQuery();
/*if(rs.next()){
System.out.println("Name = "+rs.getString("first_name"));
}*/ //prints name so rs is not empty
//rs.first();
CSVWriter writer = new CSVWriter(new FileWriter("Test.csv"));
//even tried with seperator '\t' or ','
writer.writeAll(rs, true);
writer.close();
out.println("</body></html>");
// Clean-up environment
rs.close();
ps.close();
conn.close();
} catch (SQLException se) {
//Handle errors for JDBC
se.printStackTrace();
} catch (Exception e) {
//Handle errors for Class.forName
e.printStackTrace();
} finally {
//finally block used to close resources
try {
if (ps != null)
ps.close();
} catch (SQLException se2) {
}// nothing we can do
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
se.printStackTrace();
}//end finally try
} //end try
Not sure what's the error. Tried different way but csv is always empty.
Even tried writer.flush(), rs.beforeFirst(), rs.first() nothing works.
Is your problem that you do not see data in the html - if that is the case then instead of creating a new FileWriter in the CSVWriter just pass in you out variable.
Or is it that you checked the Test.csv and file and nothing is there? if so then first check to see if there is actually data in the result set by adding the following after executeQuery:
rs.last();
long numberOfRecords = rs.getRow();
rs.beforeFirst();
System.out.println("Number of Users in table is: " + numberOfRecords);
Im getting an image from server as InputStream and then saving it to mySQL database. It works when I use Thread.sleep(5000);. But if I dont use it no picture is saved to the DB or only one picture and half of it or less. So I understand that the program needs time writing image to the database, but how much time? This is the question, I would like to know exactly when it finished writing image to the database and can start with the next image. Below is my code:
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
int ID = rs.getInt(1);
String myName = rs.getString(2);
try {
String myCommand = "take picture and save /mydir/mydir2/mydir3" + myName + ".png";
telnet.sendCommand(myCommand); // Here taking a picture via telnet
// Thread.sleep(5000);// If I uncomment this line it works
String sqlCommand = "UPDATE my_table SET Picture = ? WHERE ID ='" + ID +"';";
PreparedStatement statement = conn.prepareStatement(sqlCommand);
String ftpUrl = "ftp://"+server_IP+"/mydir/mydir2/mydir3" + myName + ".png;type=i";
URL url = new URL(ftpUrl);
URLConnection connUrl = url.openConnection();
//Thread.sleep(5000); // If I uncomment this line, it works too.
InputStream inputStreamTelnet = connUrl.getInputStream();
statement.setBlob(1, inputStreamTelnet);
int row = statement.executeUpdate();
if (row > 0) {
System.out.println("A picture was inserted into DB.");
System.out.println("Value of row(s) : " + row);
}
} catch (Exception e) {
e.printStackTrace();
}
} // End of while
I would expect to put the waiting(sleep) after InputStream inputStreamTelnet = connUrl.getInputStream(); but it doesnt work when I put the sleep after this line. It works only when the sleep is before. Could someone explain me why and I would like to avoid using Thread.sleep(5000); and instead would like to wait exact time or not wait at all which will make the program faster also there might be a case saving the picture can take more than 5 seconds or maybe saving the picture doesnt take time but opening the url connection. There are 2 sleep lines on the code when I uncomment one of them the program works(saves the images to mysql DB successfully). I also verified on the server that the images exist but in the end I dont see them in the mysql DB.
UPDATE : I removed the try block and telnet stuff now it works without waiting but I really need the telnet stuff...
UPDATE 2: After inspecting my telnet class found out that I forgot to apply a change I made to single line... now it works without wait!
Huh, I tested my code on JDK 1.7.0_67 / PostgreSQL 9.2 and it works well:
public class ImageLoader {
private static final int START_IMAGE_ID = 1;
private static final int END_IMAGE_ID = 1000;
private static final String IMAGE_URL = "http://savepic.net/%d.jpg";
public static void main(String[] args) throws SQLException, IOException {
Connection connection = DriverManager.getConnection("jdbc:postgresql://localhost:5432/test", "username", "password");
PreparedStatement imageStatement = connection.prepareStatement("INSERT INTO public.image VALUES(?, ?)");
for (int i = START_IMAGE_ID; i <= END_IMAGE_ID; i++) {
String imageUrl = String.format(IMAGE_URL, i);
URL url = new URL(imageUrl);
URLConnection urlConnection = url.openConnection();
imageStatement.setLong(1, i);
imageStatement.setBytes(2, read(urlConnection.getInputStream()));
int count = imageStatement.executeUpdate();
if (count != 1) {
throw new IllegalStateException("Image with ID = " + i + " not inserted");
} else {
System.out.println("Image (" + imageUrl + ") saved to database");
}
}
imageStatement.close();
connection.close();
}
private static byte[] read(InputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1 << 15); // assume image average size ~ 32 Kbytes
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
byte[] buffer = new byte[1 << 10];
int read = -1;
while ((read = bufferedInputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, read);
}
return byteArrayOutputStream.toByteArray();
}
}
I am using the JDBC driver to connect to a mysql database and using the "LOAD DATA INFILE" command in my java application to load(insert) a text file into the database. I am getting the following error: Data truncation: Data too long for column xxx at row 1.
However if I load the same text file manually by logging into the database and entering the SQL manually, the data loads fine.
Can someone pelase tell me what the error might be?
I am running this on Red Hat Enterprise Linux Server release 5.8 and the jdk version is 1.5.0_16 if that helps
This is the function used to load the data
public static void loaddata(Connection conn, String filename, String tablename)
{
try{
Statement stmt = null;
stmt = conn.createStatement();
File file = new File(filename);
file.getAbsolutePath().replace("\\", "\\\\");
String cmd = "LOAD DATA INFILE '"
+ file.getAbsolutePath().replace("\\", "\\\\")
+ "' INTO TABLE " + tablename + " FIELDS TERMINATED BY \'^\'";
stmt.executeUpdate(cmd);
System.out.println("cmd :" + cmd);
}
catch(SQLException sqle){
sqle.printStackTrace();
}
}
This is the function to create the JDBC connection:
public static Connection createConnection()
{
Connection conn=null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
}
catch(Exception e) {
e.printStackTrace();
}
try {
String url = ""; //URL mentioned in the actual code
conn = DriverManager.getConnection(url, user, pass);
} catch (SQLException sqe1) {
sqe1.printStackTrace();
}
return conn;
}
Does anyone have any ideas of how to connect Access 2010 to java jdbc. I use this method, but when I call it, it doesn't work:
public void loadDb(){
try{
Class.forName("sun.jdbc.JdbcOdbcDriver");
File f = new File(System.getProperty("user.dir"))
con = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Acess Driver (*.mdb, *.accdb)}; DBQ="+ f.getPath() + "//db//JavaAccess.accd","","");
st = con. createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
}catch(ClassNotFoundException e){e.printStackTrace();
}catch(SQLException e){e.printStackTrace();}
}
//con and st are already defined
According to msdn it should be sun.jdbc.odbc.JdbcOdbcDriver. So replace this line of code:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Spelling error? Perhaps this line:
con = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Acess Driver (*.mdb, *.accdb)}; DBQ="+ f.getPath() + "//db//JavaAccess.accd","","");
should be
con = DriverManager.getConnection("jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ="+ f.getPath() + "//db//JavaAccess.accd","","");
Access has 2 C's
Create connection
public static Connection getConnection() {
String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
String url = "jdbc:odbc:anime"; //anime is the database
String username = "ipieluser"; //leave blank if none
String password = "ipielpassword"; //leave blank if none
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
return DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
How to call:
public static void main(String args[]) {
try {
Connection conn = getConnection();
Statement st = conn.createStatement();
st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM localTable");
//get and displays the number of columns
ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
System.out.println("resultSet MetaData column Count=" + numberOfColumns);
st.close();
conn.close();
} catch(Exception e) {
System.out.println(e.getMessage());
}
}
Use UCanAccess JDBC Driver :
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); // can be omitted in most cases
Connection conn=DriverManager.getConnection("jdbc:ucanaccess://<mdb or accdb file path>",user, password);
e.g.:
Connection conn=DriverManager.getConnection("jdbc:ucanaccess://c:/pippo.mdb");
So for your example it will be
con = DriverManager.getConnection("jdbc:ucanaccess://"+f.getPath()+"/db/JavaAccess.accd")
Rishab's reply helped me to connect to my access database.
I did following correction in the code:
Instead of
String url = "jdbc:odbc:anime"; //anime is the database
I did
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=" + "d://institute//institutedata.accdb";
I explicitly defined driver and full database name with path and extension.
As today only we face the same problem and found that to check the version of java if your
version of java if the version of the java is above 7 then the sun.jdbc.odbc.JdbcOdbcDriver will not be supported so just check the version of the java.