SQL query to retrieve data according to train_number - mysql

I want to retrieve all the trains with the given coach type that runs between the source and destination from the database in ascending order based on train number;
I am trying this query.This is a JDBC code to fetch the trains. I couldn't figure out what is wrong in this.
`import java.sql.*;
import java.util.*;
import java.io.*;
public class TrainManagementSystem {
public ArrayList <Train> viewTrain (String coachType, String source, String destination){
// Fill your code here
Connection myConn =null;
PreparedStatement myStmt = null;
ResultSet myRes = null;
ArrayList <Train> trainArr = new ArrayList<>();
try{
Properties props = new Properties();
FileInputStream in = new FileInputStream("database.properties");
props.load(in);
in.close();
String driver = props.getProperty("DB_DRIVER_CLASS");
if (driver != null) {
Class.forName(driver) ;
}
myConn = DriverManager.getConnection(
props.getProperty("DB_URL"),
props.getProperty("DB_USERNAME"),
props.getProperty("DB_PASSWORD"));
myStmt = myConn.prepareStatement("SELECT * from train WHERE source = ? AND destination = ? AND ? != 0 ORDER BY train_number");
myStmt.setString(1,source);
myStmt.setString(2,destination);
myStmt.setString(3,coachType);
myRes = myStmt.executeQuery();
while(myRes.next()){
trainArr.add(new Train(
myRes.getInt("train_number"),
myRes.getString("train_name"),
myRes.getString("source"),
myRes.getString("destination"),
myRes.getInt("ac1"),
myRes.getInt("ac2"),
myRes.getInt("ac3"),
myRes.getInt("sleeper"),
myRes.getInt("seater")));
}
return trainArr;
}catch(Exception exc){
exc.printStackTrace();
return null;
}
}
}
coachType=ac1,ac2,ac3,sleeper,seater;

In my opinion there are two approaches:
make a SELECT without the condition on the parametrized column (derived from coachType) and filter the results in your Java code. You'll get all the trains with the desired source and destination, ordered by train_number
myStmt = myConn.prepareStatement("SELECT * from train WHERE source = ? AND destination = ? ORDER BY train_number");
myStmt.setString(1,source);
myStmt.setString(2,destination);
myRes = myStmt.executeQuery();
and then, in your loop on the resultset,
while(myRes.next()) {
if (myRes.getInt(coachType) != 0) { // excludes records with column derived from coachType != 0
trainArr.add(new Train(
myRes.getInt("train_number"),
myRes.getString("train_name"),
myRes.getString("source"),
myRes.getString("destination"),
myRes.getInt("ac1"),
myRes.getInt("ac2"),
myRes.getInt("ac3"),
myRes.getInt("sleeper"),
myRes.getInt("seater")));
}
}
To avoid SQL Injection you can make an apparently useless query:
firstStmt = myConn.prepareStatement("SELECT column_name FROM information_schema.columns WHERE table_schema = ? AND table_name = ? AND column_name = ?");
firstStmt.setString(1, table_schema); // a variable with your schema name
firstStmt.setString(2, "train");
firstStmt.setString(3, coachType);
safeQueryRes = firstStmt.executeQuery();
safeCoachTypeColName = safeQueryRes.next().getString("column_name");
In this way you can use concatenation in your final query, avoiding SQL Injection, as if someone puts some hacking string in your coachType input variable, the first query will fail and nothing dangerous will happen. Otherwise, if the first query will be executed without a SQL Injection, you'll get the "real-and-SQL-Injection-safe" column name that you can use to create your final query with string concatenation:
myStmt = myConn.prepareStatement("SELECT * from train WHERE source = ? AND destination = ? AND " + safeCoachTypeColName + " != 0 ORDER BY train_number");
myStmt.setString(1,source);
myStmt.setString(2,destination);
myRes = myStmt.executeQuery();

Related

How can refresh a ResultSet in Java

I want to use a MySQL with JDBC in a loop, because I have to poll a table frequently for new data which comes in from other clients. But even if I close the ResultSet, the connection and the statement, is the old result at the next round still there. I cannot get a new result, unless I restart the program. What is my mistake?
I condensed the code for the necessary.
import java.sql.*;
public class Eventmgr {private static String in_text;
private static String in_typ;
private static Connection connection;
private static String URL = "jdbc:mysql://xxx.xxx.x.x:3306/xxxx";
private static String username = "xxx";
private static String password = "xxx";
public static void start() throws SQLException {
while(loop_count > 0) {
if (loop == false) {
loop_count = loop_count -1;}
connection = DriverManager.getConnection(URL, username, password);
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select id, nummer, text, typ from inbox order by id asc limit 1") ;
while(rs.next()) {
in_id = rs.getString("id");
in_nummer = rs.getString("nummer");
in_text = rs.getString("text");
in_typ = rs.getString("typ");}
connection.close();
stmt.close();
rs.close();
System.out.println("still running");
}
}
}
Anybody has an idea what my problem is?
Thanks in advance
I am stupid, and it was my mistake...
The problem is. I check on the variable "in_id" and if there is no new result "while(rs.next())" dont deliver a new value, so I need to reset that variable with "in_id = null;" at the end of the loop.
Now it works...

Import JSON Files to SQL Server with SSIS

The JSON file has 2 parts (Nested) and I just could import the first one I don't know why, any idea for this? The first column from the second part showed me NULL in database
This is the JSON file format:
My code is:
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
String jsonFileContent = File.ReadAllText(#"C:\Json XLM project SSIS\FileSample.JSON");
JavaScriptSerializer js = new JavaScriptSerializer();
List<Order> orders = js.Deserialize<List<Order>>(jsonFileContent);
foreach (Order order in orders)
{
Output0Buffer.AddRow();
Output0Buffer.TrackingNumber = order.TrackingNumber;
Output0Buffer.LocalReferenceNumber = order.LocalReferenceNumber;
Output0Buffer.TotalShipmentPieces = order.TotalShipmentPieces;
Output0Buffer.TotalShipmentValue = order.TotalShipmentValue;
Output0Buffer.ShipmentCurrency = order.ShipmentCurrency;
Output0Buffer.ShipmentGrossWeight = order.ShipmentGrossWeight;
Output0Buffer.ShipmentNetWeight = order.ShipmentNetWeight;
Output0Buffer.BorderTransportMode = order.BorderTransportMode;
Output0Buffer.ConveyanceDetail = order.ConveyanceDetail;
Output0Buffer.TransportId = order.TransportId;
Output0Buffer.Region = order.Region;
Output0Buffer.WarehouseLocation = order.WarehouseLocation;
Output0Buffer.InvoiceNumber = order.InvoiceNumber;
Output0Buffer.InvoiceDate = order.InvoiceDate;
Output0Buffer.ItemCategoryId = order.ItemCategoryId;
Output0Buffer.InsuredValue = order.InsuredValue;
Output0Buffer.SoldByShipmentPartyAddressId = order.SoldByShipmentPartyAddressId;
}
}
Thanks in advance.

JDBC SQL aliasing not working

I am trying to run the following query in my java web application:
SELECT platform AS "Platform" FROM edb.cases
The web-app is working fine and is able to execute all queries however whenever I use an alias (through 'AS'), the resultant data-set gives me a null value for the alias. In fact, despite using an alias for the column 'platform' in the above query, the resultant data-set has a null value for the key 'Platform' but gives me the correct value for the key 'platform' (which is the original name of the column).
Now the actual sql statement which I need to execute is a bit more complex with select statements and left joins on the same table twice using aliases, like so:
SELECT numOne.platform , numTwo.platform AS 'PlatformTwo' FROM edb.cases LEFT JOIN
edb.platform as numOne ON (numOne.rank = cases.platform) LEFT JOIN edb.platform as numTwo ON
(numTwo.rank = cases.highestPlatform) WHERE cases.index = 1000
The problem is that the resultant data-set contains the correct value for the key 'platform' (for numOne table) but the keys 'PlatformOne' and 'PlatformTwo' DO NOT EXIST. The aliases are not working!
I have tried both the statements in MySql workbench and they work fine.
Please do not hesitate to ask for more information.
EDIT:
The code that prepares the query and sends it to the database:
public static List<Map<String, Object>> executeQuery(final String query,
Map<Integer, Object> data) {
List<Map<String, Object>> result = null;
try {
Connection conn = createConnection();
PreparedStatement pstmt = null;
pstmt = conn.prepareStatement(query);
if(data != null) {
pstmt = createPreparedStatement(pstmt, data);
}
System.out.println(pstmt.toString());
//The GET_CASE_FOR_INDEX query uses the executequery function in the else block:
if((pstmt.toString().indexOf("INSERT") >= 0) || (pstmt.toString().indexOf("UPDATE") >= 0)) {
pstmt.executeUpdate();
} else {
ResultSet rs = pstmt.executeQuery();
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
result = new ArrayList<Map<String, Object>>();
/*
* Get the next row of the ResultSet 'rs' and insert a Map of the Column/Value pair
* into the ArrayList of Maps 'result'
*/
while(rs.next()) {
Map<String, Object> row = new HashMap<String, Object>(columns);
for(int i=1; i <= columns; i++) {
try {
row.put(md.getColumnName(i), rs.getObject(i));
} catch(Exception e) {
System.out.println(md.getColumnName(i));
System.out.println(row);
e.printStackTrace();
}
}
result.add(row);
}
}
destroyConnection(conn);
pstmt.close();
} catch(SQLException e) {
//TODO
e.printStackTrace();
}
return result;
}
The function creating the prepared statement:
//creates a prepared statement by checking the type of the value that needs to be set.
private static PreparedStatement createPreparedStatement(
PreparedStatement pstmt, Map<Integer, Object> data) {
try {
for(Integer key : data.keySet()) {
Object value = data.get(key);
System.out.println(key);
if(data.get(key).equals(Types.NULL)) {
pstmt.setNull(key, Types.INTEGER);
} else if(value.getClass().equals(Integer.class)) {
pstmt.setInt(key, (Integer) value);
} else if(value.getClass().equals(String.class)) {
pstmt.setString(key, (String) value);
} else if(value.getClass().equals(Date.class)) {
pstmt.setDate(key, (Date) value);
} else if(value.getClass().equals(Timestamp.class)) {
pstmt.setTimestamp(key, (Timestamp) value);
}
}
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pstmt;
}
And the code snippet which uses the executeQuery function to execute the query and sends it to the web template:
Map<Integer, Object> data_details = new HashMap<Integer, Object>();
data_details.put(1, parameter_ID);
List<Map<String, Object>> details = DBUtility.executeQuery(DBQuery.GET_CASE_FOR_INDEX, data_details);
webContext.setVariable("details", details);//This is where the template variable is being set
System.out.println(details);
The GET_CASE_FOR_INDEX query is :
SELECT numOne.platform , numTwo.platform AS 'PlatformTwo' FROM edb.cases LEFT JOIN
edb.platform as numOne ON (numOne.rank = cases.platform) LEFT JOIN edb.platform as numTwo ON
(numTwo.rank = cases.highestPlatform) WHERE cases.index = ?
When I print the details hash map (which is the result data-set) the key PlatformTwo is entirely absent!
You are using the .getColumnName method of ResultSetMetaData, which returns the name of the underlying column (if available). .getColumnLabel will return the column alias as defined by SELECT ... AS ....
To illustrate, the following Java code
PreparedStatement ps = conn.prepareStatement(
"SELECT platform AS Platypus FROM cases");
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println(String.format(
".getColumnName returns \"%s\"",
rsmd.getColumnName(1)));
System.out.println(String.format(
".getColumnLabel returns \"%s\"",
rsmd.getColumnLabel(1)));
returns
.getColumnName returns "platform"
.getColumnLabel returns "Platypus"

Using JAVA API update Rally Team membership

My Java API compares Team members from another application with Rally. The compared results is updated in Rally. It takes the reference of Project name and Res name.
The code throws "java.lang.IndexOutOfBoundsException: Index: 0, Size: 0" error. I coudn't spot the error. Could some one help? Following is the code and the output
package teammembership;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.rallydev.rest.RallyRestApi;
import com.rallydev.rest.request.QueryRequest;
import com.rallydev.rest.response.QueryResponse;
import com.rallydev.rest.request.UpdateRequest;
import com.rallydev.rest.response.UpdateResponse;
import com.rallydev.rest.util.Fetch;
import com.rallydev.rest.util.QueryFilter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.io.*;
import java.sql.*;
import javax.xml.parsers.DocumentBuilder;
import org.apache.soap.util.xml.*;
import org.w3c.dom.*;
//import org.json.*;
//import static projectteammembers.JsonUtil.getJsonValue;
public class TeamMembership {
public static Connection makeConnection(String propertiesFile) throws SQLException, Exception {
Connection conn = null;
DocumentBuilder docBuilder = XMLParserUtils.getXMLDocBuilder();
Document doc = docBuilder.parse(new File(propertiesFile));
// Retrieve database parameters
Element database = (Element) doc.getElementsByTagName("database").item(0);
String url = database.getAttribute("url");
String serviceId = database.getAttribute("serviceId");
String username = database.getAttribute("username");
String password = database.getAttribute("password");
String host = url.substring(url.indexOf("//"), url.indexOf(";"));
String connectString = "jdbc:oracle:thin:#" + host + "/" + serviceId;
// Load JDBC Driver
String driverClass = "oracle.jdbc.driver.OracleDriver";
Class.forName(driverClass);
try {
conn = DriverManager.getConnection(connectString, username, password);
} catch (SQLException ex) {
throw new SQLException(ex);
} catch (Exception ex) {
throw new Exception(ex);
}
return conn;
}
public static void main(String[] args) throws URISyntaxException, IOException, SQLException {
String host = "https://rally1.rallydev.com";
String username = "username#abc.com";
String password = "password";
//String userRef = "";
String applicationName = "update team membership";
//int queryLimit = 4000;
Connection conn = null;
String propertiesFile = "";
propertiesFile = "c:/app/c/properties_prod.xml";
String projid = "";
String resid = "";
//String returnValue = "";
String selectString = "";
RallyRestApi restApi = new RallyRestApi(
new URI(host),
username,
password);
restApi.setApplicationName(applicationName);
System.out.println(restApi.getWsapiVersion());
try {
conn = makeConnection(propertiesFile);
// Select compared records of Team member present in table1 not in table2
selectString += "select Prj_name ";
selectString += ",res_name";
selectString += " from CUST_table1_v c ";
selectString += " WHERE NOT EXISTS( select 1 from CUST_table2_v r";
selectString += " where c.prj_name = r.Prj_name and c.res_name = r.res_name)";
// Create select statement
Statement st = (Statement) conn.createStatement();
// Execute select statement
ResultSet rs = st.executeQuery(selectString);
while (rs.next()) {
projid = rs.getString("Prj_name");
resid = "(" + rs.getString("res_name") + ")";
System.out.println(projid);
System.out.println(resid);
QueryRequest projectRequest = new QueryRequest("Project");
projectRequest.setFetch(new Fetch("Name"));
projectRequest.setQueryFilter(new QueryFilter("Name", "=", projid));
QueryResponse projectQueryResponse = restApi.query(projectRequest);
JsonObject projectObj = projectQueryResponse.getResults().get(0).getAsJsonObject();
QueryRequest userRequest = new QueryRequest("User");
userRequest.setFetch(new Fetch("UserPermissions", "TeamMemberships"));
userRequest.setQueryFilter(new QueryFilter("DisplayName", "contains", resid));
QueryResponse userQueryResponse = restApi.query(userRequest);
System.out.println(userQueryResponse);
JsonObject userObject = userQueryResponse.getResults().get(0).getAsJsonObject();
//JsonObject projectObj = new JsonObject(projid);
String userRef = userObject.get("_ref").toString();
System.out.println("Found User with Ref: " + userRef);
JsonArray existTeamMemberships = (JsonArray) userQueryResponse.getResults().get(0).getAsJsonObject().get("TeamMemberships");
// add or remove projects for user
existTeamMemberships.add(projectObj);
// Setup update fields/values for Team Membership
JsonObject updateUserTeamMembershipObj = new JsonObject();
updateUserTeamMembershipObj.add("TeamMemberships", existTeamMemberships);
UpdateRequest updateTeamMembershipsRequest = new UpdateRequest(userRef, updateUserTeamMembershipObj);
UpdateResponse updateTeamMembershipResponse = restApi.update(updateTeamMembershipsRequest);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
restApi.close();
conn.close();
}
}
}
Following is the error out put
v2.0
DT-E2E Automation
(tmanjunath)
com.rallydev.rest.response.QueryResponse#193d23b
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:635)
at java.util.ArrayList.get(ArrayList.java:411)
at com.google.gson.JsonArray.get(JsonArray.java:92)
at teammembership.TeamMembership.main(TeamMembership.java:125)
BUILD SUCCESSFUL (total time: 11 seconds)
You have a List (an ArrayList to be exact) which contains nothing (no single object) and you try to access the first object (which doesn't exist). That's what the error tells you. You try to access index 0 (the first position in the list) but there is no element in it (so the size is 0). It happens around line 125. Since your formatting in the question doesn't seem to be correct, I can only guess which line in your question is line 125 (and I don't want to read 125 lines of code by the way). So I think the exception occurs here:
JsonObject userObject = userQueryResponse.getResults().get(0).getAsJsonObject();
Try to track it down. Make sure the list returned from userQueryResponse.getResults() contains something:
list = userQueryResponse.getResults();
System.out.println(list.size());
If not, that's your problem. If you cannot solve it, ask a specific question about this problem without posting 150 line of code.
get("_ref").toString() used to work with the older versions, and the code you refer to is older. When using 2.0.4 jar (which by default uses the most recent version of WS API in production, v2.0) replace all instances of it with get("_ref").getAsString().
For example,
String userRef = userObject.get("_ref").toString();
will generate java.lang.NullPointerException: key == null

How to correctly return special Spanish characters from a MS Access db with jdbc-odbc driver

How can you return special characters from a Ms access (.accdb or .mdb) database using the jdbc-odbc driver for MS Acess databases?
Converting from bytes of the result set(bytes[] bt = rs.getbytes(index_of_field) and then new String (bt, "UTF-8") or even new String (bt, "iso-8859-1")) or getting the string (rs.getString()) won't work and you need a valid way to do it.
The way to get special characters like (some other special characters may also be returned successfully, however, that case hasn't been analyzed yet):
Á,É,Í,Ó,Ú,á,é,í,ó,ú,Ü,ü,Ñ,ñ
and format all the returned string correctly (I mean the queried fields) the following procedure must be followed.
Before the connection to the DB is donde, and before querying the database, we must define a property parameter like the charset:
Properties props;
props = new Properties();
props.put ("charSet", "iso-8859-1");
Then we need to add props to the database connection. In the end, this is the final code you need.
String dbPath = "C:/example/directory/myDatabase.accdb";
Properties props;
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String connURL="jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+dbPath;
try {
props = new Properties();
props.put ("charSet", "iso-8859-1");
con = DriverManager.getConnection(connURL, props);
stmt = con.createStatement();
stmt.execute("select "field+" from "+tableName); // query exec
rs = stmt.getResultSet(); // query resultset
rsMetaData = rs.getMetaData(); // resultset metadata
} catch (SQLException ex) {
return false;
}
Then you just need to return the value of each field as a string (remember to save the string in an aux variable, in case you want to use it more than once, since you can just run rs.getString() once):
String resultString;
if( rs != null){
while( rs.next() ){ // this while may be surrounded with a try-catch
// Fields will be displayed for every row in the DB
// indexField must start from 1 !
for (int indexField = 1; indexField<=rsMetaData.getColumnCount(); indexField++){
resultString = rs.getString(field_index);
System.out.println(This is the field of column number "+indexField+": "+resultString);
} // for close
} // while close
} // if close