In my app, i'm using subquerys of sqlite, the subquery returns 3 values, its ok, but in the main query, returns empty and i need help in this.
*some parts of variables is in portuguese because i'm brazilian.
public List<Table_Anuncio_Empregador> getAllUser_Empregador() {
SQLiteDatabase db = this.getReadableDatabase();
List<Table_Anuncio_Empregador> anuncios = new ArrayList<Table_Anuncio_Empregador>();
SharedPreferences preferences = context.getSharedPreferences("user_preferences", MODE_PRIVATE);
int user_id = preferences.getInt("user_id_conectado",0);
String selectQuery = "SELECT "+KEY_ID+", "+KEY_IMAGEM_ANUNCIO+", "+KEY_TITULO+", "+KEY_DESCRICAO+", "+KEY_CIDADE
+ " FROM " + TABLE_ANUNCIO_EMPREGADOR
+ " WHERE "+ KEY_ID +" IN (SELECT "+KEY_ANUNCIO_EMPREGADOR_ID+" FROM "+ TABLE_ANUNCIO
+" WHERE "+ KEY_ANUNCIO_PERFIL+" = 'empregador' AND "+ KEY_USER_ID+" = "+user_id+")";
Log.e(LOG, selectQuery);
Cursor c = db.rawQuery(selectQuery, null);
if (c.moveToFirst()) {
do {
Table_Anuncio_Empregador anuncio = new Table_Anuncio_Empregador();
anuncio.setAnuncio_empregador_id(c.getInt(c.getColumnIndex(KEY_ID)));
anuncio.setImagem_do_anuncio(c.getBlob(c.getColumnIndex(KEY_IMAGEM_ANUNCIO)));
anuncio.setTitulo(c.getString(c.getColumnIndex(KEY_TITULO)));
anuncio.setDescricao(c.getString(c.getColumnIndex(KEY_DESCRICAO)));
anuncio.setCidade(c.getString(c.getColumnIndex(KEY_CIDADE)));
anuncios.add(anuncio);
} while (c.moveToNext());
}
return anuncios;
}
The LOG shows the query as :-
E/Banco_Helper: SELECT ID, Imagem_anuncio, Titulo, Descricao, Cidade FROM Anuncio_empregador WHERE ID IN (SELECT Anuncio_empregado_info_ID FROM Anuncio WHERE Anuncio_perfil = 'empregador' AND User_ID = 2)
The tables are created using :-
private static final String CREATE_TABLE_ANUNCIO =
"CREATE TABLE IF NOT EXISTS " + TABLE_ANUNCIO + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
KEY_USER_ID + " INTEGER NOT NULL," +
KEY_ANUNCIO_PERFIL + " TEXT NOT NULL," +
KEY_ANUNCIO_EMPREGADOR_ID + " INTEGER," +
KEY_ANUNCIO_PRESTADOR_ID + " INTEGER," +
KEY_CREATED_AT + " DATETIME NOT NULL" + ")";
and :-
private static final String CREATE_TABLE_ANUNCIO_EMPREGADOR =
"CREATE TABLE IF NOT EXISTS " + TABLE_ANUNCIO_EMPREGADOR + "(" + KEY_ID + " INTEGER PRIMARY KEY," +
KEY_TITULO + " TEXT NOT NULL," +
KEY_DESCRICAO + " TEXT NOT NULL," +
KEY_BAIRRO + " TEXT NOT NULL," +
KEY_CIDADE + " TEXT NOT NULL," +
KEY_ESTADO + " TEXT NOT NULL," +
KEY_LOCAL_SERVICO + " TEXT NOT NULL," +
KEY_EXIGENCIAS + " TEXT," +
KEY_IMAGEM_ANUNCIO + " BLOB NOT NULL" + ")";
Equating to :-
CREATE TABLE IF NOT EXISTS Anuncio(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
USER_ID INTEGER NOT NULL,
Anuncio_perfil TEXT NOT NULL,
Anuncio_empregado_info_ID INTEGER,
ANUNCIO_PRESTADOR_ID INTEGER,
CREATED_AT DATETIME NOT NULL
);
And :-
CREATE TABLE IF NOT EXISTS Anuncio_empregador (
ID INTEGER PRIMARY KEY,
Titulo TEXT NOT NULL,
Descricao TEXT NOT NULL,
Bairro TEXT NOT NULL,
Cidade TEXT NOT NULL,
Estado TEXT NOT NULL,
Local_Servico TEXT NOT NULL,
Exigencias TEXT,
Imagem_anuncio BLOB NOT NULL
);
I believe that your issue is with the actual data rather then the query.
That is, the following was used to create and populate the two tables and to also run the query (plus some intermediate queries). The result was that the three expected rows were included and that the three rows that should have been excluded were. That is the query in question ran with the expected results.
The following SQL was used :-
DROP TABLE IF EXISTS Anuncio;
CREATE TABLE IF NOT EXISTS Anuncio(
ID INTEGER PRIMARY KEY AUTOINCREMENT,
USER_ID INTEGER NOT NULL,
Anuncio_perfil TEXT NOT NULL,
Anuncio_empregado_info_ID INTEGER,
ANUNCIO_PRESTADOR_ID INTEGER,
CREATED_AT DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
DROP TABLE IF EXISTS Anuncio_empregador;
CREATE TABLE IF NOT EXISTS Anuncio_empregador (
ID INTEGER PRIMARY KEY,
Titulo TEXT NOT NULL,
Descricao TEXT NOT NULL,
Bairro TEXT NOT NULL,
Cidade TEXT NOT NULL,
Estado TEXT NOT NULL,
Local_Servico TEXT NOT NULL,
Exigencias TEXT,
Imagem_anuncio BLOB NOT NULL DEFAULT X'00010203040506070809'
)
;
INSERT INTO Anuncio_empregador
(Titulo,Descricao,Bairro,Cidade,Estado,Local_Servico,Exigencias)
VALUES
('Mr','Albert','Bloggs','something','something else','xxx','xxxx'),
('Mr','Bert','Bloggs','something','something else','xxx','xxxx'),
('Mr','Charlie','Bloggs','something','something else','xxx','xxxx'),
('Mr','Dave','Bloggs','something','something else','xxx','xxxx'),
('Mr','Eddie','Bloggs','something','something else','xxx','xxxx'),
('Mr','Fred','Bloggs','something','something else','xxx','xxxx'),
('Mr','George','Bloggs','something','something else','xxx','xxxx')
;
SELECT * FROM Anuncio_empregador;
INSERT INTO Anuncio
(USER_ID, Anuncio_perfil,Anuncio_empregado_info_ID,ANUNCIO_PRESTADOR_ID)
VALUES
(1,'empregador',1,100),
(2,'empregador',2,100),
(3,'empregador',3,100),
(4,'not an empregador',1,100),
(5,'not an empregador',2,100),
(6,'not an empregador',3,100)
;
SELECT * FROM Anuncio;
SELECT * FROM Anuncio WHERE Anuncio_perfil = 'empregador';
SELECT ID,Imagem_anuncio,Titulo,Descricao,Cidade
FROM Anuncio_empregador
WHERE ID IN
(
SELECT Anuncio_empregado_info_ID
FROM ANUNCIO
WHERE ANUNCIO_PERFIL = 'empregador' AND USER_ID = user_id
)
;
Note that some liberties were taken, like
using the CURRENT_TIMESTAMP and
using X'00010203040506070809'
saving having to repeat these values which would have no impact upon workings of the SQL.
The resultant Anuncio_empregador table being :-
The resultant Anuncio table being :-
i.e. last 3 rows have been set to be excluded according to the clause WHERE ANUNCIO_PERFIL = 'empregador'
The result of the query in Question
SELECT ID,Imagem_anuncio,Titulo,Descricao,Cidade
FROM Anuncio_empregador
WHERE ID IN
(
SELECT Anuncio_empregado_info_ID
FROM ANUNCIO
WHERE ANUNCIO_PERFIL = 'empregador' AND USER_ID = user_id
)
;
being :-
Note changing AND USER_ID = user_id to AND USER_ID = 2 shows just the 1 row for Bert, as expected.
Related
My question is very simple. I just want to know how to write a create Table statement for MySQL using Java statements where the name of the table is a string.
I know how to insert String values as values of the coloumns using Java. I tried it that way but could not do it. I will show you my code:
String table = "CREATE TABLE table_name'" +
"(SL. No INT not NULL AUTO_INCREMENT, " +
" NAME VARCHAR(100), " +
" YEAR INT not NULL, " +
" IMDB INT not NULL)";
Here instead of table_name I want to input a string variable. The variable name is s2.
Now the Insert into table value is as follows:
myStmt.executeUpdate("insert into l1(id,email,usname,pwd)value('"+(i)+"','"+s1+"','"+s2+"','"+s5+"')");
Here s1,s2,s5 are string values. But this method is not working for Create Table and it is showing syntax error. What is the correct code?
You should remove additional ' sign and change name for SL. No column to somethin else so it looks like
String table = "CREATE TABLE table_name" +
"(slno INT not NULL AUTO_INCREMENT, " +
" NAME VARCHAR(100), " +
" YEAR INT not NULL, " +
" IMDB INT not NULL)"
If your table string is correct you can replace table_name with new name for each table with replace method on string or just use function
public static String getCreateTableQuery(String tableName) {
String table = "CREATE TABLE table_name" +
"(slno INT not NULL AUTO_INCREMENT, " +
" NAME VARCHAR(100), " +
" YEAR INT not NULL, " +
" IMDB INT not NULL)";
String createTableWithNewNameQuery = table.replaceFirst("table_name'", tableName);
return createTableWithNewNameQuery;
}
EDIT: I did a mistake writing WHERE Users.Username=? instead of WHERE Answers.Username=?
If I use the following statement I get correct average 3.33:
public final String SELECT_USER_AND_AVGANSWERS_STMT =
"SELECT AVG(CAST(Answers.Rating AS FLOAT)) FROM Answers "
+ "WHERE Answers.Username=?";
Notice I am only selecting AVG. When I try select more columns it returns 4, as in it rounded it up.
public final String SELECT_USER_AND_AVGANSWERS_STMT =
"SELECT Users.Username, Users.Nickname, AVG(CAST(Answers.Rating AS FLOAT)) "
+ "FROM Users, Answers "
+ "WHERE Users.Username=?"
+ "GROUP BY Users.Username, Users.Nickname";
Users Table:
"CREATE TABLE Users(Username VARCHAR(10) PRIMARY KEY,"
+ "Password VARCHAR(8) NOT NULL,"
+ "Nickname VARCHAR(20) NOT NULL,"
+ "Description VARCHAR(50),"
+ "Photo VARCHAR(4000))";
Answers Table:
"CREATE TABLE Answers(AnswerID INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,"
+ "QuestionID INTEGER NOT NULL,"
+ "SubmittedTime TIMESTAMP NOT NULL,"
+ "Text VARCHAR(300) NOT NULL,"
+ "Username VARCHAR(10) NOT NULL,"
+ "Rating INTEGER DEFAULT 0 NOT NULL)";
Using Java / Embedded Derby database.
Appreciate your help.
As you pointed out, you are trying to match the Users.Username in this query, but Answers.Username in your first query, so this is one problem! This should work:
SELECT Users.Username, Users.Nickname, AVG(CAST(Answers.Rating AS FLOAT))
FROM Users, Answers
WHERE Answers.Username=?
GROUP BY Users.Username, Users.Nickname
Something else that could be problematic is whether or not the aggregation happens before the CAST. To check this you could use:
SELECT UserName, NickName, CAST(AVG(AnswersRating) AS FLOAT)
FROM
(
SELECT Users.Username As UserName, Users.Nickname As NickName, CAST(Answers.Rating AS FLOAT) As AnswersRating
FROM Users, Answers
WHERE Answers.Username=?
) AS Float_Table
GROUP BY UserName, NickName
I can't create a table in the database (mySQL), using preparedStatement and try to enter name of future table with preparedStatement.setInteger():
static String queryCreateTable = "CREATE TABLE ?" +
"(ID INTEGER not NULL ," +
"BRAND VARCHAR(40)," +
"MODEL VARCHAR(40)," +
"YEAR INTEGER not NULL," +
"NOVELTY BINARY," +
"PRIMARY KEY ( ID ))";
And then I try to construct and call the statement after inputing name of table by user:
newNameOfTable = JOptionPane.showInputDialog("Connected for saving data. " +
"Input name of new table:");
pStatement = connection.prepareStatement(queryCreateTable);
pStatement.setString(1, newNameOfTable);
pStatement.executeUpdate();
It works well if I try to execute it without entering name (like a constant string: "CREATE TABLE newtable (...)" but I need to enter name..
You will have to format the string after reading the table name, something like:
static String queryCreateTable = "CREATE TABLE {0}" +
"(ID INTEGER not NULL ," +
"BRAND VARCHAR(40)," +
"MODEL VARCHAR(40)," +
"YEAR INTEGER not NULL," +
"NOVELTY BINARY," +
"PRIMARY KEY ( ID ))";
then create like:
newNameOfTable = JOptionPane.showInputDialog("Connected for saving data. " +
"Input name of new table:");
statement = connection.createStatement();
statement.execute(MessageFormat.format(queryCreateTable, newNameOfTable));
newNameOfTable = JOptionPane.showInputDialog("Connected for saving data. " +
"Input name of new table:");
static String queryCreateTable = "CREATE TABLE " + newNameOfTable +
"(ID INTEGER not NULL ," +
"BRAND VARCHAR(40)," +
"MODEL VARCHAR(40)," +
"YEAR INTEGER not NULL," +
"NOVELTY BINARY," +
"PRIMARY KEY ( ID ))";
pStatement = connection.prepareStatement(queryCreateTable);
pStatement.executeUpdate();
PreparedStatement example:
http://tutorials.jenkov.com/jdbc/preparedstatement.html
Here is my code:
DataBaseAlarm mDbHelper = new DataBaseAlarm(this);
db = mDbHelper.getWritableDatabase();
private static final String SQL_CREATE_ENTRIES="CREATE TABLE IF NOT EXISTS"+TABLE_NAME+" ("+rowid+" INTEGER PRIMARY KEY AUTOINCREMENT, "+Title+TEXT_TYPE+Time+TEXT_TYPE+Date+TEXT_TYPE+Repeat+TEXT_TYPE+Note+" TEXT NOT NULL);";
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
Cursor c = db.query(
"Alarms", // The table to query
cols, // The columns to return
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
);
from=new String[]{"title","note","time","date","repeat","_id"};
to=new int[]{R.id.title_row,R.id.note_row,R.id.time_row,R.id.date_row,R.id.repeat_row};
adapterCursor =new SimpleCursorAdapter(MainActivity.this, R.layout.alarm_row, c, from, to);
l_list.setAdapter(adapterCursor);
ContentValues cv = new ContentValues();
cv.put("title",msg);
cv.put("note",note);
cv.put("time",hour+":"+minute);
cv.put("date",month+"/"+day+"/"+year);
cv.put("Repeat","daily");
db.insert("Alarms",null,cv);
and for some reason I'm getting this error:
Caused by: android.database.sqlite.SQLiteException: no such column: id (code 1): , while compiling: SELECT id, title, time, date, repeat, note FROM Alarms
Take a look at your table creation code:
private static final String SQL_CREATE_ENTRIES="CREATE TABLE IF NOT EXISTS"+TABLE_NAME+" ("+rowid+" INTEGER PRIMARY KEY AUTOINCREMENT, "+Title+TEXT_TYPE+Time+TEXT_TYPE+Date+TEXT_TYPE+Repeat+TEXT_TYPE+Note+" TEXT NOT NULL);";
It's a mess, and it's full of errors.
It should be something like:
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME +
" (" + rowid + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
Title + " TEXT, " + Time + " TEXT, " + Date + " TEXT, " +
Repeat + " TEXT, " + Note + " TEXT NOT NULL)";
[EDIT]
Also, this
cv.put("date",month+"/"+day+"/"+year);
is not a valid timeString
This one (assuming that year is a 4 character string and month and day are 2 character strings) is:
cv.put("date", year + "-" + month + "-" + day);
For your reference: http://www.sqlite.org/lang_datefunc.html
I am trying to make a variable Table name through Java.
My code is :
public void createTable(String tableName){
try {
Statement stmt = con.createStatement();
stmt.executeUpdate("CREATE TABLE '"+tableName+"'" +
"(id INTEGER not NULL, " +
" username VARCHAR(255), " +
" pass VARCHAR(255), " +
" age INTEGER, " +
" PRIMARY KEY ( id ))");
}
catch (SQLException e){
e.printStackTrace();
}
}
It gives me a syntax error saying:
Incorrect syntax near 'VariableTableNameIChose'.
Does anyone have any ideas?
It could be one of 2 things or the combination of both.
Maybe the single quotes around the table name are not valid in your database. So do like this:
stmt.executeUpdate("CREATE TABLE "+tableName+" " +
"(id INTEGER not NULL, " +
" username VARCHAR(255), " +
" pass VARCHAR(255), " +
" age INTEGER, " +
" PRIMARY KEY ( id ))");
Or maybe you need a spaces between the table name and the ( following after:
Statement stmt = con.createStatement();
// v this one was missing
stmt.executeUpdate("CREATE TABLE '"+tableName+"' " +
"(id INTEGER not NULL, " +
" username VARCHAR(255), " +
" pass VARCHAR(255), " +
" age INTEGER, " +
" PRIMARY KEY ( id ))");
The table name is an identifier. Identifiers do not use single quotes (in standard SQL).
"CREATE TABLE '"+tableName+"' "
Will result in
CREATE TABLE 'foobar'
which is invalid SQL. You need to remove the single quotes:
"CREATE TABLE "+tableName+" " + ...
As the table name is apparently a user input, you might actually want to use quoted identifiers (although this is in general a bad idea). Identifiers are quoted using double quotes in the SQL standard:
"CREATE TABLE \""+tableName+"\" " + ...