Adobe Air Database - sql

I have 3 Questions
1) Can Adobe Air Database create more than 1 table in the DB?
will it work by just executing two create table statement work?
sqls.sqlConnection = sqlc;
sqls.text = "Create table if not exists test_table ( id INTEGER PRIMARY KEY autoincrement, first_name TEXT, last_name TEXT);"
sqls.execute();
sqls.text = "Create table if not exists test_table2 ( id INTEGER PRIMARY KEY autoincrement, first_name TEXT, last_name TEXT);";
sqls.execute();
2) How can i do SQL indexing for a table in a database?
sqls.text= "create index index_1 ON test_table (first_name);";
sqls.execute();
Will this work for indexing?
3) If all the above work, how to i check if the database is implementing the above?

1) Yes.
2) Yes. http://www.sqlite.org/lang_createindex.html I'm not sure if this is what you want, but you can force the use of an index in SQLite via the INDEXED BY keyword: http://www.sqlite.org/lang_indexedby.html

Related

Remove Unique constraint on a column in sqlite database

I am trying to remove a UNIQUE constraint on a column for sqlite but I do not have the name to remove the constraint. How can I find the name of the UNIQUE constraint name to remove it.
Below is the schema I see for the table I want to remove the constraint
UNIQUE (datasource_name)
sqlite> .schema datasources
CREATE TABLE "datasources" (
created_on DATETIME NOT NULL,
changed_on DATETIME NOT NULL,
id INTEGER NOT NULL,
datasource_name VARCHAR(255),
is_featured BOOLEAN,
is_hidden BOOLEAN,
description TEXT,
default_endpoint TEXT,
user_id INTEGER,
cluster_name VARCHAR(250),
created_by_fk INTEGER,
changed_by_fk INTEGER,
"offset" INTEGER,
cache_timeout INTEGER, perm VARCHAR(1000), filter_select_enabled BOOLEAN, params VARCHAR(1000),
PRIMARY KEY (id),
CHECK (is_featured IN (0, 1)),
CHECK (is_hidden IN (0, 1)),
FOREIGN KEY(created_by_fk) REFERENCES ab_user (id),
FOREIGN KEY(changed_by_fk) REFERENCES ab_user (id),
FOREIGN KEY(cluster_name) REFERENCES clusters (cluster_name),
UNIQUE (datasource_name),
FOREIGN KEY(user_id) REFERENCES ab_user (id)
);
SQLite only supports limited ALTER TABLE, so you can't remove the constaint using ALTER TABLE. What you can do to "drop" the column is to rename the table, create a new table with the same schema except for the UNIQUE constraint, and then insert all data into the new table. This procedure is documented in the Making Other Kinds Of Table Schema Changes section of ALTER TABLE documentation.
I just ran into this myself. An easy solution was using DB Browser for SQLite
It let me remove a unique constraint with just a checkbox in a gui.
PRAGMA foreign_keys=off;
BEGIN TRANSACTION;
ALTER TABLE table_name RENAME TO old_table;
CREATE TABLE table_name
(
column1 datatype [ NULL | NOT NULL ],
column2 datatype [ NULL | NOT NULL ],
...
);
INSERT INTO table_name SELECT * FROM old_table;
COMMIT;
PRAGMA foreign_keys=on;
Source: https://www.techonthenet.com/sqlite/unique.php
I was just working through this issue on a small database and found it easier to dump the data as SQL statements, it prints out your tables exactly as they are and also adds the INSERT INTO statements to rebuild the DB.
The .help terminal command shows:
.dump ?OBJECTS? Render database content as SQL
and prints the SQL to the terminal, you can update it in a TXT file. For once off changes and tidying this seems like a reasonable solution albeit a little inelegant

How to use soft order with JOIN

I want to use table JOIN with soft order for these tables:
CREATE TABLE ACCOUNT(
ID INTEGER NOT NULL,
USER_NAME TEXT NOT NULL,
PASSWD TEXT,
FIRST_NAME TEXT,
LAST_NAME TEXT,
E_MAIL TEXT NOT NULL,
COUNTRY TEXT,
STATE TEXT,
CITY TEXT,
ADDRESS TEXT,
STATUS INTEGER,
SECURITY_QUESTION TEXT,
SECURITY_ANSWER TEXT,
LAST_PASSWD_RESET DATE,
DESCRIPTION TEXT,
LAST_UPDATED DATE,
CREATED DATE
)
;
-- ADD KEYS FOR TABLE ACCOUNT
ALTER TABLE ACCOUNT ADD CONSTRAINT KEY1 PRIMARY KEY (ID)
;
ALTER TABLE ACCOUNT ADD CONSTRAINT USER_NAME UNIQUE (USER_NAME)
;
ALTER TABLE ACCOUNT ADD CONSTRAINT E_MAIL UNIQUE (E_MAIL)
;
-- TABLE ACCOUNT_ROLE
CREATE TABLE ACCOUNT_ROLE(
ID INTEGER NOT NULL,
USER_NAME TEXT NOT NULL,
ROLE INTEGER,
PERMISSION TEXT,
LAST_UPDATED DATE,
CREATED DATE
)
;
-- CREATE INDEXES FOR TABLE ACCOUNT_ROLE
CREATE INDEX IX_RELATIONSHIP19 ON ACCOUNT_ROLE (ID)
;
-- ADD KEYS FOR TABLE ACCOUNT_ROLE
ALTER TABLE ACCOUNT_ROLE ADD CONSTRAINT KEY26 PRIMARY KEY (ID)
;
ALTER TABLE ACCOUNT_ROLE ADD CONSTRAINT RELATIONSHIP19 FOREIGN KEY (ID) REFERENCES ACCOUNT (ID) ON DELETE CASCADE ON UPDATE CASCADE
;
Working query:
SELECT * FROM ACCOUNT ORDER BY %S %S offset ? limit ?
I tried this SQL query:
SELECT *
FROM ACCOUNT_ROLE
INNER JOIN ACCOUNT ON ACCOUNT.ID = ACCOUNT_ROLE.ID
ORDER BY Account.%S Account.%S offset ? limit ?
But I get this error message:
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "Account"
Position: 99
How I can fix this query? I would like to get the data from two tables and sort it based in value.
It is not entirely clear what you are asking so instead I am proposing a few troubleshooting steps:
It looks like you are trying to do some query preprocessing. Please log the query after this is done and troubleshoot based on that. Failing that, check the PostgreSQL logs for the failing query text string (the logged query is better because of how placeholders are handled).
Once you are looking at the query itself, then look at it for syntax errors.
The problems are almost certainly in portions of your code you have not shown us. Knowing how to get the troubleshooting process started however can be worth mentioning.

Learn SQL The Hard Way - Exercise 2 - Creating Multitable DB - .schema command

I understand the sql in this exercise perfectly, but the setup type tasks are confusing to me. Zed asks you to use the following SQL to create the following tables in a new database that are related by the id key. I'm fine there.
CREATE TABLE person (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
age INTEGER
);
CREATE TABLE pet (
id INTEGER PRIMARY KEY,
name TEXT,
breed TEXT,
age INTEGER,
dead INTEGER
);
CREATE TABLE person_pet (
person_id INTEGER,
pet_id INTEGER
);
In my windows command prompt I entered:
C:\SQLite> sqlite3 ex2.db < ex2.sql
ex2.db is my new db and ex2.sql contains the create statements listed above.
Zed then asks you to enter .schema using the sqlite command prompt. Nothing happens for me. It does not dump. Does .schema only work with Linux or OSX? I'm on windows.
The following is what he says you should get:
sqlite> .schema
CREATE TABLE person (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
age INTEGER
);
CREATE TABLE person_pet (
person_id INTEGER,
pet_id INTEGER
);
CREATE TABLE pet (
id INTEGER PRIMARY KEY,
name TEXT,
breed TEXT,
age INTEGER,
dead INTEGER
);
sqlite>
Instead, this is what I get:
sqlite> .schema
sqlite>
You have to start the sqlite3 tool with:
C:\SQLite> sqlite3 ex2.sb
sqlite> .schema
...
Without a database file name, sqlite3 just creates a temporary database.
In the Windows command prompt type:
C:\SQLite> sqlite3 ex3.db
sqlite will open.
sqlite> .schema
Create statements will display.

Can these three SQLITE INSERTS be combinded or improved?

I have three tables:
CREATE TABLE "local" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "serialNumber" TEXT, "location" TEXT)
CREATE TABLE "setups" ("id" INTEGER PRIMARY KEY NOT NULL ,"hold" TEXT,"mode" INTEGER,"setTemp" REAL,"maxSTemp" REAL,"minSTemp" REAL,"units" TEXT,"heat" INTEGER,"heatMode" INTEGER,"fanMode" INTEGER,"fan" INTEGER,"cool" INTEGER)
CREATE TABLE "data" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,"humidity" REAL,"time" INTEGER,"filtChng" INTEGER,"indoorTemp" REAL,"outdoorTemp" REAL, "setups_id" INTEGER, "local_id" INTEGER)
Everytime I get a new entry I execute:
INSERT INTO local ('serialNumber') SELECT 'XXXX' WHERE NOT EXISTS (SELECT * FROM local WHERE serialNumber='XXXX')"
INSERT INTO setups ('hold','mode','setTemp','maxSTemp','minSTemp','units','heat','heatMode','fanMode','fan','cool') SELECT '00',1,74.0,74.0,74.0,'F',1,1,1,1,1 WHERE NOT EXISTS (SELECT * FROM setups WHERE hold='00' AND mode=1 AND setTemp=74.0 AND maxSTemp=74.0 AND minSTemp=74.0 AND units='F' AND heat=1 AND heatMode=1 AND fanMode=1 AND fan=1 AND cool=1)
INSERT INTO data ('humidity','filtChng','time','indoorTemp','outdoorTemp',local_id,setups_id) SELECT 74.0,111111111,100,74.0,74.0,local.id,setups.id FROM local CROSS JOIN setups WHERE local.serialNumber='XXXX' AND setups.hold='00' AND setups.mode=1 AND setups.setTemp=74.0 AND setups.maxSTemp=74.0 AND setups.minSTemp=74.0 AND setups.units='F' AND setups.heat=1 AND setups.heatMode=1 AND setups.fanMode=1 AND setups.fan=1 AND setups.cool=1
What I am doing works, but seems slow and redundant/inefficient...
Well, you can remove the "where not exists" part from the "local" insert if you use a unique constraint on the "serialNumber" field. Be careful, this will throw a constraint violation instead of just not inserting the row. So be sure to handle that in the application.
And though I assume it is, be sure that checking for duplicates is really necessary in your app.

sqlite3 explain table_name

In mysql you can view a table's structure via explain tablename; What is the equivalent for sqlite3?
I believe ".schema tablename" is what you're looking for.
You can use .schema in the Command Line Shell:
With no arguments, the ".schema"
command shows the original CREATE
TABLE and CREATE INDEX statements that
were used to build the current
database. If you give the name of a
table to ".schema", it shows the
original CREATE statement used to make
that table and all if its indices.
This was already answered in a more generic way here.
Edit:
Note that .schema will also give you INDEXES that match the same name.
Example:
CREATE TABLE job (
id INTEGER PRIMARY KEY,
data VARCHAR
);
CREATE TABLE job_name (
id INTEGER PRIMARY KEY,
name VARCHAR
);
CREATE INDEX job_idx on job(data);
Note the differences between:
sqlite> SELECT sql FROM SQLITE_MASTER WHERE type = 'table' AND name = 'job';
CREATE TABLE job (
id INTEGER PRIMARY KEY,
data VARCHAR
)
sqlite> SELECT sql FROM SQLITE_MASTER WHERE name = 'job_idx';
CREATE INDEX job_idx on job(data)
and
sqlite> .schema job
CREATE TABLE job (
id INTEGER PRIMARY KEY,
data VARCHAR
);
CREATE INDEX job_idx on job(data);
Including the semi-colon at the end of the queries.