I wonder what's wrong with my sql syntax.Its working on mysql but for sqlite gives me error.
CREATE TABLE IF NOT EXISTS `points` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET latin1 NOT NULL,
`longitude` double NOT NULL,
`latitude` double NOT NULL,
`radius` double NOT NULL,
`image` blob NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=4;
INSERT INTO `points` (`id`, `name`, `longitude`, `latitude`, `radius`, `image`)
VALUES (1, 'Isfahan, Iran', 51.678314, 32.65036, 0.064486,
0xffd8ffe000104a46494600010001009600960000fffe001f4c45414420546563686e6f6c6f6769657320496e632e2056312e303100ffdb008400100b0c0e0c0a100e0d0e1211101318281a181616183123251d283b343e3d3a34393841495d4f414558463839516f52586063696a693f4e737b72667a5d676964011112121815182f1a1a2f644339436464646464646464646464646464646464646464646464646464646464646464646464646464646464646464646464646464ffc4003000000203010000000000000000000000000001020304050101010101010100000000000000000000000102030405ffc20011
It should be AUTOINCREMENT as one word.
You dont require this statement: ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci AUTO_INCREMENT=4; which is MySQL specific. Further more, if you are setting the autoincrement value to start from 5, then you shouldn't be inserting an id of value equal to 1.
You do not seem to have a closing bracket after the insert statement.
You should instead try:
CREATE TABLE IF NOT EXISTS `points` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`name` varchar(50) CHARACTER SET latin1 NOT NULL,
`longitude` double NOT NULL,
`latitude` double NOT NULL,
`radius` double NOT NULL,
`image` blob NOT NULL
);
INSERT INTO `points` (`id`, `name`, `longitude`, `latitude`, `radius`, `image`)
VALUES (1, 'Isfahan, Iran', 51.678314, 32.65036, 0.064486,
0xffd8ffe000104a46494600010001009600960000fffe001f4c45414420546563686e6f6c6f6769657320496e632e2056312e303100ffdb008400100b0c0e0c0a100e0d0e1211101318281a181616183123251d283b343e3d3a34393841495d4f414558463839516f52586063696a693f4e737b72667a5d676964011112121815182f1a1a2f644339436464646464646464646464646464646464646464646464646464646464646464646464646464646464646464646464646464ffc4003000000203010000000000000000000000000001020304050101010101010100000000000000000000000102030405ffc20011);
There could be more fixes required as well. Back tick though recognized by SQLite, is a MySQL specific quoting.
Related
I know you have many questions on here about this error, but I cannot understand why all the fields appears to be filled correctly on Logcat, but even so the failure occurs.
Here is the creation of the table:
public void onCreate(SQLiteDatabase db) {
String ddl = "CREATE TABLE Politician (id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE , idpolitician INTEGER NOT NULL, name TEXT NOT NULL, picture TEXT , position TEXT NOT NULL, country TEXT NOT NULL, state TEXT NOT NULL, city TEXT NOT NULL);";
db.execSQL(ddl);
}
Here is where I tried to save.
public void savePolitician(Politician politician) {
ContentValues values = new ContentValues();
values.put("idpolitician", politician.getId());
values.put("name", politician.getName());
values.put("picture", politician.getPictureFilename());
values.put("position", politician.getPosition());
values.put("country", politician.getCountry());
values.put("state", politician.getState());
values.put("city", politician.getCity());
mDatabase.insert("Politician", null, values);
}
And here is the LogCat:
01-08 04:03:31.149 32633-32633/? E/Database﹕ [SQLiteDatabase.java:1428:insert()] Error inserting
state=SP position=governador picture=example idpolitician=1 city=Sao Paulo country=Brasil name=Alckmin
android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:61)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1582)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1426)
at com.politify.dao.DbManegament.savePolitician(DbManegament.java:44)
As you can see all the fields are filled. Anyone can help and tell what i`m doing wrong
try remove AUTOINCREMENT UNIQUE inyour create table script
This is your mistake id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE
When you are defining any column as Primary Key then you do not need to specify it as UNIQUE. Primary Key is by default UNIQUE.
I am building an Android app with an internal SQLite DB.
Here is the schema:
CREATE TABLE IF NOT EXISTS [tblImageVideoLink] (
[LinkID] INTEGER NOT NULL PRIMARY KEY,
[ImageID] INTEGER UNIQUE NOT NULL,
[VideoID] INTEGER NULL
);
CREATE TABLE IF NOT EXISTS [tblImages] (
[ID] INTEGER PRIMARY KEY NOT NULL,
[ImageName] VARCHAR(50) NOT NULL,
[ImageDescription] VARCHAR(100) NULL,
[Page] INTEGER NULL
);
CREATE TABLE IF NOT EXISTS [tblPages] (
[ID] INTEGER NOT NULL PRIMARY KEY,
[PageName] VARCHAR(30) NULL
);
CREATE TABLE IF NOT EXISTS [tblVideos] (
[ID] INTEGER NOT NULL PRIMARY KEY,
[VideoName] VARCHAR(150) NOT NULL,
[VideoDescription] VARCHAR(100) NULL,
[VideoType] VARCHAR(10) NULL
);
CREATE INDEX IF NOT EXISTS [IDX_TBLIMAGEVIDEOLINK_IMAGEID] ON [tblImageVideoLink](
[ImageID] DESC,
[VideoID] DESC
);
CREATE INDEX IF NOT EXISTS [IDX_TBLIMAGES_PAGE] ON [tblImages](
[Page] DESC
);
Here's the relevant data I have in the tables:
INSERT INTO tblImages (ID, ImageName, Page) VALUES (1, 'Beach.jpg', 1);
INSERT INTO tblImages (ID, ImageName, Page) VALUES (2, 'Bowling.jpg', 1);
INSERT INTO tblImages (ID, ImageName, Page) VALUES (3, 'Car.jpg', 1);
INSERT INTO tblVideos (ID, VideoName) VALUES (2, 'Bowling.3gp');
INSERT INTO tblVideos (ID, VideoName) VALUES (3, 'Car.3gp');
INSERT INTO tblImageVideoLink (LinkID, ImageID, VideoID) VALUES (1, 2, 2);
INSERT INTO tblImageVideoLink (LinkID, ImageID, VideoID) VALUES (2, 3, 3);
INSERT INTO tblPages (ID, PageName) VALUES (1, 'Misc');
I am trying to run this query to get all the images with a certain page, and their related videos:
SELECT DISTINCT I.ID AS 'Image ID', I.ImageName, V.ID AS 'Video ID', V.VideoName
FROM tblImages I
LEFT JOIN tblImageVideoLink L ON L.VideoID=V.ID
LEFT JOIN tblVideos V ON L.ImageID=I.ID
WHERE I.Page=1;
When I test it in SQLite Administrator, I am getting the desired result set, which is:
When I test it in the App (or in SQLiteSpy) I am getting a different result set:
I have tried everything I know, including GROUP BY, removing the DISTINCT, different JOIN types, etc.
BTW, SQLiteSpy writes at the bottom: SQLite 3.7.8 while SQLite Administrator writes SQLite 3.5.1. I don't know if it matters.
Please help, and also kindly explain why there's a difference between two SQLite tools...
What you see in SQLLite Admin is (considering your output) same as
SELECT DISTINCT(I.ImageName), V.VideoName
What you actual seeing in app is (considering your output) same as
SELECT DISTINCT(I.ImageName, V.VideoName)
Try brackets
My dear friend and DBA helped me spot my issue. Here's the working query to JOIN the two tables and get the data set I wanted:
SELECT DISTINCT I.ID AS 'Image ID', I.ImageName, V.ID AS 'Video ID', V.VideoName
FROM tblImages I
LEFT JOIN tblImageVideoLink L ON L.ImageID=I.ID
LEFT JOIN tblVideos V ON L.VideoID=V.ID
WHERE I.Page=1;
Thank you all for trying to help.
I havea weird problem in my android application which is related to database relations on foreign keys. The following codes describe my simple database's structure,
i have used SQLiteOpenHelper as a super class for handle database operation
private static final String CATEGORIES_TABLE = "CREATE TABLE __CATEGORIES_TBL(_id INTEGER PRIMARY KEY AUTOINCREMENT, _name TEXT NOT NULL, _desc TEXT NULL,"
+ "_create_date INTEGER NOT NULL, _update_date INTEGER NULL"
+ ", _parent_id INTEGER NULL, FOREIGN KEY(_parent_id) REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT);";
private static final String CARDS_TABLE = "CREATE TABLE __CARDS_TBL(_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "_value TEXT NOT NULL, _play_count INTEGER NULL, "
+ "_category_id INTEGER NOT NULL, FOREIGN KEY(_category_id) REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT);";
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL("PRAGMA foreign_keys = ON;");
db.execSQL(CATEGORIES_TABLE);
db.execSQL(CARDS_TABLE);
Logger.i("DB-INIT-DONE!");
} catch (Exception ex) {
Logger.e("Database on create error", ex);
}
}
as you see everything seems to be O.K and it is; I can insert, edit , select row(s) to/from both tables but unfortunately i can delete rows which they have child rows.
as i expected. because i set the FK (foreign-key) relation between the tow tables with ON DELETE RESTRICT mode therefore i expect to get an exception when i try to delete a row from parent table (__CATEGORIES_TBL) , actually the parent record is deleting and no exception happens,
by theory sqlite must prevent deleting any row in __CATEGORIES_TBL when it has one or more child row(s) in __CARDS_TBL or any child row(s) in __CATEGORIES_TBL but in my application i can delete rows when it has a parent-child relationship rows,
consider the following code (this is the deleting code)
private SQLiteDatabase db;
public long delete(long objId) {
try {
// TABLE_NAME can be __CATEGORIES_TBL or __CARDS_TBL based on program flow
return db.delete(TABLE_NAME, COLUMN_ROWID + "=" + objId, null);
} catch (Exception e) {
Logger.d("Unable to delete category <" + objId + ">.", e);
return -123456;
}
}
every call to db.delete returns 1 (means 1 row is deleted by this command) this code is executing under android 2.3 ;
Thanks in advance.
I get the behavior I'd expect from SQLite 3.7.9.
sqlite> CREATE TABLE __CATEGORIES_TBL (
...> _id INTEGER PRIMARY KEY AUTOINCREMENT,
...> _name TEXT NOT NULL,
...> _desc TEXT NULL,
...> _create_date INTEGER NOT NULL,
...> _update_date INTEGER NULL,
...> _parent_id INTEGER NULL,
...> FOREIGN KEY(_parent_id)
...> REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT
...> );
sqlite>
sqlite> CREATE TABLE __CARDS_TBL(
...> _id INTEGER PRIMARY KEY AUTOINCREMENT,
...> _value TEXT NOT NULL,
...> _play_count INTEGER NULL,
...> _category_id INTEGER NOT NULL,
...> FOREIGN KEY(_category_id)
...> REFERENCES __CATEGORIES_TBL(_id) ON DELETE RESTRICT
...> );
sqlite>
sqlite> insert into __categories_tbl values
...> (1, 'name', 'desc',current_date,current_date,1);
sqlite> insert into __cards_tbl values (1, 'value',3, 1);
sqlite> pragma foreign_keys=on;
sqlite> select * from __categories_tbl;
1|name|desc|2012-08-25|2012-08-25|1
sqlite> delete from __categories_tbl;
Error: foreign key constraint failed
If I were you, I'd try to visually inspect the SQLite database after each step to see whether what you expect to happen is actually happening. IIRC, not every failure will raise an exception.
Foreign key support was introduced in version 3.6.19. There are compile-time settings that allow SQLite to parse foreign key constraints, but don't allow it to actually enforce them. (SQLITE_OMIT_TRIGGER defined, SQLITE_OMIT_FOREIGN_KEY not defined.) You should be able to tell whether your build of SQLite can enforce foreign keys by trying to create a trigger.
If creating a trigger fails with a parse error, then SQLite will parse foreign key statements, but won't enforce them. You'll need to recompile your build of 3.6.19, or upgrade to a newer version. (And check those settings before you compile.)
A column declared NOT NULL can appear to be empty if you've inserted an empty string. By default, NULL and empty strings look identical on output. You can tell whether a column contains nulls by selecting them.
select * from table_name where column_name is null;
about this problem i have put a db.execSQL("pragma foreign_keys=on;"); before delete statement in my app code then the problem solved, but i think this is unnecessary code maybe my phone's installed sqlite configs are wrong and needs to be reconfigured , is it possible to reconfigure the sqlite on phone ?
the test device is a HTC wildfire s (running sqlite version is 3.7.2)
I'm trying to build a database using 21 tables each bind with constraints. I have implemented the database in PHPmyAdmin and then download the structure script to import in my Android SQLite database.
But I would like to know what are the good practices in building relational databases with many tables in Android, and how to create them.
currently I have a class implementing SQLiteOpenHelper:
public class SqlSig extends SQLiteOpenHelper {
#Override
public void onCreate(SQLiteDatabase db) {
for(int i = 0; i != ConfigBDD.requetes.length; i++){
db.execSQL(ConfigBDD.requetes[i]);
}
}
}
ConfigBDD.requetes[i] fetch a string array containing tables creation requests and constraints requests. This code doesn't work at all, and logCat show an error with the PRIMARY KEY instruction:
05-29 15:13:51.992: E/Database(8187): Failure 1 (near "KEY": syntax error) on 0x15c4b8
when preparing 'CREATE TABLE IF NOT EXISTS `arret` ( `id` int(11) NOT NULL , `id_externe`
varchar(10) DEFAULT NULL, `id_pid` int(11) NOT NULL, `nom` varchar(50) NOT NULL,
`description` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `id_pid` (`id_pid`) )
DEFAULT CHARSET=utf8 =1 ;'.
I am pretty sure there are other ways to create this database but did not found any explanations about multi tables Android SQLite database creation...
Your:
CREATE TABLE IF NOT EXISTS `arret` (
`id` int(11) NOT NULL ,
`id_externe` varchar(10) DEFAULT NULL,
`id_pid` int(11) NOT NULL,
`nom` varchar(50) NOT NULL,
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `id_pid` (`id_pid`))
DEFAULT CHARSET=utf8 =1 ;
should probably look something like this if you want it to work in SQLite.
CREATE TABLE IF NOT EXISTS arret (
id INTEGER PRIMARY KEY NOT NULL ,
id_externe TEXT DEFAULT NULL,
id_pid INTEGER NOT NULL,
nom TEXT NOT NULL,
description TEXT
);
followed by a CREATE INDEX for your id_pid which is what KEY implies in MySQL.
Im getting this error when i try to access my View
I've built my database/View using this
CREATE TABLE Boxer(
BoxerId INTEGER PRIMARY KEY AUTOINCREMENT,
Firstname NVARCHAR(50) NOT NULL,
Lastname NVARCHAR(50) NOT NULL
);
CREATE TABLE Match(
MatchId INTEGER PRIMARY KEY AUTOINCREMENT,
BoxerA INTEGER NOT NULL FOREIGN KEY REFERENCES Boxer(BoxerId),
BoxerB INTEGER NOT NULL FOREIGN KEY REFERENCES Boxer(BoxerId),
MatchDate date NOT NULL DEFAULT GETDATE(),
NumberOfRounds INTEGER NOT NULL DEFAULT 12
);
CREATE TABLE Round(
RoundId INTEGER PRIMARY KEY AUTOINCREMENT,
MatchId INTEGER NOT NULL FOREIGN KEY REFERENCES Match(MatchId),
BoxerA INTEGER NOT NULL DEFAULT 0,
BoxerB INTEGER NOT NULL DEFAULT 0,
Position INTEGER NOT NULL
);
/*
Building a view which dislpays matches with boxers names and total scores
*/
CREATE VIEW MatchDetail AS
SELECT Match.MatchId, A.BoxerId AS IdA, B.BoxerId AS IdB, A.Firstname + ' ' + A.Lastname AS NameA, B.Firstname + ' ' + B.Lastname AS NameB,
(SELECT SUM(R.BoxerA) AS Score FROM Round AS R WHERE (R.MatchId = Match.MatchId)) AS ScoreA,
(SELECT SUM(R.BoxerB) AS Score FROM Round AS R WHERE (R.MatchId = Match.MatchId)) AS ScoreB,
Match.MatchDate, Match.NumberOfRounds
FROM Boxer AS A INNER JOIN Match ON A.BoxerId = Match.BoxerA INNER JOIN Boxer AS B ON Match.BoxerB = B.BoxerId
I've pretty much built my app so far using the notepad example so I then call my DbHelper
Cursor MatchesCursor = mDbHelper.fetchAllMatchDetails();
This then calls the query
public Cursor fetchAllMatchDetails(){
return mDb.query(VIEW_MATCHDETAIL, new String[] {
"MatchId"
}, null, null, null, null, null);
}
VIEW_MATCHDETAIL is defined as a string = "MatchDetail"
and it's here where it crashes saying
no such table MatchDetail: while compiling SELECT MatchId FROM MatchDetail
anyone had this problem before?
You have some beautiful SQL there. Unfortunately only the first line of sql will be executed in SQLiteDatabase.execSQL. The rest will be ignored silently (convenient eh?). Split up the statements manually like this:
https://github.com/browep/fpt/blob/master/src/com/github/browep/nosql/NoSqlSqliteOpener.java
or if you like to keep your sql in a separate file, try this:
String sqlText = getSqlText();
for(String sqlStmt : sqlText.split(";"))
myDb.execSQL(slqStmt + ";");
What stands out to me is the use of datatypes like NVARCHAR(50). SQLite only has a very simple set of datatypes. I'm surprised it doesn't throw an exception when you install the app. Try using simply TEXT instead.
If you cannot access a database that you know you have initialized, try passing the Context from the Activity that created the table to the class trying to query the table. Use that Context as part of your connection initialization.