I have tried to use these two questions as a reference
JAVA - SQLException throws exist column not found
Strange SQLException: Column not found
However, none of it helped my case. I keep receiving
java.sql.SQLException: Column 'debut' not found.
this is my SQL
private List<MemberModel> getModelFromNickname(String test) throws SQLException {
List<MemberModel> result = new ArrayList<>();
String sql = "select distinct " +
"m.name," +
"m.visual," +
"m.branch, " +
"m.illustrator, " +
"m.debut3D AS debut " +
"FROM " +
"member_list as m, " +
"nickname AS n " +
"WHERE n.nick_id = m.nick AND n.nickname LIKE ?";
ResultSet ret= sqlAdapter.select(
sql, 1,test
);
while (ret.next()){
result.add(fillRecord(ret));
}
return result;
}
this is my MYSQLAdapter
public ResultSet select(String sql,int option, Object... params) throws SQLException {
PreparedStatement query;
try{
logger.info(params.length);
query = getConnection().prepareStatement(sql);
}
catch (Exception e){
throw new Error("Problem "+ e);
}
resolveParameters(query,option, params);
return query.executeQuery();
}
this is my fillRecord command
private static MemberModel fillRecord(ResultSet resultSet) throws SQLException {
MemberModel member = new MemberModel();
member.name =resultSet.getString("name");
member.branch = resultSet.getString("branch");
member.debut_3d = resultSet.getBoolean("debut");
member.visual = resultSet.getString("visual");
member.illustrator = resultSet.getString("illustrator");
return member;
}
while this is my memberModel
public class MemberModel {
public String name = "";
public int social_media = 0;
public int nick = 0;
public String branch = "";
public boolean debut_3d= true;
public String illustrator ="";
public String visual = "";
}
I tried to use
ResultSetMetaData rsmd = sqlAdapter.getConnection().prepareStatement(sql).getMetaData();
for(int i =1; i<= rsmd.getColumnCount();i++){
System.err.println(rsmd.getColumnCount()+"\n"+rsmd.getColumnName(i));
}
which gives me the following (I don't know how it somehow managed to print more than 5. But, all of it except "debut" can be found)
5
name
5
visual
5
branch
5
illustrator
5
debut
5
name
5
visual
5
branch
5
illustrator
5
debut
This indicates that the debut column should exist yet I still get that exception. Where did I do wrong? I make sure that it is case sensitive just in case. The data type for "debut" column is boolean in my localhost XAMPP MySQL. If I erase member.debut_3d = resultSet.getBoolean("debut"); within fillrecord... Everything works perfectly fine
Rather get values by labelName trying column number.
private static MemberModel fillRecord(ResultSet resultSet) throws SQLException {
MemberModel member = new MemberModel();
member.name = resultSet.getString(1);
member.branch = resultSet.getString(3);
member.debut_3d = resultSet.getBoolean(5);
member.visual = resultSet.getString(2);
member.illustrator = resultSet.getString(4);
return member;
}
resultSet.getBoolean("debut3D"); // Instead of "debut"
The column in the database table is called "debut3D".
BTW you are not closing PreparedStatement and ResultSet. I would use try-with-resources.
The column name is "debut3D" not "debut", thats why you are getting the error.
Update below line with correct column name,
member.debut_3d = resultSet.getBoolean("debut3D");
Related
I want to have a method in java to create sqlite tables without knowing the number of columns
public static void createNewTable(String databaseName, String tableName, String typeOfAttribute1, String attribute1) {
// SQLite connection string
String url = "jdbc:sqlite:" + databaseName;
// static SQL statement for creating a new table
String sql = "CREATE TABLE IF NOT EXISTS "+ tableName + " (" + attribute1 + " " + typeOfAttribute1 + ");";
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement()) {
// create a new table
stmt.execute(sql);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
In this specific case i'm forced to create a table with only one column (attribute1). Is possible to have a more reusable approach and create a table without knowing the number of the columns?
I hope that everything is clear
You can use StringBuilder and instead to pass list of columns i suggest to use a List which take an Array[column_name, column_type] like this :
public static void createNewTable(String databaseName, String tableName, List<String[]> columns) {
// SQLite connection string
String url = "jdbc:sqlite:" + databaseName;
String query = "CREATE TABLE IF NOT EXISTS " + tableName + " (";
StringBuilder sql = new StringBuilder(query);
String prefix = "";
for (String[] s : columns) {
sql.append(prefix);
prefix = ", ";
sql.append(s[0]);
sql.append(" ");
sql.append(s[1]);
}
sql.append(");");
System.out.println(sql);
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement()) {
// create a new table
stmt.execute(sql.toString());
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) {
List<String[]> list = new ArrayList<>();
list.add(new String[]{"col1", "type1"});
list.add(new String[]{"col2", "type2"});
list.add(new String[]{"col3", "type3"});
list.add(new String[]{"col4", "type4"});
list.add(new String[]{"col5", "type5"});
createNewTable("database_name", "table_name", list);
}
This will show you:
CREATE TABLE IF NOT EXISTS table_name (col1 type1, col2 type2, col3 type3, col4 type4, col5 type5);
You can use varargs, which is simply an array. Consider that each odd item is attribute name, each even item is attribute type:
public static void createNewTable(String databaseName, String tableName, String ...attributes) {
if (attributes.length % 2 != 0) throw new IllegalArgumentException(...);
// attributes[0] - 1st attribute name
// attributes[1] - 1st attribute type
for (int i = 0; i < attributes.length-1; i+=2) {
// attributes[i] - i-st attribute name
// attributes[i+1] - 1st attribute type
// ...
}
// ...
}
I hope you can complete rest logic of this method by your self.
I want to ask for help my code that will find relevant name from database according to id number.
My code find the name that i try to find.
BUT i want to send an error message when the program can not find ID number.
I tried many ways but always when it couldnt find ID number, it said build succesfull and show no error just quitted the program.
Thanks for your help.
public void search(String ID) throws SQLException {
Statement mystate = con.createStatement();
String sql = "SELECT*FROM users" +
" WHERE id LIKE " + ID;
ResultSet rs = mystate.executeQuery(sql);
while (rs.next()) {
System.out.println("Your Name is " + rs.getString("name"));
}
}
Two big issues with your code:
You don't put SQL quotes around ID, so it looks like a keyword or identifer to the SQL parser
It's wide open to SQL-injection attacks (see below)
You want to use a PreparedStatement, which deals with both of those for you. Then just use a flag for whether you saw anything:
public void search(String ID) throws SQLException {
boolean sawOne = false;
PreparedStatement mystate = con.prepareStatement(
"SELECT * FROM users WHERE id LIKE ?"
);
mystate.setString(1, ID);
ResultSet rs = mystate.executeQuery(mystate);
while (rs.next()) {
sawOne = true;
System.out.println("Your Name is " + rs.getString("name"));
}
if (!sawOne) {
System.out.println("...");
}
}
I'm assuming ID already has a wildcard on it (or that you really don't want one).
Or if you know there will be only one match, or you only want one match even if there's more than one, you can add a
mystate.setMaxRows(1);
...before executeQuery(), and then just use if/else, no need for the flag:
if (rs.next()) {
System.out.println("Your Name is " + rs.getString("name"));
} else {
System.out.println("...");
}
Obligatory SQL-injection link: http://bobby-tables.com/
And cartoon:
public void search(String ID) throws SQLException {
Statement mystate = con.createStatement();
String sql = "SELECT*FROM users" +
" WHERE id LIKE " + ID;
ResultSet rs = mystate.executeQuery(sql);
if(rs.next()) {
System.out.println("Your Name is " + rs.getString("name"));
}
else
{
System.out.println("Id not found");
}
}
I have a list like following:
List<SelectItem> measurementList;
I want to assign measurementList.get(i) into a Long variable.
For example I want to assign it in the following way:
Long sd = measurementList.get(0);
But, it is showing type mismatch. That is really obvious. How can I assign the value from measurementList.get(0) to a Long variable.
Thanks
Code are given below:
public List<SelectItem> measurementList(Long coModAssetId)
{
// log.info("Start");
// log.debug("finding MeasurementSeneorTypeList instance by example using dbMeasurementSeneorTypeList");
List<SelectItem> results;
try {
// Add SELECT with a nested select to get the 1st row
String queryString = "SELECT M.Measurement_Id, M.NAME" +
" FROM ems.COMPANY_MODULE_ASSET CMA, " +
" ems.Asset_Measurement Am," +
" ems.MEASUREMENT M" +
" WHERE CMA.Co_Mod_Asset_Id = ?" +
" And Cma.Asset_Id = Am.Asset_Id " +
" AND AM.MEASUREMENT_ID = M.MEASUREMENT_ID" +
" GROUP BY M.measurement_id, M.NAME" +
" ORDER BY M.name";
MeasurementSeneorTypeListWork work = new MeasurementSeneorTypeListWork();
work.coModAssetId = coModAssetId;
work.queryString = queryString;
getSession().doWork(work);
results = work.results;
} catch (RuntimeException re) {
// log.error("getMostRecentObservationId() failed", re);
throw re;
}
//log.info("End");
return results;
}
Class definition
public class MeasurementSeneorTypeListWork implements Work {
List<SelectItem> results = new ArrayList<SelectItem>();
private String queryString;
private Long coModAssetId;
#Override
public void execute(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(queryString);
int index = 1;
ps.setLong(index++, coModAssetId);
ResultSet rs = ps.executeQuery();
while(rs.next())
{
//String userName = PropertyReader.getLabel(rs.getString(2));
Long id = rs.getLong(1);
SelectItem item = new SelectItem(id, null);
results.add(item);
}
rs.close();
ps.close();
}
}
}
If your SelectItem type is javax.faces.model.SelectItem, then you have a getValue() method that you can use.
Long sd = (Long) measurementList.get(i).getValue();
Note: you're using the 2-argument constructor SelectItem(Object value, String label) to create your items for the list, but since the second parameter is always null, you could use SelectItem(Object value) instead.
You can use the .longValue() method:
(measurementList.get(i)).longValue()
This returns the numeric value represented by this object after conversion to type long.
I am trying to implement FK relation from MySQL into JAVA using JDBC. I have a list of Garaz objects and each Garaz has a list of Auto (cars) objects. I have very mixed data.
My MySQl DB is ok and I try to do it like this:
public static ArrayList <Garaz> selectRecords() throws SQLException {
Connection dbConnection = null;
Statement statement = null;
String selectTableSQL = "SELECT Garaz.G_ID, Garaz.Nazwa, Garaz.Adres, Garaz.LiczbaMiejsc, Garaz.LiczbaPoziomow, " +
"Garaz.Czynny, Auta.A_Id, Auta.Model, Auta.Kolor, Auta.IloscDrzwi, Auta.Rejestracja\n" +
"FROM Garaz\n" +
"LEFT JOIN Auta\n" +
"ON Garaz.G_Id=Auta.G_Id\n" +
"ORDER BY Garaz.G_Id; ";
// ArrayList lista = new ArrayList <Garaz>();
try {
dbConnection = getDBConnection();
statement = dbConnection.createStatement();
System.out.println(selectTableSQL);
// execute select SQL stetement
ResultSet rs = statement.executeQuery(selectTableSQL);
while (rs.next()) {
int g_id = rs.getInt("G_ID");
String nazwa = rs.getString("NAZWA");
String adres = rs.getString("ADRES");
int lmiejsc = rs.getInt("LICZBAMIEJSC");
int lpoz = rs.getInt("LICZBAPOZIOMOW");
boolean czynny = rs.getBoolean("CZYNNY");
ArrayList lista2 = new ArrayList <Auto>();
int a_id = rs.getInt("A_Id");
String model = rs.getString("Model");
String kolor = rs.getString("Kolor");
int ildrzwi = rs.getInt("IloscDrzwi");
String rejestracja = rs.getString("Rejestracja");
Auto d = new Auto(a_id, model, kolor, ildrzwi, rejestracja);
if (a_id !=0){
lista2.add(d);
}
Garaz f = new Garaz(g_id, nazwa, lista2, adres, lmiejsc, lpoz, czynny);
lista.add(f);
//System.out.println("nazwa : " + nazwa);
//System.out.println("adres : " + adres);
// return lista;
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null) {
statement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
return lista;
}
I don't understand how to read from ResultSet rs in the way that: ArrayList Garaz contains objects (Garaz) and each Garaz object contains ArrayList Auto. So I have big problem with creating 2 lists (one is part of another) by reading data from rs (ResultSet). I have all Garaz and all Auto from DB tables, but the relation is mixed. Like Garaz1 contains random Auto (cars).
How do I create 2 lists (one is part of another) to keep the relation Auto is part of Garaz based on G_ID?
your result set will provide one result (aka line) for each Garaz and Auto, since thats what the select statement does. So you can...
either parse the resultset as it is, and manually create each Garaz & Auto record you want, but you will have to deal with the duplicate Garaz data.
OR
You can either use a framework like MyBatis to get the get the objects back, or.
OR
Perform a SELECT statement for the list of Garaz, then perform another SELECT statement to get the list of AUTO's back for each Garaz.
Sudo code.....
#Repository
public class StoreDbDAO
{
#Autowired
public void init(#Qualifier("dataSourceCDB") DataSource dataSource) {
this.dataSource = dataSource;
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
private static final String GET_USABLE_RECORDS = "SELECT d.ID, d.HARDWARE_ID " +
" FROM DEVICE d " +
" LEFT JOIN TABLEB o on o.X_ID = d.X_ID " +
" WHERE " +
" d.DEVC_HARDWARE_ID IS NOT NULL " +
" AND o.CODE = ? "";
public List<Map<String, Object>> getStores(String cCode)
{
return simpleJdbcTemplate.queryForList(GET_USABLE_RECORDS, code);
}
}
#Autowired
StoreDbDAO storeDbDAO;
public void caller() {
List> stores = storeDbDAO.getStores();
List<Stores> storeRecords = new ArrayList[stores.size()];
for (Map<String, Object> store: stores)
{
final String storeId = (String) store.get("HARDWARE_ID");
StoreRecord x = new StoreRecord(storeId)
storeRecords.add(x);
List<Map<String, Object>> devicesInTheStore = storeDbDAO.getDevicesForStore(storeId);
// convert these into something useful.
x.setDevicesInStore(convertToList(devicesInTheStore));
}
}
You need to iterate over the result, check if you already created the Garaz object for the G_ID of the row and either use that or create a new one. This can be simplified by sorting on the G_ID field and just create a new Garaz object when the G_ID changes.
As you comment that you don't know how to do this, here is a full example:
public List<Garaz> getAllGaraz() throws SQLException {
List<Garaz> garazList = new ArrayList<Garaz>();
try (
Connection con = getDBConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT Garaz.G_ID, /* other garaz columns */ " +
"Auta.A_Id /*other auta columns */\n" +
"FROM Garaz\n" +
"LEFT JOIN Auta\n" +
"ON Garaz.G_Id=Auta.G_Id\n" +
"ORDER BY Garaz.G_Id");
) {
Garaz currentGaraz = null;
while (rs.next()) {
int garazId = rs.getInt("G_ID");
// Create Garaz only if it is different
if (currentGaraz == null || currentGaraz.getId() != garazId) {
// retrieve other columns
currentGaraz = new Garaz(g_id /* + other garaz columns */);
garazList.add(currentGaraz);
}
int a_id = rs.getInt("A_Id");
// replacement of your condition of a_id != 0
// 0 could be a valid value, check for null instead
if (!rs.wasNull()) {
// retrieve other columns
Auto auta = new Auta(a_id /* + other auta columns */);
// The list of Auta is part of the garaz
currentGaraz.addAuta(auta);
}
}
return garazList;
}
}
public class Garaz {
private final List<Auta> autaList = new ArrayList<Auta>();
private final int id;
public Garaz(int g_id /* + other fields*/) {
id = g_id;
}
public int getId() {
return id;
}
public void addAuta(Auta auta) {
autaList.add(auta);
}
public List<Auta> getAutaList() {
return new ArrayList<Auta>(autaList);
}
}
I have two .java files under the same package in a project folder in NetBeans IDE.
I am trying to use the following method to insert data to a Derby DB using JDBC:
public static void insertDisease(int id, String diseaseName, String diseaseDefinition) {
try {
stmt = conn.createStatement();
stmt.execute("insert into " + tableName + " values (" + id + ",'" + diseaseName + "','" + diseaseDefinition + "')");
stmt.close();
} catch(SQLException sqlExcept) {
sqlExcept.printStackTrace();
}
}
I have returned the data I need using the following method in another .java file (In the same package):
public List<String> nameOf() {
String nameStr = null;
List<String> nameResults = new ArrayList<String>();
for(int j=101;j<=110;j++) {
refNum = j;
try {
//crawl and parse HTML from definition and causes page
Document docN = Jsoup.connect("http://www.abcde.edu/encylopedia/article/000" + refNum + ".htm").get();
// scrape name data
Elements name = docN.select("title");
nameStr = name.get(0).text();
//System.out.println(nameStr);
nameResults.add(nameStr);
} catch (Exception e) {
nameStr = "No data";
nameResults.add(nameStr);
//System.out.println("Reference number " + refNum + " does not exist.");
}
}
return nameResults;
}
How should I implement my main method? This is what I have now:
public static void main(String[] args) throws InstantiationException, IllegalAccessException, SQLException {
createConnection();
for(int i=101;i<=110;i++) {
insertDisease(i, ?, ?);
}
viewTable(conn, dbURL);
}
What should go in as the 2nd and 3rd parameters (question marks) so that the names of the diseases from 101th to the 110th are inserted into my Derby DB correspondingly?
For Example, the table should look like the following:
id name definition
101 stomachache stomach hurts
102 headache head hurts
103 toothache tooth hurts
Thanks in advance!