SQLite. Column constraint CHECK doesn't work with an INTEGER column - sqlite

I tested the following cases.
CHECK is applied to an INTEGER column. It doesn't work.
sqlite> CREATE TABLE log (_id INTEGER PRIMARY KEY, timestamp INTEGER NOT NULL, message TEXT NOT NULL, status INTEGER NOT NULL CHECK (status IN (1, 0));
Error: near ";": syntax error
CHECK is applied to a TEXT column. It works.
sqlite> CREATE TABLE log (_id INTEGER PRIMARY KEY, timestamp INTEGER NOT NULL, message TEXT NOT NULL CHECK (message IN ('Bad', 'OK')), status INTEGER NOT NULL);
sqlite> insert into log values (3, 11111, 'OK', 1);
sqlite> select * from log;
3|11111|OK|1
sqlite> insert into log values (3, 11111, 'dsvsdvOK', 1);
Error: constraint failed
Both cases should work if I understand the documentation correctly.
column-constraint
expr

The first CREATE TABLE statement has three opening but only two closing parentheses.

Related

Can't figure out how to create exchange rate tables

These are two commands I try to execute to create a pair or tables related to exchange rates.
CREATE TABLE IF NOT EXISTS Currencies(
numeric_code integer NOT NULL PRIMARY KEY,
code text NOT NULL UNIQUE
CREATE TABLE IF NOT EXISTS ExchangeRates(
id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
numeric_code integer NOT NULL,
exchange_rate real NO NULL,
date_from date NOT NULL,
FOREIGN KEY (numeric_code) REFERENCES Currencies(numeric_code)
I get the error: SQLITE_ERROR: incomplete input errno: 1, code: 'SQLITE_ERROR'
What is wrong? I am not good at SQL queries.

sqlite integer primary key not null constraint failed

According to the SQLite documentation / FAQ a column declared INTEGER PRIMARY KEY will automatically get a value of +1 the highest of the column if omitted.
Using SQLite version 3.22.0 2018-01-22 18:45:57
Creating a table as follows:
CREATE TABLE test (
demo_id INTEGER PRIMARY KEY NOT NULL,
ttt VARCHAR(40) NOT NULL,
basic VARCHAR(25) NOT NULL,
name VARCHAR(255) NOT NULL,
UNIQUE(ttt, basic) ON CONFLICT ROLLBACK
) WITHOUT ROWID;
Then inserting like this:
INSERT INTO test (ttt, basic, name) VALUES ('foo', 'bar', 'This is
a test');
gives:
Error: NOT NULL constraint failed: test.demo_id
sqlite>
When it is expected to create a record with a demo_id value of 1. Even if the table already contains values, it'll fail inserting the row without explicitly specifying the id with the same error.
What am I doing wrong?
The documentation says that you get autoincrementing values for the rowid. But you specified WITHOUT ROWID.

SQLite doesn't care about `varchar` length. Is the same true for `char` length?

When I run sqlite3 foo.db from cmd (Windows) and enter these commands (assuming TABLE 'test' does not exist):
sqlite> CREATE TABLE test (id integer PRIMARY KEY, name char(1));
sqlite> INSERT INTO test (name) VALUES ('aaaaaa');
there are no errors. To verify,
//Input
sqlite> SELECT * FROM test;
//Output
1|aaaaaa
Again, to verify,
sqlite> .schema test
CREATE TABLE test (id integer PRIMARY KEY, name char(1)); //output
and the schema isn't changed.
Is there something wrong, especially with the name char(1) part? For the record, I compiled SQLite3 using MinGW64 with
--host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw // where /mingw is included in my PATH
Thanks in advance.
As there is no types in SQLite, the question is meaningless. All TEXT values are the same and are stored as "unlimited" (up to SQLITE_MAX_LENGTH) length strings.
What you see is a WAD: "working as designed".
SQLite doesn't enforce the length of a char(n) or varchar(n) column as it's declared in a CREATE TABLE statement. But you can enforce length restrictions using a CHECK constraint.
sqlite> create table test (
...> id integer primary key,
...> name char(1),
...> check (length(name)<=1)
...> );
sqlite> INSERT INTO test (name) VALUES ('aaaaaa');
Error: CHECK constraint failed: test

Insert default values in SQLite2

How to crate a now row without knowing the any of the columns of the table and using default values therefore?
In sqlite3 I simply do:
sqlite> CREATE TABLE t ("id" INTEGER PRIMARY KEY, "text" TEXT DEFAULT "hello world");
sqlite> INSERT INTO t DEFAULT VALUES;
sqlite> SELECT * FROM t;
1|hello world
But in sqlite2.8.17 I get:
sqlite> INSERT INTO t DEFAULT VALUES;
SQL error near 'DEFAULT': Syntax error.
Is there a way to do this right in sqlite2 or do I need to give the values manually in the insert statement?
You have to specify at least one value; all the others will then get their default values.
The rowid automatically gets a value when you specify NULL, so you can use that one:
INSERT INTO t(id) VALUES(NULL);

Not empty string constraint in SQLite

Can I create a database constraint on a TEXT column in SQLite disallowing the value of the column to be empty string ""?
I want to allow the column to be null, but disallow empty string.
Yes you can:
sqlite> create table foo (bar TEXT, CHECK(bar <> ''));
sqlite> insert into foo values (NULL);
sqlite> insert into foo values ('bla');
sqlite> insert into foo values ('');
Error: constraint failed
You can use a CHECK constraint (http://www.sqlite.org/lang_createtable.html):
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> create table example(col, CHECK (col is null or length(col) > 0));
sqlite> insert into example values ('');
SQL error: constraint failed
sqlite> insert into example values (null);
sqlite> insert into example values ('sample');
sqlite> .nullvalue NULL
sqlite> select col from example;
NULL
sample
As far as i know doesn't exist a similar constraint in SQLite, but maybe you can workaround with a Trigger that on INSERT and/or UPDATE automatically change the string empty in NULL.

Resources