SQLite: duplicate column error from Create Table - sqlite

I'm a first time user for SQLite. I'm using command line SQLite, version 3.20.1 2017-08-24 16:21:36 on a Mac
I start SQLite by specifying the db file via the command line:
sqlite3 ~/www/sqlite/statistics.db
I try to create a table but receive the error duplicate column name
Advice appreciated. In the transcript below, I first tested with a 1 column table.
sqlite> CREATE TABLE api_methods(
...>    id INTEGER PRIMARY KEY
...> );
sqlite> SELECT name FROM sqlite_master WHERE type='table';
api_methods
sqlite> drop table api_methods;
sqlite> CREATE TABLE api_methods(
...>    id INTEGER PRIMARY KEY,
...>    action_name TEXT NOT NULL
...> );
Error: duplicate column name:   
sqlite>

Problem solved when I deleted the leading spaces before the column names:
sqlite> CREATE TABLE api_methods(
...> id INTEGER PRIMARY KEY,
...> action_name TEXT NOT NULL
...> );
sqlite> SELECT name FROM sqlite_master WHERE type='table';
api_methods
sqlite> pragma table_info(api_methods);
0|id|INTEGER|0||1
1|action_name|TEXT|1||0
sqlite>

Related

SQLite3: How to Import an CSV and change the column types?

I am looking to import an CSV using Command Line Shell For SQLite on linux (SQLite version 3.29.0), and set the appropriate data types.
sqlite> .open outputSQLDB.db
sqlite> .import input.csv tmpTable
But now the imported table is messed up:
sqlite> .schema
CREATE TABLE DX(
"id,field1,field2" TEXT
);
Why aren't the fields separated?
At the end do I just do:
sqlite> CREATE TABLE myTbl (
...> id INTEGER,
...> field1 TEXT,
...> field2 INTEGER
...> );
CREATE INDEX id_index on myTbl (id);
sqlite> DROP TABLE IF EXISTS tmpTable;
Specify .mode csv before inserting. Also make sure the temp table does not exist, otherwise SQLite interpretes the first line of the CSV as data.
Before dropping the temp table, transfer the rows to the new table with an INSERT INTO command. Otherwise they will be lost.
You will get a command sequence of:
.open outputSQLDB.db
DROP TABLE IF EXISTS tmpTable;
.mode csv
.import input.csv tmpTable
CREATE TABLE myTbl (
id INTEGER,
field1 TEXT,
field2 INTEGER
);
CREATE INDEX id_index on myTbl (id);
INSERT INTO myTbl (id, field1, field2)
SELECT id, field1, field2
FROM tmpTable;
DROP TABLE IF EXISTS tmpTable;
I would also either use
CREATE TABLE IF NOT EXISTS myTbl (
...
);
or
DROP TABLE IF EXISTS myTbl;
before creating the table.

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

how to get the ordered query in sqlite?

I insert some data into test table.
C:\> sqlite3 e:\\test.db
sqlite> create table test(code TEXT,content numeric);
sqlite> insert into test(code,content)values('x',3);
sqlite> insert into test(code,content)values('x',1.5);
sqlite> insert into test(code,content)values('x',1);
sqlite> insert into test(code,content)values('y',9);
sqlite> insert into test(code,content)values('y',3);
sqlite> insert into test(code,content)values('y',2);
sqlite> insert into test(code,content)values('y',12.3);
sqlite> insert into test(code,content)values('y',11.5);
how can i get the ordered output as the following ?
select * from test group by code order by content;can not get it.
select * from test order by content;neither.
x|1
x|1.5
x|3
y|2
y|3
y|9
y|11.5
y|12.3
You can sort by multiple criteria:
SELECT * FROM test ORDER BY code, content;

How to remove a row from a child table if it is removed from a parent one?

Here is a simple shema:
sqlite> .schema recordtypes
CREATE TABLE recordtypes (record_id text primary key);
sqlite> .schema headers
CREATE TABLE headers (header_id text primary key);
sqlite> .schema record_to_headers
CREATE TABLE record_to_headers (id INTEGER, recordid TEXT, headerid TEXT, FOREIGN KEY(recordid) REFERENCES recordtypes(record_id), FOREIGN KEY(headerid) REFERENCES headers(header_id));
Then I insert values into recordtypes and then in record_to_headers:
sqlite> insert into recordtypes values("test");
sqlite> insert into record_to_headers values (1, "test", "yeah");
Then I remove the "test" from recordtypes table expecting it is removed from record_to_headers table also but this never happens:
sqlite> delete from recordtypes where record_id = "test";
sqlite> select * from recordtypes;
sqlite> select * from record_to_headers;
1|test|yeah
I need behavior if I remove the value from recordtypes table it is also removed from record_to_header table. Please advice how to do so. Thanks a lot.
Not that much experience with SQLLite, but from the documentation I can see, that SQLLite supports foreign key cascading. That would delete the child row when parent row is deleted:
FOREIGN KEY(headerid) REFERENCES headers(header_id) ON DELETE CASCADE
You should consult the documentation to see whether you need to configure something beforehand in SQLLite.

SQLite Store strings that start with zero e.g. "001"

Which data type do I choose in SQLite to store a string such as "001" in the database.
I've tried using Text but when I go to type in the string 001, it drops the 00 and only puts a 1.
I've even tried using "blob" data type but still no luck. They all drop the zeros before the digit.
Works ok for me:
sqlite> create table sotest
...> (
...> col1 varchar(20)
...> );
sqlite>
sqlite> select * from sotest;
sqlite>
sqlite> insert into sotest values ('001');
sqlite> select * from sotest;
001
sqlite>
Maybe you weren't quoting your strings? For example:
sqlite> insert into sotest values ('001');
sqlite> select * from sotest;
001
sqlite> insert into sotest values (001);
sqlite> select * from sotest;
001
1
sqlite>
Column type should set to varchar, not string, if type is string zero will be dropped automatically.

Resources