Altering a column on SQLite after definition - sqlite

I was following an SQLite tutorial where the goal is to create a simple student database from an UML diagram.
The first thing I did was copy your UML, then took a break. Upon return, I figured I'd get started from the UML while reloading your video, so the very first things I did was create the student and sex_type table as so:
sqlite> create table student(name VARCHAR(23),
...> sex CHARACTER(1),
...> id_number INTEGER PRIMARY KEY);
sqlite> create table sex_type(sex_id TEXT PRIMARY KEY, sex_type INTEGER);
But then I realized, I forgot to indicated that I want sex_id to be NOT NULL as well. I also forgot under the to ensure that Foreign Key(sex) references sex_type(sex_id).
I reviewed my SQL books, and recalled something known as the ALTER command. However, no matter how I slice it, I get something along these lines:
sqlite> alter table sex_type MODIFY column sex_id TEXT PRIMARY KEY NOT NULL;
Error: near "MODIFY": syntax error
sqlite> alter table sex_type CHANGE column sex_id TEXT PRIMARY KEY NOT NULL;**
Error: near "CHANGE": syntax error
sqlite> alter table sex_type drop sex_id;
Error: near "DROP": syntax error
Always with the same supposed syntax error. About the only thing that has worked tonight:
sqlite> alter table sex_type RENAME TO gender;
sqlite> alter table gender_id RENAME TO sex_type;
So what is this syntax error that I'm overlooking, because going by my books my syntax should be fine. Do I have to insert something into these columns before modification can be done (which admittedly, I haven't tried yet)? Or am I missing something obvious about the ALTER/MODIFY/CHANGE/DROP command(s)?

SQLite's support for ALTER TABLE is pretty limited, including only RENAME TO and ADD_COLUMN. You're getting syntax errors because you're issuing a command that's not supported.
If you don't have any data to lose, you might be better of dropping and recreating the table.
If you do have data to lose, you might be better off renaming the table and creating a replacement using INSERT with SELECT, as seen in this example.

Related

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 does sqlite ON CONFLICT clause work in a column definition?

I have the following example:
sqlite> create table FILES (FILENAME VARCHAR(1024) PRIMARY KEY NOT NULL ON CONFLICT IGNORE);
With this, I gather from the documentation that an insert that violates this primary key would be ignored.
But that's not happening, the 2. insert gives an error.
sqlite> insert into files values ('fileA');
sqlite> insert into files values ('fileA');
Error: UNIQUE constraint failed: FILES.FILENAME
So, how does ON CONFLICT IGNORE work in the above table, what is its purpose ?
(Note - I know I can also run insert or ignore into files values ('fileA');, and that will be ignored, but the question is about the column definition).
The conflict resolution clause applies to the NOT NULL constraint, so it would ignore only NULL values.
To ignore duplicates, add ON CONFLICT IGNORE directly after the PRIMARY KEY constraint.

SQLite does not give syntax error on mistyped data type

I am new to sqlite3 but this seems strange for any dbms
I was trying to create the following table but mistyped decimal to dcimal
sqlite> CREATE TABLE ac(
...> name char(4),
...> pay dcimal(18,5)
...> );
However it allowed me to create the table.
To add to my surprise I tested the below CREATE TABLE
sqlite> CREATE TABLE ac(
...> name r(4),
...> pay l(18,5)
...> );
in both cases not only it allows me to create table but also allows me to insert and retrieve data from it.
sqlite> insert into ac values ('dbcd',18.2);
sqlite> select * from ac;
dbcd|18.2
Is there any way to enforce strict syntax checks, so that it error outs on these junk data types ?
Thanks
Sam
No.
SQLite uses dynamic typing, so it does not care whether you are using dcimal or fluffy bunnies or no data type at all.

Copy SQLite table including metadata

I wanted to add a constraint to an existing column in my SQLite database. However, I read that it is not possible to do so.
I tried the solution from How do I rename a column in a SQLite database table?, but there seems to be missing the copying of all the metadata.
I pretty much want an exact copy of a given table, except for the new constraints.
How does the INSERT command look like to copy all the metadata, thus the indexes will increase correctly, for example.
I'm not a heavy user of sqlite3, but you can use the command line to get the data and "create table" and "create index" commands. I am using the 'History' DB from the Google chrome browser which has a table called "visits". The 'mode insert' command says to provide output in a format that can be used to input this data. The '.schema visits' command says to show the 'create table' and 'create index' statements. The 'select..' statement gives you the data. The database I used doesn't seem to have any foreign key constraints, but they could very well be part of the 'create table' information if your DB has any.
sqlite3 History
.mode insert
.schema visits
select * from visits;

SQLite - How to insert to table with preliminary scan of the fields?

I use a database in my project and when i insert values ​​into a table i need to check if the field already has a value that does not produce an insert.
for exemple:
INSERT INTO myTable (column1) values ('some_value1')
if some_value1 alredy exists in column1 do not insert the value.
Put a unique constraint on myTable.column1. Then, whenever you try to insert a duplicate value, it won't let you as it violates the constraint. You can either catch and handle this error, or just let the DB engine do it's thing automatically.
EDIT: Note that SQLite doesn't allow you to do many alterations to your table, once it's created; so you may have to recreate your table with the constraint in place.
I believe this can be handled using the conflict resolution IGNORE method on SQLite. The code below should do the trick. The column1 here should be set to unique for this.
INSERT OR IGNORE INTO myTable (column1) values ('some_value1')
I'm using the following links for reference;
http://www.sqlite.org/lang_insert.html
http://www.sqlite.org/lang_conflict.html

Resources