Why two column created of same name in angular + ionic - deprecated

I am creating a table inside the DB.I am a successfully created a table and able to insert data on table my issue is that in my table I have two "ID" columns but I only created one .why two ID column generate in table.
Follow this step to generate issue :-
Click the bottom right button (enter the text in pop up screen ).Press "add" button .It generate the row in a "cases" table but when you inspect it show two column of "ID" why ?
Here is my code
http://codepen.io/anon/pen/OVPgoP
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE "Cases" ("ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "CaseName" VARCHAR NOT NULL )');
})

It appears that this is the expected behaviour for SQLite, the technology underpinning Web SQL (which is a deprecated technology, btw).
From the docs:
If a table contains a column of type INTEGER PRIMARY KEY, then that column becomes an alias for the ROWID. You can then access the ROWID using any of four different names, the original three names described above or the name given to the INTEGER PRIMARY KEY column. All these names are aliases for one another and work equally well in any context.
Therefore, my guess is that the Chrome devtools are showing the rowid column using its alias (ID), in addition to the alias column explicitly added (ID).
It seems like you don't actually need to explicitly add an ID column with Web SQL/SQLite. It will add one for you, which you can refer to using rowid, _rowid_ or oid in any statement.
EDIT: Here is a fork of your CodePen, with updates and deletes all correctly working.

Totally new to webSQL, so this answer is very useful to me as well. You can't expect primary keys to work properly with webSQL because internally it tracks something called "rowid" as the primary key. Use unique instead, as seen in a useful example here. You can also use this error code from the spec to figure out if a non-unique column value was inserted.

Related

Adapt ON CONFLICT clause to new unique index?

I want to add an extra unique constraint to an existing table. This and other answers say it's not possible with sqlite, and suggest creating an unique index:
ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
This seems to work. However, I'm having trouble with UPSERTs:
INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';
This gives an error:
ON CONFLICT cause does not match any PRIMARY KEY or UNIQUE constraint
Is there any way I could adapt the ON CONFLICT clause of the statement above to work with the new "constraint"?
I tried using new_unique_index, to no avail. If it's impossible, is there any alternative to creating a new table with the new unique constraint and copying the values from the old table into the new one with NULL for the new constraint column? This would be burdensome. I imagine I could create a new table with all of the former's columns, except the old uniques, plus the new unique, and link them somehow, but it sounds messy and I have no idea how to proceed.
Minimum reproducible example:
CREATE TABLE example (foo TEXT, old_unique TEXT, UNIQUE(old_unique));
ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';
Is there any way I could adapt the ON CONFLICT clause of the statement above to work with the new "constraint"?
(old_unique, new_unique) is a not a possible constraint target as there is no index that combines both columns, each is an individual constraint (so you could use one or the other, as my understanding is that you are limited to a single UPSERT clause and a single conflict target).
If instead of :-
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
You used
CREATE UNIQUE INDEX new_unique_index ON example(old_unique,new_unique);
Then the following will work :-
INSERT INTO example (foo,old_unique,new_unique) VALUES('foo','old','new') ON CONFLICT (old_unique,new_unique) DO UPDATE SET foo = 'foo';
(well at least not be rejected due to no covering primary key or index for the given conflict target).
If it's impossible, is there any alternative to creating a new table with the new unique constraint and copying the values from the old table into the new one with NULL for the new constraint column? This would be burdensome.
It's not really burdensome e.g. you could use :-
CREATE TABLE IF NOT EXISTS temp_example (foo, old_unique,new_unique, UNIQUE(old_unique,new_unique));
INSERT INTO temp_example SELECT *,null FROM example;
ALTER TABLE example RENAME TO old_example;
ALTER TABLE temp_example RENAME TO example;
DROP TABLE If EXISTS old_example;
i.e. as you are adding a column and it will be the last column then there is no need to code column names.

SQLite: foreign key referencing data in an FTS5 shadow table

The full-text search extensions of SQLite (FTS3, FTS4, FTS5) create shadow tables. E.g., if I create FTS5-table
CREATE VIRTUAL TABLE test USING fts5(textData);
that will also automatically create several real (non-virtual) tables, with test_content among them, which (apparently) stores the actual data inserted into the original virtual table test.
I know SQLite authors suggest that these shadow tables "should not be accessed directly by the user". But it's not clear from the docs if there are no any guarantee at all about behavior of these tables, or this advise concerns primarily attempts to directly INSERT or UPDATE on them. But what are the risks of reading from these tables?
Specifically - I need another (regular) table to have a FOREIGN KEY which references rowid of the virtual FTS5 table:
CREATE VIRTUAL TABLE test USING fts5(textData);
CREATE TABLE myTable (col1 INTEGER REFERENCES test(rowid));
I couldn't find hints on that in the docs, but my own experiments showed that foreign key just doesn't work here - I still can delete records from the test table even though they are referenced from myTable. However, if instead I do
CREATE VIRTUAL TABLE test USING fts5(textData);
CREATE TABLE myTable (col1 INTEGER REFERENCES test_content(id));
then everything seems to work as needed - I can't delete records from the virtual test table if they are referenced from myTable.
This works because, as follows from direct inspection, the rowid value of the test table is always equal to the id column value of the test_content table. Even when I specify rowid manually like in INSERT INTO test (rowid, value) VALUES (424242, 'foobar'); - then a new row appears in the test_content with the corresponding content and the corresponding id equal to 424242 (even if no preceding records were ever in the table).
So basically, my question is - is this correspondence between the rowid of an FTS5-table and the id of the corresponding <name>_content shadow table guaranteed to hold? Or might this break in some cases or in future versions?

Tying table records together in SQLite3

I am currently working on a database structure in SQLite Studio (not sure whether that's in itself important, but might as well mention), and error messages are making me wonder whether I'm just going at it the wrong way or there's some subtlety I'm missing.
Assume two tables, people-basics (person-ID, person-NAME, person-GENDER) and people-stats (person-ID, person-NAME, person-SIZE). What I'm looking into achieving is "Every record in people-basics corresponds to a single record in people-stats.", ideally with the added property that person-ID and person-NAME in people-stats reflect the associated person-ID and person-NAME in people-basics.
I've been assuming up to now that one would achieve this with Foreign Keys, but I've also been unable to get this to work.
When I add a person in people-basics, it works fine, but then when I go over to people-stats no corresponding record exists and if I try to create one and fill the Foreign Key column with corresponding data, I get this message: "Cannot edit this cell. Details: Error while executing SQL query on database 'People': no such column: people-basics.person" (I think the message is truncated).
The DDL I currently have for my tables (auto-generated by SQLite Studio based on my GUI operations):
CREATE TABLE [people-basics] (
[person-ID] INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE
NOT NULL,
[person-NAME] TEXT UNIQUE
NOT NULL,
[person-GENDER] TEXT
);
CREATE TABLE [people-stats] (
[person-NAME] TEXT REFERENCES [people-basics] ([person-NAME]),
[person-SIZE] NUMERIC
);
(I've removed the person-ID column from people-stats for now as it seemed like I should only have one foreign key at a time, not sure whether that's true.)
Alright, that was a little silly.
The entire problem was solved by removing hyphens from table names and column names. (So: charBasics instead of char-basics, etc.)
Ah well.

How should I go about making sure the value pairs in this table are unique?

I am using Visual Web Developer and Microsoft SQL server. I have a tag table "Entry_Tag" which is as follows:
entry_id
tag_id
I want to make the entry_id and tag_id pairing unique. A particular tag can only be applied to an entry once in the table. I made the two columns a primary key. They are also both foreign keys referencing the ids in their respective tables. When I dragged the tables into the Object Relationship Designer it only showed a relationship line between either "Entry_Tag" and "Entry" or when I tried again between "Entry_tag" and "Tag".
The "Entry_tag" table should have a relationship with both "Tag" and "Entry".
How do I go about doing this?
In general, you can add a unique constraint on the table that includes both columns. In this case, including both of the columns in the primary key should have already done this. If you have relationships set up for each field to other tables, then I believe those relationships should be displayed in the query designer... I see no cause for this given the information you've provided - perhaps you need to post more information.
Create an UNIQUE INDEX to for entry_id and tag_id.
CREATE UNIQUE INDEX index_name ON table (entry_id, tag_id)

SQLITE: Unable to remove an unnamed primary key

I have a sqlite table that was originally created with:
PRIMARY KEY (`column`);
I now need to remove that primary key and create a new one. Creating a new one is easy, but removing the original seems to be the hard part. If I do
.indices tablename
I don't get the primary key. Some programs show the primary key as
Indexes: 1
[] PRIMARY
The index name is typically in the [].
Any ideas?
You can't.
PRAGMA INDEX_LIST('MyTable');
will give you a list of indices. This will include the automatically generated index for the primary key which will be called something like 'sqlite_autoindex_MyTable_1'.
But unfortunately you cannot drop this index...
sqlite> drop index sqlite_autoindex_MyTable_1;
SQL error: index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped
All you can do is re-create the table without the primary key.
I the database glossary; a primary-key is a type of index where the index order is typically results in the physical ordering of the raw database records. That said any database engine that allows the primary key to be changed is likely reordering the database... so most do not and the operation is up to the programmer to create a script to rename the table and create a new one. So if you want to change the PK there is no magic SQL.
select * from sqlite_master;
table|x|x|2|CREATE TABLE x (a text, b text, primary key (`a`))
index|sqlite_autoindex_x_1|x|3|
You'll see that the second row returned from my quick hack has the index name in the second column, and the table name in the third. Try seeing if that name is anything useful.

Resources