I faced an issue with SQLite (version 3.7.13 if matters).
I created a new table with two columns foo and bar, data type is undefined. When I try to insert numbers, it works fine. When I insert text, "Error: no such column" happens.
sqlite> CREATE TABLE test (foo, bar);
sqlite> .tables
test
sqlite> insert into test values (0,1);
sqlite> select * from test;
0|1
sqlite> insert into test values (a,b);
Error: no such column: a
What am I doing wrong?
Thanks.
You need to quote strings
insert into test values('a', 'b')
Related
This seems odd to me and violates my previous experience with SQLite. I have a trivial database with one table and 3 columns. When I query the first column I get 'Error: no such column: Name'. The other columns work fine. Log below. There must be something ridiculously basic that I am missing. My sleazy work-around is to add a dummy first column, at which point querying on 'Name' works fine, but that is pretty unsatisfactory. Running on a Mac mini (M1, 2020), macOS Monterey Version 12.5.1.
bash-3.2$ head Names/nameTest1.csv
Name,Gender,Count
James,M,5304407
John,M,5260831
Robert,M,4970386
...
bash-3.2$ sqlite3 test1.db
SQLite version 3.19.3 2017-06-08 14:26:16
Enter ".help" for usage hints.
sqlite> .mode csv
sqlite> .separator ','
sqlite> .import Names/nameTest1.csv testtable1
sqlite> .schema
.schema
CREATE TABLE testtable1(
"Name" TEXT,
"Gender" TEXT,
"Count" TEXT
);
sqlite> select * from testtable1 where Count='5304407';
James,M,5304407
sqlite> select * from testtable1 where Name='James';
Error: no such column: Name
sqlite> .quit
.quit
Your CSV file has the BOM field. It does not correspond to a printable character, so you do not see it, but SQLite fails to strip it and includes it as the the prefix of your Name field. This is a known issue, but recent versions of SQLite should handle it properly. You might be using an older version. Either upgrade your SQLite or strip the BOM code before importing.
I'm connected to a SQLite database named db.sqlite3 on Windows. After running .tables command I know which tables I have, so I'm trying to show one of them with select * from table1, without seeing any output in Windows Terminal.
Why is this happening? Should I use some special command to print the query output in terminal?
I suspect your table has zero rows in it. Consider the following example in a blank database:
-- create a table
sqlite> create table "test"("field1" INTEGER);
-- select rows
sqlite> select * from test;
-- note: no output!
-- insert some values
sqlite> insert into test values(1),(2);
-- try the select again
sqlite> select * from test;
1
2
-- we have output!
-- to check if you have rows, do this:
sqlite> select count(*) from test;
2
-- 2 rows present
I have a database file with log data. The database contains a table LOG and the table contains a column MSG. There are 30 rows in the table, where the MSG column contains the string "down" at the end of the line:
$ sqlite3 log.db "select msg from log" | grep down$ | wc -l
30
But when I try to find them with LIKE, I get no match:
$ sqlite3 log.db "select msg from log where msg like '%down'" | grep down$ | wc -l
0
What could be the reason for this?
Update: MCVE
CREATE TABLE LOG (MSG VARCHAR(6291456) NOT NULL);
INSERT INTO LOG VALUES (X'666163696c6974793d6461656d6f6e3b636f6d706f6e656e743d6e616d65643b746578743d7368757474696e6720646f776e');
SELECT MSG FROM LOG; -- returns the row
SELECT MSG FROM LOG WHERE MSG LIKE '%down'; -- returns nothing
SELECT MSG FROM LOG WHERE MSG LIKE '%down%'; -- returns nothing
SELECT MSG FROM LOG WHERE CAST(MSG AS VARCHAR) LIKE '%down'; -- returns the row
I have no idea why a cast from VARCHAR to VARCHAR makes a difference.
Update: Another MCVE
CREATE TABLE LOG (MSG VARCHAR(6291456) NOT NULL);
INSERT INTO LOG VALUES (X'666163696c6974793d6461656d6f6e3b636f6d706f6e656e743d6e616d65643b746578743d7368757474696e6720646f776e');
INSERT INTO LOG VALUES ('facility=daemon;component=named;text=shutting down');
SELECT ROWID,MSG FROM LOG; -- returns both rows
SELECT ROWID,MSG FROM LOG WHERE MSG LIKE '%down'; -- returns just the second
SELECT ROWID,MSG FROM LOG WHERE MSG LIKE '%down%'; -- returns just the second
SELECT ROWID,MSG FROM LOG WHERE CAST(MSG AS VARCHAR) LIKE '%down'; -- returns both rows
SELECT HEX(MSG) FROM LOG;
Given your sample data and the results you're seeing on different versions of sqlite, here's what I'm sure is happening.
First, you're inserting blobs into your table, not strings. These blobs are stored unchanged, instead of being converted to strings the way numeric values are for a column with TEXT affinity like you're using. See the documentation for details about column affinity and implicit datatype conversions.
Second, the sqlite3 instance that's not matching those blobs was built with the SQLITE_LIKE_DOESNT_MATCH_BLOBS configuration option turned on, and the one that is matching them was built with it turned off (The default setting).
This compile-time option causes the LIKE operator to always return False if either operand is a BLOB. The default behavior of LIKE is that BLOB operands are cast to TEXT before the comparison is done.
If you check PRAGMA compile_options output you should be able to verify that it's being used.
I would paste this into the comments, but the formatting would look ugly. It works for me:
$ sqlite3 log.db
SQLite version 3.24.0 2018-06-04 14:10:15
Enter ".help" for usage hints.
sqlite> create table log (id int, msg text);
sqlite> insert into log values (1,'database is down');
sqlite> insert into log values (2,'database is down');
sqlite> insert into log values (3,'database is down');
sqlite> ^D
$ sqlite3 log.db "select msg from log" | grep down$ | wc -l
3
$ sqlite3 log.db "select msg from log where msg like '%down'" | grep down$ | wc -l
3
Can you share the contents of your log table, so I can try to reproduce your problem?
In an SQLite database, I created a table and imported CSV data into it.
The last column only contains integers:
ZIP;AMOUNT
78123;4272
95456;154
etc.
I used the following commands:
.mode csv
.separator ';'
CREATE TABLE MyTable("ZIP" TEXT, "AMOUNT" INTEGER);
.import input.csv MyTable
sqlite> select SUM(AMOUNT) from MyTable;
25270.0
Why is SQLite displaying SUM with a decimal?
Thank you.
===
Edit: Here's the infos:
sqlite> select typeof(AMOUNT) from MyTable LIMIT 10;
text
integer
integer
integer
integer
etc.
sqlite> select typeof(SUM(AMOUNT)) from MyTable;
real
==
Edit: Here's the top of input.csv as exported from LibreOffice Calc:
ZIP;AMOUNT
78123;4272
95456;154
etc.
Maybe I didn't use the right commands to import data into SQLite.
#PetSerAl has it. Because you're importing into an existing table, every line is imported including the header. That string makes sum() return a floating point result.
I work around this case with:
.import '| tail -n +2 input.csv' mytable
which strips the first line.
If the first character of the filename is a |, it's treated as a shell command to run (Using the C popen() function) and its output is used as the data to import.
I want to assure a column of my table in sqlite3 to be a text by CREATE TABLE directly from the command line, which has following form: ABCD-1234. The first part should consist of only characters, then comes a minus sign -, then comes the second part which should be INT. Is there anyway to do that?
I tried to create a table with following schema:
CREATE TABLE test(ID int check(typeof(ID) = 'integer'), Des text check(Des like '%-%'));
But it also accepts following unwanted records:
INSERT INTO test VALUES(1, 'abc-def');
INSERT INTO test VALUES(2, '123-456');