I'm working a project(Full source code here) and as part of the project, I've created a Database class to make interfacing with the SQLite database easier and cleaner. I'm currently attempting to write a method that will use SELECT along with the given parameters to return a string array containing the results. The issue that I'm having is that when I run the program to test it, Eclipse throws java.sql.SQLException: no such column: 'MOVES'
But, when I look at the database in a GUI, it clearly shows the column that I'm trying to access, and when I execute just the sql in the same program, it's able to return the data.
This is the method that I've written so far:
public String[] get(String what, String table, String[] conds) {
try {
if (what.equals("*")) {
throw new Exception("'*' selector not supported");
}
c.setAutoCommit(false);
stmt = c.createStatement();
String sql = "SELECT " + what.toUpperCase() + " FROM " + table.toUpperCase();
if (conds.length > 0) {
sql += " where ";
for (int i = 0; i < conds.length; i++) {
if (i == conds.length - 1) {
sql += conds[i];
break;
}
sql += conds[i] + " AND ";
}
}
sql += ";";
System.out.println(sql);
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
if (table.toUpperCase().equals("DEX")) {
String id = "";//rs.getInt("id") + "";
String species = rs.getString("species");
String type1 = rs.getString("type1");
String type2 = rs.getString("type2");
String hp = rs.getInt("hp") + "";
String atk = rs.getInt("atk") + "";
String def = rs.getInt("def") + "";
String spa = rs.getInt("spa") + "";
String spd = rs.getInt("spd") + "";
String spe = rs.getInt("spe") + "";
String ab1 = rs.getString("ab1");
String ab2 = rs.getString("ab2");
String hab = rs.getString("hab");
String weight = rs.getString("weight");
return new String[] { id, species, type1, type2, hp, atk, def, spa, spd, spe, ab1, ab2, hab,
weight };
} else if (table.toUpperCase().equals("MOVES")) {
String name = rs.getString("NAME");
String flags = rs.getString("FLAGS");
String type = rs.getString("TYPE");
String full = rs.getString("LONG");
String abbr = rs.getString("SHORT");
String acc = rs.getInt("ACCURACY") + "";
String base = rs.getInt("BASE") + "";
String category = rs.getInt("CATEGORY") + "";
String pp = rs.getInt("PP") + "";
String priority = rs.getInt("PRIORITY") + "";
String viable = rs.getInt("VIABLE") + "";
return new String[] { name, acc, base, category, pp, priority, flags, type, full, abbr, viable };
} else if (table.toUpperCase().equals("LEARNSETS")) {
String species = rs.getString("SPECIES");
String moves = rs.getString("MOVES");
return new String[] { species, moves };
} else {
throw new Exception("Table not found");
}
}
rs.close();
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
return null;
}
Screencaps:
UPDATE:
I wanted to double-check that the database viewer I was using wasn't messed up, so I opened up the terminal and ran
sqlite3 git/Pokemon/data.db
pragma table_info(MOVES);
Receiving this in response:
0|SPECIES|TEXT|0||0
1|MOVES|TEXT|0||0
Finally figured it out, for anybody else having this issue, make sure that the data you're trying to get from the result set is actually included in it. For example, if I call SELECT SPECIES FROM DEX; the result set won't contain other things like id, type, or any of those other columns, it will ONLY contain the species column. I'm not sure why it took me so long to figure this out, but there you have it.
Related
I'm using a spring framework and the code I'm using won't work or check if the query is null, though I used a .isEmpty() method it doesn't mean that the query is empty. I wanted to make sure that my query is empty because a part of my code does invoke an id in which case I didn't even though its null so please help me T.T
public List<Object> searchEmployee(EmployeeSearchDto data) {
Session session = sessionFactory.openSession();
final String CRITERIA_EMPLOYEEID = "emp.employeeID =:id";
final String CRITERIA_EMPLOYEEID2 = "emp.employeeID LIKE:id";
final String CRITERIA_POSITION= "emp.positionID =:posID";
final String CRITERIA_DEPARTMENT="emp.departmentID =:deptID";
final String CRITERIA_WORKPLACE = "emp.workplaceID =:workID";
Boolean selected_dept = false;
Boolean selected_pos = false;
Boolean selected_work = false;
Boolean input_empID = false;
Boolean input_empName = false;
firstName = "";
middleName = "";
lastName = "";
completeName = "";
firstLastName = "";
List<String> criteria = new ArrayList<>();
List<Object> employees = null;
// checking the fields if all the fields is empty
try{
//one by one check the select field
String query = "Select"
+ " emp.employeeID,"
+"emp.firstName,"
+"emp.middleName,"
+"emp.lastName,"
+"pos.positionName,"
+"dept.deptName,"
+"work.workplaceName"
+"from Employee emp "
+ "INNER JOIN Department dept "
+ "ON emp.departmentID = dept.deptID "
+ "INNER JOIN Position pos "
+ "ON emp.positionID = pos.positionID "
+ "INNER JOIN Workplace work "
+ "ON emp.workplaceID = work.workplaceID ";
if(!data.isEmpty()) {
query = query.concat("WHERE ");
if(data.getEmployeeID()!="" && data.getEmployeeID()!=null) {
criteria.add(CRITERIA_EMPLOYEEID2);
System.out.println("Employee IDs");
input_empID = true;
}
if(data.getEmployeeName()!="" && data.getEmployeeName()!=null){
criteria.add(nameCriteriaHelper(data.getEmployeeName()));
System.out.println("Employee Name AKOOO");
input_empName = true;
}
if(data.getDepartmentID()!=0) {
criteria.add(CRITERIA_DEPARTMENT);
System.out.println("Dept ID ");
selected_dept = true;
}
if(data.getPositionID()!=0) {
criteria.add(CRITERIA_POSITION);
System.out.println("POS ID ");
selected_pos = true;
}
if(data.getWorkplaceID()!=0) {
criteria.add(CRITERIA_WORKPLACE);
selected_work = true;
}
query = query.concat(String.join(" OR ", criteria));
}
query = query.concat(" ORDER BY emp.joinDate DESC");
System.out.println("QUERY: " + query);
Query q = session.createQuery(query);
if(input_empID) {
q.setParameter("id", "%" + data.getEmployeeID() + "%");
}
if(input_empName) {
if(searchbyOne)
q.setParameter("inputName", "%" + data.getEmployeeName() + "%");
if(searchbyFandL)
q.setParameter("firstLastName", "%" +firstLastName+ "%");
if(searchbyCompName)
q.setParameter("completeName", "%" +completeName+ "%");
}
if(selected_dept) {
q.setParameter("deptID", data.getDepartmentID());
}
if(selected_pos) {
q.setParameter("posID", data.getPositionID());
}
if(selected_work) {
q.setParameter("workID", data.getWorkplaceID());
}
employees = (List<Object>) q.list();
}catch(Exception e){
e.printStackTrace();
}finally{
session.close();
}
return employees;
}
public String nameCriteriaHelper(String name) {
searchbyOne = false;
searchbyFandL = false;
searchbyCompName = false;
final String noOfTokens_1 = "CONCAT(emp.lastName,' ',emp.firstName, ' ',emp.middleName) LIKE :inputName";
final String noOfTokens_2 = "(CONCAT(emp.lastName, ' ', emp.firstName) LIKE :firstLastName "
+ "OR CONCAT(emp.firstName, ' ', emp.lastName) LIKE :firstLastName)";
final String noOfTokens_3 = "CONCAT(emp.lastName,' ',emp.firstName, ' ',emp.middleName) LIKE :completeName";
StringTokenizer stringTokenizer = new StringTokenizer(name);
int no_of_tokens = stringTokenizer.countTokens();
switch(no_of_tokens) {
case 1: searchbyOne = true;
return noOfTokens_1;
case 2: firstName = stringTokenizer.nextToken();
lastName = stringTokenizer.nextToken();
firstLastName = lastName + " " + firstName;
searchbyFandL = true;
return noOfTokens_2;
default: int counter = 0;
while( counter < (no_of_tokens - 2)) {
firstName = firstName.concat(stringTokenizer.nextToken() + " ");
counter++;
}
firstName = stringTokenizer.nextToken();
middleName = stringTokenizer.nextToken();
lastName = stringTokenizer.nextToken();
completeName = lastName + " " + firstName + " " + middleName;
searchbyCompName = true;
return noOfTokens_3;
}
You're using wrong order and wrong function to compare string:
Replace:
data.getEmployeeID()!="" && data.getEmployeeID()!=null
With
data.getEmployeeID() != null && !data.getEmployeeID().equals("")
Comparing string must use equals(). And check for null should be done first, before accessing the equals method
You should correct other conditions as above too.
Actually, the logic that Mr. Nguyễn provided here is faulty. An object or variable cannot both be null and initialized to a default value (such as foo == "") at the same time.
At the time of the logic check, if the String is in fact null, the second half of the logic statement will engage, checking to see if the String is equal to "", which will throw a null pointer exception. Instead of checking for both at the same time, check for one and then check for the other like so:
//since two logic checks are being performed,
//it is advantageous to put the data from the query
//into memory so you don't have to get the
//same result twice
String foo = data.getEmployeeID();
if (foo != null)
{
if (!(foo.equals("")))
{
//the result is neither null or empty
}
else
{
//the result is not null but it is empty
}
}
else
{
//the result is null
}
Following is my code which retrieves Rally data.
public static void main(String[] args) throws URISyntaxException, IOException {
String host = "examplehost";
String username = "exampleuser";
String password = "password";
String projectRef = "project";
String workspaceRef = "workspace";
String applicationName = "";
int queryLimit = 4000;
Connection conn = null;
String propertiesFile = "";
String projectValue = "";
String columnValue = "";
String returnValue = "";
RallyRestApi restApi = new RallyRestApi(
new URI(host),
username,
password);
restApi.setApplicationName(applicationName);
System.out.println(restApi.getWsapiVersion());
try{
QueryRequest projectRequest = new QueryRequest("Project");
projectRequest.setFetch(new Fetch("Name", "TeamMembers"));
projectRequest.setWorkspace(workspaceRef);
projectRequest.setProject(projectRef);
projectRequest.setScopedDown(true);
projectRequest.setQueryFilter(new QueryFilter("Name", "contains", "DT-"));
projectRequest.setLimit(queryLimit);
QueryResponse projectQueryResponse = restApi.query(projectRequest);
int count = projectQueryResponse.getResults().size();
System.out.println(count);
if(count > 0){
for (int i=0;i<count;i++){
JsonObject projectObject = projectQueryResponse.getResults().get(i).getAsJsonObject();
JsonObject obj = projectObject.getAsJsonObject();
projectValue = JsonUtil.getJsonValue(obj, "_refObjectName");
System.out.println("Project: " + projectValue);
int numberOfTeamMembers = projectObject.getAsJsonObject("TeamMembers").get("Count").getAsInt();
if(numberOfTeamMembers > 0) {
QueryRequest teamRequest = new QueryRequest(projectObject.getAsJsonObject("TeamMembers"));
JsonArray teammates = restApi.query(teamRequest).getResults();
//JsonObject teammates = restApi.query(teamRequest).getResults();
if (teammates instanceof JsonArray) {
JsonArray jsonarr = teammates.getAsJsonArray();
//returnValue += squote;
for (int j=0; j<jsonarr.size(); j++) {
if (j>0)
returnValue += "\n";
JsonObject tobj = jsonarr.get(j).getAsJsonObject();
if (obj.has("Name"))
columnValue = getJsonValue(tobj, "Name");
if (obj.has("_refObjectName"))
columnValue = JsonUtil.getJsonValue(tobj, "_refObjectName");
returnValue += columnValue;
System.out.println(columnValue);
}
//returnValue += squote;
}
//columnValue = JsonUtil.getJsonString(teammates);
//for (int j=0;j<numberOfTeamMembers;j++){
//JsonObject teamObject = teamQueryResponse.getResults().get(j).getAsJsonObject();
//System.out.println(teammates.get(j).getAsJsonObject().get("_refObjectName").getAsString());
//}
}
}
}
}catch(Exception e){
e.printStackTrace();
} finally{
restApi.close();
}
}
I'm trying to insert Project ID and the associated team members into db. For one Project ID there may be 1- 10 members, The count may differ for each project. In DB, there would be only two Column holding Project ID and User name. Could anyone help me with this request?
Hope it helps.
If you need more details, please do reply
Thanks
Sreer
From your comment above, the actual line that is failing is:
st.executeUpdate("INSERT INTO CUST_RALLY_TEAM_MEMBER " + "VALUES projectValue,columnValue)");
Here, you are literally passing this string to Oracle:
INSERT INTO CUST_RALLY_TEAM_MEMBER VALUES projectValue,columnValue)
You need to pass the values of those variables (you're also missing an open parenthesis:
st.executeUpdate("INSERT INTO CUST_RALLY_TEAM_MEMBER VALUES ('" + projectValue + "','" + columnValue + "')");
This assumes that the cust_rally_team_member contains only these two columns, if not (and as a best practice, even if it does), you should be specifying the columns to be inserted into. Assuming the column names are also "projectvalue" and "columnvalue", then the statement would be:
st.executeUpdate("INSERT INTO CUST_RALLY_TEAM_MEMBER (projectvalue,columnvalue) VALUES ('" + projectValue + "','" + columnValue + "')");
Note, too, that prepared statements are a good approach for a process such as this. It eliminates the risk of SQL errors if the values contain a single quote, reduces the risk of SQL Injection attacks, and improves performance by compiling the statement only once.
I try to generate random code name as licenseKey and check whether it is exist in database or not. If not exist, then display in my jsp page, if exist, continue generating the random code. I got the error "java.lang.StackOverflowError". How to solve this? Below is my code :
package com.raydar.hospital;
import com.raydar.hospital.DB_Connection;
import java.sql.*;
public class RandomCodeGenerator {
String licenseKey = "";
int noOfCAPSAlpha = 4;
int noOfDigits = 4;
int minLen = 8;
int maxLen = 8;
char[] code = RandomCode.generateCode(minLen, maxLen, noOfCAPSAlpha, noOfDigits);
public RandomCodeGenerator(){
}
public String getOutputCode() throws Exception{
String result ="";
result = isLicenseKeyExist();
System.out.println("4 + " +result);
if (result=="false"){
System.out.println("1 + " +new String(code));
licenseKey = new String(code);
}
else if (result=="true"){
System.out.println("2 + " +new String(code));
licenseKey = new String(code);
isLicenseKeyExist ();
}
return licenseKey;
}
private String isLicenseKeyExist () throws Exception{
String code = "";
code = getOutputCode();
Connection connection = null;
Statement statement = null;
ResultSet rs = null;
String result="";
System.out.println("3 + " +code);
try{
DB_Connection connect = new DB_Connection();
connection = connect.getDBConnection();
statement = connection.createStatement();
rs = statement.executeQuery("SELECT licenseKey FROM hospital WHERE licenseKey = '" +code+ "'");
if (rs.next()){
result = "true";
}
else{
result = "false";
}
}catch (Exception e){
System.out.println("Error retrieving data! "+e);
}
return result;
}
}
You create a recursive loop where isLicenseKeyExist() calls getOutputCode(), but then getOutputCode() calls isLicenseKeyExist(). So eventually you run out of stack space, and get this exception.
Here,
public String getOutputCode() throws Exception{
String result ="";
result = isLicenseKeyExist();
...
}
private String isLicenseKeyExist () throws Exception{
String code = "";
code = getOutputCode();
...
}
I think you want something like this. Remove the field called code from your class, and its initialiser, and put the call to RandomCode.generateCode inside your getOutputCode method like this. The reason is that you'll have to call it repeatedly if your code is already in the database.
public String getOutputCode() throws SQLException {
String code;
do {
code = new String(RandomCode.generateCode(minLen, maxLen, noOfCAPSAlpha, noOfDigits));
}
while(licenceKeyExists(code));
return code;
}
private boolean licenceKeyExists(String code) throws SQLException {
try{
DB_Connection connect = new DB_Connection();
connection = connect.getDBConnection();
statement = connection.createStatement();
rs = statement.executeQuery("SELECT licenseKey FROM hospital WHERE licenseKey = '" +code+ "'");
return rs.next();
}
finally {
try {
connection.close();
} catch (SQLException ignored){}
}
}
#aween - #captureSteve has answered the first part of the question .
So, straight to "I wan't to call this function" comment. See, if I
understand your question correctly, you want to generate a key, and
check if it is available in the DB using isLicenseKeyExist() . In such
case, why don't you create the key first, then pass it to the
isLicenseKeyExist(). Then this function will return true/false based
on which you can decide what to do.
Hey im attempting to to make an invoice program that uses Java and Sqlite as a database. I know that sqlite is a forward only language, but is there a way to scroll backwards or make it type scroll insensitive here is the class that im trying to use. I am attempting to put all of my information extracted from my database into an array.
public String[] getRow(int rowID)
{
String id =("");
String name = ("");
String day = ("");
String location = ("");
String price = ("");
String timestart= ("");
String Timeend = ("");
String Showtype = ("");
String[] row= new String[8];
try
{
Class.forName("org.sqlite.JDBC");
Connection x=DriverManager.getConnection("jdbc:sqlite:test.db");
Statement stmt = x.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery ("SELECT ID, NAME, day, Location, price, timestart, Timeend, Showtype FROM Showinformation ORDER BY ID LIMIT 5 OFFSET:index;");
rs.step(rowID);
while(rs.next())
{
for(int i=0; i<8; i++)
{
id = rs.getString("ID");
row[0]=id;
name = rs.getString("NAME");
row[1]=name;
day = rs.getString("day");
row[2]=day;
location = rs.getString("Location");
row[3]=location;
price = rs.getString("price");
row[4]=price;
timestart= rs.getString("timestart");
row[5]=timestart;
Timeend= rs.getString("Timeend");
row[6]=Timeend;
Showtype= rs.getString("Showtype");
row[7]=Showtype;
}
//String potato =(i+1+id+""+name+""+day+""+location+""+price+""+timestart+""+Timeend+""+Showtype);
//System.out.println("ID = " + id +"\nNAME = " + name+"\nDAY = " + day+"\nADDRESS = " + location+"\nPRICE = " + price+"\nTIME START = " + timestart+"\nTIME END = " + Timeend+"\nSHOWTYPE = " + Showtype );
}
}
catch(Exception er)
{
System.err.println(er.getClass().getName()+":"+er.getMessage() );
}
return row;
}
any help would be appreciated.
I have a webservice where from the Client-side some parameters are passed to perform a query on the DB, the Server-Side is supposed to carry out the query and return the results.Since the result might be more than one row and i will have to use it on the client-side to show an output this what i did:
1.Perform the query
2.take each row of the result and put it in an array
3.convert the array to String and pass it to the client side(converted array to String, because it was simple)
BUT the problem is that it doesnt pass the the array-turned-string but only the value which was used to initialize the string, here is the code
String ris = "";
String q;
String beta = null;
String one="";
String errore = connetti();
try {
if (errore.equals("")) {
Statement st = conn.createStatement();
//ESECUZIONE QUERY
q = "SELECT DISTINCT nome FROM malattia WHERE eta='" + age + "' AND sesso='" + sexstr + "' AND etnia='" + etniastr + "' AND sintomi IN(" + tes + ")";
ResultSet rs = st.executeQuery(q);
if (!rs.last()) {
ris = "no";
}
//This is the part which i'm talking about
else {
//getRowCount is another class used to find out number of rows,I use it to declare an array which would contain the result of the query
int two=getRowCount(rs);
String[] alpha= new String[two];
//Loop through the resultstatement and put result from the column **nome** in the array **alpha**
while(rs.next()){
alpha[i]=rs.getString("nome");
i++;
}
//The value of ris which is empty, is returned
ris="";
//instead of this one, where i convert the array **alpha** to String
ris=arrayToString(alpha,",");
}
}
else {
ris = errore;
}
conn.close();
} catch (Exception e) {
ris = e.toString();
}
return ris;
}
//returns the number of rows of **ris**
public static int getRowCount(ResultSet set) throws SQLException
{
int rowCount;
int currentRow = set.getRow(); // Get current row
rowCount = set.last() ? set.getRow() : 0; // Determine number of rows
if (currentRow == 0) // If there was no current row
set.beforeFirst(); // We want next() to go to first row
else // If there WAS a current row
set.absolute(currentRow); // Restore it
return rowCount;
}
//converts the array to String
public String arrayToString(String[] array, String delimiter) {
StringBuilder arTostr = new StringBuilder();
if (array.length > 0) {
arTostr.append(array[0]);
for (int i=1; i<array.length; i++) {
arTostr.append(delimiter);
arTostr.append(array[i]);
}
}
return arTostr.toString();
Thanks alot in advance!
After conn.close() you return beta instead of ris. This may be the cause of the behavior you are experiencing. However, I am not sure because I can not properly see how you open and close the curly brackets.