SQLite User Forum

SQLite CLI usage
Login

SQLite CLI usage

(1.2) By Craig Maynard (craigm) on 2025-02-05 00:19:55 edited from 1.1 [link] [source]

According to the SQLite shell docs, sqlite3 accepts two optional parameters: FILENAME and SQL.

Usage: sqlite3 [OPTIONS] [FILENAME [SQL]]
FILENAME is the name of an SQLite database. A new database is 
created if the file does not previously exist. Defaults to :memory:.

The syntax of the SQL parameter is not documented. I tried the following compound command and it was rejected:

DELETE FROM artists; .import --skip 1 artists.csv artists

Error: in prepare, near ".": syntax error
.import --skip 1 artists.csv artists
^--- error here

Why doesn't this parse?

(2) By Richard Hipp (drh) on 2025-02-05 00:23:20 in reply to 1.2 [link] [source]

".import" is not an SQL command. It is a special command that is intercepted and interpreted by the CLI itself, not by SQLite. One of the parsing rules is that the "." at the beginning must be the first character on a new line.

(3.1) By Aask (AAsk1902) on 2025-02-05 12:07:55 edited from 3.0 in reply to 1.2 [link] [source]

If I understand your objective, namely:

  1. You have already created your database

  2. You have already created your table

  3. You want to refresh your table with the data that is in your CSV file - discarding what is already in your table.

If that is correct, you can achieve your objective as follows:

a. At the command prompt type this followed by enter:

sqlite3.exe <yourinputfile

where yourinputfile looks like this:

.open 'your database'
delete from [yourtable];
.import 'yourCSVSourceFile'  [yourTabeName] -csv -skip 1 
.exit

Note the prefix < before yourinputfilename: if you enclose yourinputfilename within quotes, < remains outside the quotes.

b. When the command completes, start the CLI, open your database & examine your table. Was it refreshed with the data in your source CSV file?

Notes:

i Ensure that you specify the fully qualified path for all files

ii Ensure that your CSV source corresponds with your table i.e. the number of columns match

iii Ensure that your CSV source does not have any blank lines

(4) By Kees Nuyt (knu) on 2025-02-05 16:47:45 in reply to 1.2 [link] [source]

Put every single command (that you would type as 1 line in the interactive SQLite CLI) between "".

Example:

sqlite3 -bail yourdb.sqlite "DELETE FROM artists" ".import --skip 1 artists.csv artists" "SELECT * FROM artists LIMIT 5"

For clarity, you can give every command its own line, using the continuation of your shell (e.g. bash), like this:

sqlite3 -bail yourdb.sqlite \
 "DELETE FROM artists" \
 ".import --skip 1 artists.csv artists" \
 "SELECT * FROM artists LIMIT 5"

Alternatively, use a socalled HEREDOC, like this:

sqlite3 -bail yourdb.sqlite <<EOSQL
DELETE FROM artists;
.import --skip 1 artists.csv artists
SELECT * FROM artists LIMIT 5;
EOSQL

Or put it all in a script that you feed to sqlite3 using shell redirection, like Aask showed.

(5) By Richard Hipp (drh) on 2025-02-05 19:06:47 in reply to 4 [source]

I had completely forgotten that you could give the CLI multiple commands as arguments after the database filename. That's a useful feature to know about. I've now added it to the documentation a brief explanation of how this works.

(8) By anonymous on 2025-02-20 14:04:56 in reply to 5 [link] [source]

This also affects the CLI help - could you adjust that one accordingly?

Please see https://sqlite.org/forum/forumpost/20e617feee83ae07 for details.

(9) By Stephan Beal (stephan) on 2025-02-20 14:07:14 in reply to 8 [link] [source]

This also affects the CLI help - could you adjust that one accordingly?

That's already done.

(10) By anonymous on 2025-02-20 16:33:11 in reply to 9 [link] [source]

Thank you :)

(6) By Craig Maynard (craigm) on 2025-02-05 22:25:42 in reply to 4 [link] [source]

Thanks! I discovered this useful feature independently by searching on GitHub for code examples. Here's my revised code from a Bash script:

printf -v CMD1 "DELETE FROM $TABLE"
printf -v CMD2 ".import --skip 1 $FILE $TABLE"
stdbuf -o0 sqlite3 -csv -header "$DB" "$CMD1" "$CMD2"; returncode=$?

(7) By Adrian Ho (lexfiend) on 2025-02-06 14:04:37 in reply to 6 [link] [source]

Shell arrays would probably work better and be more flexible in this regard:-

cmds=(
  "DELETE FROM $TABLE"
  ".import --skip 1 $FILE $TABLE"
)
stdbuf -o0 sqlite3 -csv -header "$DB" "${cmds[@]}"; returncode=$?