I want to create table and insert some values into it. I'm trying to do it using H2 database and sql2o framework at the code below:
public class Main {
private static final String DB_DRIVER = "org.h2.Driver";
private static final String DB_CONNECTION = "jdbc:h2:~/test";
private static final String DB_USER = "";
private static final String DB_PASSWORD = "";
static String TABLE = "PERSONS";
static Sql2o sql2o;
public static void main(String[] args) throws Exception, SQLException {
sql2o = new Sql2o(DB_CONNECTION, DB_USER, DB_PASSWORD);
createTable();
insertIntoTable();
}
public static void createTable() {
final String tableSql = "CREATE TABLE IF NOT EXISTS " + TABLE + " (id int, name varchar(255))";
try (org.sql2o.Connection con = sql2o.beginTransaction()) {
con.createQuery(tableSql).executeUpdate();
con.commit();
con.close();
}
}
public static void insertIntoTable() {
String insertSql = "insert into " + TABLE + " values (:id, :name)";
try (org.sql2o.Connection con = sql2o.open()) {
con.createQuery(insertSql).addParameter("id", 1).addParameter("name", "test").executeUpdate();
con.close();
}
}
}
And after all I get an error:
Error preparing statement - Column count does not match; SQL
statement: insert into PERSONS values (?, ?) [21002-191]
The SQL statement is correct, the names and types of columns match each other, and I really can't understand what the problem.
There was an existing PERSONS table that did not match the structure in the CREATE TABLE IF NOT EXISTS statement. Dropping and recreating the table solved the problem.
Related
I am new with Android Sqlite Database.
I have created a database with SQLite in Android and I have a table Student_details which use a foreign key of the table: Student, I have made the id as AUTOINCREMENT.
And i tried to return the value of the AUTOINCREMENT Id from Student table.
But I am stuck to use the return values to insert into COLUMN_FR_KEY_USER_ID = "student_id"; as Foreign Key values.
How can I add value with a foreign key from another table using ContentValues into insetDataIntoStudentDetails method?
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "finalStudent.db";
private static final int VERSION_NUMBER = 16;
private static final String TABLE_STUDENT = "Student";
private static final String TABLE_DETAILS_NAME = "Student_details";
private static final String COLUMN_STUDENT_ID = "id";
private static final String COLUMN_DETAILS_ID = "id";
private static final String COLUMN_FR_KEY_USER_ID = "student_id";
private static final String COLUMN_STUDENT_NAME = "name";
private static final String COLUMN_DETAILS_NAME = "name";
private static final String COLUMN_STUDENT_EMAIL = "email";
private static final String COLUMN_STUDENT_PASSWORD = "password";
private static final String CREATE_STUDENT_TABLE = "CREATE TABLE "+TABLE_STUDENT+"( "+COLUMN_STUDENT_ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+COLUMN_STUDENT_NAME+" TEXT, "+COLUMN_STUDENT_EMAIL+" TEXT, "+COLUMN_STUDENT_PASSWORD+" TEXT)";
private static final String CREATE_DETAILS_TABLE = "CREATE TABLE "+TABLE_DETAILS_NAME+"( "+COLUMN_DETAILS_ID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+COLUMN_DETAILS_NAME+" TEXT, "+COLUMN_FR_KEY_USER_ID+" INTEGER, FOREIGN KEY("+COLUMN_FR_KEY_USER_ID+") REFERENCES "+TABLE_STUDENT+" ("+COLUMN_STUDENT_ID+") ON UPDATE CASCADE ON DELETE CASCADE)";
private Context context;
private static final String DROP_TABLE = "DROP TABLE IF EXISTS "+TABLE_STUDENT;
private static final String DROP_DETAILS_TABLE = "DROP TABLE IF EXISTS "+TABLE_DETAILS_NAME;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, VERSION_NUMBER);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
Toast.makeText(context,"Table created successfully and called onCreate method",Toast.LENGTH_SHORT).show();
db.execSQL(CREATE_STUDENT_TABLE);
db.execSQL(CREATE_DETAILS_TABLE);
}catch (Exception e){
Toast.makeText(context,"Exception : "+e,Toast.LENGTH_SHORT).show();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
Toast.makeText(context,"Table created successfully and called onCreate method",Toast.LENGTH_SHORT).show();
db.execSQL(DROP_TABLE);
db.execSQL(DROP_DETAILS_TABLE);
onCreate(db);
}catch (Exception e){
Toast.makeText(context,"Exception : "+e,Toast.LENGTH_SHORT).show();
}
}
public long insertDataIntoStudent( String name, String email, String password){
// to write or read data in database , we have to call getWritableDatabase
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
// we have to call contentValues class to store data in the data
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_STUDENT_NAME,name);
contentValues.put(COLUMN_STUDENT_EMAIL,email);
contentValues.put(COLUMN_STUDENT_PASSWORD,password);
// Insert the new row, returning the primary key value of the new row
long newRowId = sqLiteDatabase.insert(TABLE_STUDENT,null,contentValues);
return newRowId;
}
public void insetDataIntoStudentDetails(String name){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
// TODO: insert the foreign key's value
contentValues.put(name,name);
}
#Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
//enable foreign key constraints like ON UPDATE CASCADE, ON DELETE CASCADE
db.execSQL("PRAGMA foreign_keys=ON;");
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private final AppCompatActivity activity = MainActivity.this;
DatabaseHelper databaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseHelper = new DatabaseHelper(activity);
databaseHelper.insertDataIntoStudent("Bappy","abcd#gmail.com","145456");
}
}
I'll answer about databases in general, not specifically about Sqlite or it's usage in Android.
So you have student's name (which is not a primary key), but you need to save some additional data for this student to another table. The steps are:
Execute SELECT id FROM students WHERE name = ? to find the relevant identifier.
Execute INSERT INTO student_details for your secondary table using retrieved id as a key.
Extra tips:
Name is not a good unique identifier. It's good to have one more criteria - such as some group name, or group number or even date of birth.
When your database is large enough you may benefit from index for your search criteria to optimize execution of the first query. But usually it's not the case for client-side (in-app) databases.
Here we assume that name is not the data which could be updated by someone (or something) else between searching for id and executing INSERT. Otherwise it's wise to use transaction and "lock" your student until you complete the updates.
I'm quite new to Android and I guess it's a stupid question but i'll be glad to recieve help. I've got a code in one activity which set a database to SQLite. In another activity I want to refer to this SQLite code in order to enter it into a json and send it to a remote server.
The problem is that it's not recognizing the variable from the other activity. here is the code which creates the data from the db into a string.
In this example I want to create an ArrayList from the db, but it couldnt find the set functions I developed or the table name. Am I missed something ? Here is the code of the ArrayList :
GpsPage.java
public class PersonsDatabaseHandler extends SQLiteOpenHelper {
//Database Name
private static final String DATABASE_NAME = "RecordsDB";
//Table names
private static final TABLE_RECORD = "record";
//Get all Persons
public ArrayList<Record> getAllPersons() {
ArrayList<Record> localList = new ArrayList<Record>();
String selectQuery = "SELECT * FROM " + TABLE_RECORD;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
//Loops through all rows and adds them to the local list
if(cursor.moveToFirst())
{
do {
//Get person information
Record record = new Record();
Record.setpLong(cursor.getString(0));
Record.setpLat(cursor.getString(1));
Record.setpAcc(cursor.getString(2));
Record.setpTime(cursor.getString(3));
//Add person to list
localList.add(record);
} while (cursor.moveToNext());
}
return localList;
}
}
And here are the codes from the two other java pages (activities), the first one define the get and set of the records :
Record.Java
package com.program.android.taskir;
public class Record {
//private variables
private int id;
private double pLong;
private double pLat;
private float pAcc;
private long pTime;
public Record(){}
// Empty constructor
// constructor
public Record( double pLong, double pLat, float pAcc, long pTime){
super();
this.pLong = pLong;
this.pLat= pLat;
this.pAcc= pAcc;
this.pTime= pTime;
}
#Override
public String toString() {
return "Record [id=" + id + ", Longtitude=" + pLong + ", Latitude=" + pLat + ", Accuracy" + pAcc + ", Time" +pTime
+ "]";
}
// getting ID
public int getID(){
return this.id;
}
// setting id
public void setID(int id){
this.id = id;
}
// getting pLong
public double getpLong(){
return this.pLong;
}
// setting pLong
public void setpLong(double pLong){
this.pLong = pLong;
}
// getting pLat
public double getpLat(){
return this.pLat;
}
// setting pLat
public void setpLat(double pLat){
this.pLat = pLat;
}
// getting pAcc
public float getpAcc(){
return this.pAcc;
}
// setting pAcc
public void setpAcc(float pAcc){
this.pAcc = pAcc;
}
// getting pTime
public long getpTime(){
return this.pTime;
}
// setting pTime
public void setpTime(long pTime){
this.pTime = pTime;
}
}
and the activity which creates the db :
MySQLiteHelper.java
package com.program.android.taskir;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.LinkedList;
import java.util.List;
public class MySQLiteHelper extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "RecordsDB";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// SQL statement to create record table
String CREATE_RECORD_TABLE = "CREATE TABLE RECORD ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"latitude TEXT NOT NULL, " +
"longtitude TEXT NOT NULL, " +
"accuracy TEXT NOT NULL, " +
"time TEXT NOT NULL )";
// create books table
db.execSQL(CREATE_RECORD_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older books table if existed
db.execSQL("DROP TABLE IF EXISTS Records");
// create fresh record table
this.onCreate(db);
}
// Books table name
private static final String TABLE_RECORD = "record";
// Books Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_LONG = "longtitude";
private static final String KEY_LAT = "latitude";
private static final String KEY_ACC = "accuracy";
private static final String KEY_TIME = "time";
private static final String[] COLUMNS = {KEY_ID, KEY_LONG, KEY_LAT, KEY_ACC, KEY_TIME};
public void addRecord(Record record) {
//for logging
Log.d("addBook", record.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_LONG, record.getpLong());
values.put(KEY_LAT, record.getpLat());
values.put(KEY_ACC, record.getpAcc());
values.put(KEY_TIME, record.getpTime());
// 3. insert
db.insert(TABLE_RECORD, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
}
public Record getRecord(int id) {
// 1. get reference to readable DB
SQLiteDatabase db = this.getReadableDatabase();
// 2. build query
Cursor cursor =
db.query(TABLE_RECORD, // a. table
COLUMNS, // b. column names
" id = ?", // c. selections
new String[]{String.valueOf(id)}, // d. selections args
null, // e. group by
null, // f. having
null, // g. order by
null); // h. limit
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
Record record = new Record();
record.setID(Integer.parseInt(cursor.getString(0)));
record.setpLat(cursor.getDouble(1));
record.setpLong(cursor.getDouble(2));
record.setpAcc(cursor.getFloat(2));
record.setpTime(cursor.getLong(2));
//log
Log.d("getBook(" + id + ")", record.toString());
// 5. return book
return record;
}
public List<Record> getAllRecords() {
List<Record> records = new LinkedList<Record>();
// 1. build the query
String query = "SELECT * FROM " + TABLE_RECORD;
// 2. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
// 3. go over each row, build book and add it to list
Record record = null;
if (cursor.moveToFirst()) {
do {
record = new Record();
record.setID(Integer.parseInt(cursor.getString(0)));
record.setpLat(cursor.getDouble(1));
record.setpLong(cursor.getDouble(2));
record.setpAcc(cursor.getFloat(2));
record.setpTime(cursor.getLong(2));
// Add book to books
records.add(record);
} while (cursor.moveToNext());
}
Log.d("getAllRecords()", record.toString());
// return books
return records;
}
public int UpdateRecords(Record record) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put("Latitude", record.getpLat()); //
values.put("Longtitude", record.getpLong());
values.put("Accuracy", record.getpAcc());
values.put("Time", record.getpTime());
// 3. updating row
int i = db.update(TABLE_RECORD, //table
values, // column/value
KEY_ID + " = ?", // selections
new String[]{String.valueOf(record.getID())}); //selection args
// 4. close
db.close();
return i;
}
public void deleteRecords(Record record) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. delete
db.delete(TABLE_RECORD, //table name
KEY_ID + " = ?", // selections
new String[]{String.valueOf(record.getID())}); //selections args
// 3. close
db.close();
//log
Log.d("deleteBook", record.toString());
}
}
Thank you!
What you are looking for is a Bundle. It's used to pass data between activities. Take a look at What is a "bundle" in an Android application and you can understand how it's done.
I have a small question to you guys.
I tryed to add user to database.
User have field like: id, name, surname etc.
Method
public static String insertUsertoDatabase(Connection con, User userToAdd)
doing something like this
// the mysql insert statement
String query = " insert into User (id,log,pass)"
+ " values (?, ?, ?)";
// create the mysql insert preparedstatement
PreparedStatement preparedStmt = con.prepareStatement(query);
preparedStmt.setInt(1, 1);
preparedStmt.setString(2, "h");
preparedStmt.setString(3, "l");
setUser method
public String setUser(User userToBase) {
return insertUsertoDatabase(con, userToBase);
}
and main.java
User us1 = new User("9", "h", "l");
db.setUser(us1); //insert to database User u1
How can I put values from User constructor to preparedStmt ?
I have a constructor like that:
public class User(id, login, pass) {
this.id = id;
etc.
}
but i want to know how can I send data from constructor
User us1 = new User("9", "h", "l");
to my method
public static String insertUsertoDatabase(Connection con, User userToAdd)
preparedStmt.setInt(1, 9); <------------- from User constructor
preparedStmt.setString(2, "h");
preparedStmt.setString(3, "l");
You probably need something like that:
// TODO: use meaningful names
private String pim;
private String pam;
private String poom;
public User(String pim, String pam, String poom) {
this.pim = pim;
this.pam = pam;
this.poom = poom;
}
public String getPim() {
return this.pim;
}
// ...
Then:
User usr1 = new User("9", "h", "l");
usr1.getPim() // = "9"
// ...
Some reading on constructors
Hi while developing one of my web application i am storing the user information in to an ArrayList based on sql query executed, it contain duplicate objects how to remove duplicate objects in list , i already tried some method but it still not working.
This Is My Code Correct me where i am wrong
public ArrayList loadData() throws ClassNotFoundException, SQLException {
ArrayList userList = new ArrayList();
String url = "";
String dbName = "";
String userName = "";
String password = "";
Connection con = null;
Class.forName("org.apache.derby.jdbc.ClientDriver");
con = DriverManager.getConnection(url + dbName, userName, password);
PreparedStatement ps = null;
try {
String name;
String fatherName;
int Id;
String filePath;
int age;
String address;
String query = "SELECT NAME,FATHERNAME,AGE,ADDRESS,ID,FILEPATH FROM USER_INFORMATION ,USER_PHOTO WHERE ID=USER_ID";
ps = con.prepareStatement(query);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
name = rs.getString(1);
fatherName = rs.getString(2);
age = rs.getInt(3);
address = rs.getString(4);
Id = rs.getInt(5);
filePath=rs.getString(6);
/* if(flag)
{
prev=Id;
flag=false;
}
else if(Id==prev)
{
TEMP=TEMP+";"+filePath;
}*/
//PhotoList = PhotoList(Id, con);
UserData list = new UserData();
list.setName(name);
list.setFatherName(fatherName);
list.setAge(age);
list.setAddress(address);
list.setId(Id);
// list.setFilePath(filePath);
userList.add(list);
}
ps.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
ArrayList al = new ArrayList();
HashSet hs = new HashSet();
hs.addAll(userList);
al.clear();
al.addAll(hs);
return al;
}
And My Bean Class contant is
public class UserData {
private String name;
private String fatherName;
private int Id;
//private String filePath;
private int age;
private String address;
public UserData()
{
}
public UserData(String name, String fatherName,int Id, int age,String address)
{
this.name = name;
this.fatherName = fatherName;
this.Id = Id;
//this.filePath=filePath;
this.age=age;
this.address=address;
}
//GETTER AND SETTER..
General Idea: Use Set, not List. But you must override hash and equals of the class.
If you want a Collection of objects that does not have a specific order and you don't want duplicates, it's better for you just to use a Set like for example HashSet, or, if in your set the order is important, the TreeSet.
Just remember to override the hash and equals methods.
if you add this to your bean everything should work:
public int hashCode() {
return (name + fatherName+ Id + filePath + age + address).hashCode();
}
public boolean equals(Object obj) {
return ( hashCode() == obj.hashCode() );
}
Your userdata class does not implement equals or hashcode. This means two instances created with the same values will not be counted as duplicates. This is why the set contains duplicates.
For example
UserData u1 = new UserData("Foo", "bar",1, 1,"baz");
UserData u2 = new UserData("Foo", "bar",1, 1,"baz");
u1 and u2 are not considered equal as they are different objects. Adding an equals and hashcode method should fix this. However even better is adarshr's idea of removing dupes in the SQL.
All duplicates must be removed at an SQL level. Your SQL is suggesting that it could be generating duplicate records.
String query = "SELECT NAME,FATHERNAME,AGE,ADDRESS,ID,FILEPATH FROM USER_INFORMATION ,USER_PHOTO WHERE ID=USER_ID";
What does the clause ID = USER_ID mean? Shouldn't you be passing in that value as an input to your query?
Also, is the column ID a primary key? Otherwise, use a where clause that doesn't generate duplicates.
I am making an app for android with a SQLite Database that have only one table and two columns: one for names and the other for marks. Also, I can see the information of the database in a listview and I can add more elements to it. How can I make the average of the marks which are in the database? And how can I delete a row?
I paste my database helper
public class PersonDatabaseHelper {
private static final String TAG = PersonDatabaseHelper.class.getSimpleName();
// database configuration
// if you want the onUpgrade to run then change the database_version
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "mydatabase.db";
// table configuration
private static final String TABLE_NAME = "person_table"; // Table name
private static final String PERSON_TABLE_COLUMN_ID = "_id"; // a column named "_id" is required for cursor
private static final String PERSON_TABLE_COLUMN_NAME = "person_name";
private static final String PERSON_TABLE_COLUMN_PIN = "person_pin";
private DatabaseOpenHelper openHelper;
private SQLiteDatabase database;
// this is a wrapper class. that means, from outside world, anyone will communicate with PersonDatabaseHelper,
// but under the hood actually DatabaseOpenHelper class will perform database CRUD operations
public PersonDatabaseHelper(Context aContext) {
openHelper = new DatabaseOpenHelper(aContext);
database = openHelper.getWritableDatabase();
}
public void insertData (String aPersonName, String aPersonPin) {
// we are using ContentValues to avoid sql format errors
ContentValues contentValues = new ContentValues();
contentValues.put(PERSON_TABLE_COLUMN_NAME, aPersonName);
contentValues.put(PERSON_TABLE_COLUMN_PIN, aPersonPin);
database.insert(TABLE_NAME, null, contentValues);
}
public Cursor getAllData () {
String buildSQL = "SELECT * FROM " + TABLE_NAME;
Log.d(TAG, "getAllData SQL: " + buildSQL);
return database.rawQuery(buildSQL, null);
}
// this DatabaseOpenHelper class will actually be used to perform database related operation
private class DatabaseOpenHelper extends SQLiteOpenHelper {
public DatabaseOpenHelper(Context aContext) {
super(aContext, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// Create your tables here
String buildSQL = "CREATE TABLE " + TABLE_NAME + "( " + PERSON_TABLE_COLUMN_ID + " INTEGER PRIMARY KEY, " +
PERSON_TABLE_COLUMN_NAME + " TEXT, " + PERSON_TABLE_COLUMN_PIN + " TEXT )";
Log.d(TAG, "onCreate SQL: " + buildSQL);
sqLiteDatabase.execSQL(buildSQL);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
// Database schema upgrade code goes here
String buildSQL = "DROP TABLE IF EXISTS " + TABLE_NAME;
Log.d(TAG, "onUpgrade SQL: " + buildSQL);
sqLiteDatabase.execSQL(buildSQL); // drop previous table
onCreate(sqLiteDatabase); // create the table from the beginning
}
}
}
Use the avarage (avg) aggregate function:
String query = "SELECT AVG("+PERSON_TABLE_COLUMN_PIN +") FROM "+TABLE_NAME;
and then use SQLiteDatabase.rawQuery(String sql, String[] selectionArgs) for executing the query. Something like:
database.rawQuery(query, null);
Here you can find a sample fiddle.
While, for deleting a row, you can use SQLiteDatabase.delete(String table, String whereClause, String[] whereArgs). For example:
String where = PERSON_TABLE_COLUMN_ID+"=?";
String[] whereArgs = new String[]{String.valueOf(59)};
database.delete(TABLE_NAME, where, whereArgs);
the above code delete the row with id 59.