SQLite Tutorial: Common Commands and Triggers

Taken from: http://linuxgazette.net/109/chirico1.html

This article explores common methods in SQLite such as running commands from the shell prompt and creating triggers for populating time stamped fields with either UTC or local time values. In addition, delete, update, and insert trigger examples will be explored in detail.

All examples can be found in sqlite_examples.tar.gz (local copy), and I would encourage you to download and run these examples as you read through this document.

The home page for sqlite3 is www.sqlite.org and the source for sqlite3 can be downloaded at www.sqlite.org/download.htm. This tutorial was done with the source version 3.0.8

Getting Started - Common Commands

To create a database file, run the command "sqlite3" followed by the database name. For example, to create the database "test.db" run the sqlite3 command as follows:

     $ sqlite3 test.db

SQLite version 3.0.8
Enter ".help" for instructions
sqlite> .quit
$

The database file test.db will be created, if it does not already exist. Running this command will leave you in the sqlite3 environment. There are 3 ways to safely exit this environment (.q, .quit, or .exit).

You do not have to enter the sqlite3 interactive environment. Instead, you could perform all commands at the shell prompt, which is ideal when running bash scripts and commands in an ssh string. Below is an example of how you would create a simple table from the command prompt.

     $ sqlite3 test.db  "create table t1 (t1key INTEGER

PRIMARY KEY,data TEXT,num double,timeEnter DATE);"

After table t1 has been created, data can be inserted as follows:

    $ sqlite3 test.db  "insert into t1 (data,num)

values ('This is sample data',3);"
$ sqlite3 test.db "insert into t1 (data,num)
values ('More sample data',6);"
$ sqlite3 test.db "insert into t1 (data,num)
values ('And a little more',9);"

As expected, doing a select returns the data in the table. Note, the primary key "t1key" auto increments; however, there are no default values for timeEnter. To populate the timeEnter field with the time, an update trigger is needed. An important note on the PRIMARY KEY: do not use the abbreviated "INT" when working with the PRIMARY KEY. You must use "INTEGER", for the primary key to update.

    $ sqlite3 test.db  "select * from t1 limit 2";

1|This is sample data|3|
2|More sample data|6|

In the statement above, the limit clause is used and only 2 rows are displayed. For a quick reference of SQL syntax statements available with SQLite, see the link syntax. There is an offset option to the limit clause. For instance, the third row is equal to the following: "limit 1 offset 2".

    $ sqlite3 test.db "select * from t1

order by t1key limit 1 offset 2";
3|And a little more|9|

The ".table" command shows the table names. For a more comprehensive list of tables, triggers, and indexes created in the database, query the master table "sqlite_master" as shown below.

    $ sqlite3 test.db ".table"

t1

$ sqlite3 test.db "select * from sqlite_master"
table|t1|t1|2|CREATE TABLE t1 (t1key INTEGER
PRIMARY KEY,data TEXT,num double,timeEnter DATE)

All SQL information and data inserted into a database can be extracted with the ".dump" command.

     $ sqlite3 test.db ".dump"

BEGIN TRANSACTION;
CREATE TABLE t1 (t1key INTEGER
PRIMARY KEY,data TEXT,num double,timeEnter DATE);
INSERT INTO "t1" VALUES(1, 'This is sample data', 3, NULL);
INSERT INTO "t1" VALUES(2, 'More sample data', 6, NULL);
INSERT INTO "t1" VALUES(3, 'And a little more', 9, NULL);
COMMIT;

The contents of the ".dump" can be filtered and piped to another database. Below table t1 is changed to t2 with the sed command, and it is piped into the test2.db database.

      $ sqlite3 test.db ".dump"|sed -e s/t1/t2/|sqlite3 test2.db

Triggers

An insert trigger is created below in the file "trigger1". The Coordinated Universal Time (UTC) will be entered into the field "timeEnter", and this trigger will fire after a row has been inserted into the table t1. Again, this trigger will fire after the row has been inserted.

 -- ********************************************************************

-- Creating a trigger for timeEnter
-- Run as follows:
-- $ sqlite3 test.db < timeenter =" DATETIME('NOW')" rowid =" new.rowid;">

The AFTER specification in ..."insert_t1_timeEnter AFTER..." is necessary. Without the AFTER keyword, the rowid would not have been generated. This is a common source of errors with triggers, since AFTER is NOT the default, so it must be specified. In summary, if your trigger depends on newly created data, in any of the fields from the created row, which was the case for us in this example since we need the rowid, then, the AFTER specification is needed. Otherwise, the trigger is a BEFORE trigger, and will fire before rowid or other pertinent data is entered into the field.

Comments are preceded by "--". If this script was created in the file "trigger1", you could easily execute this script as follows.

     $ sqlite3 test.db <>  

Now try entering a new record as before, and you should see the time in the field timeEnter.

     sqlite3 test.db  "insert into t1 (data,num) values ('First entry with timeEnter',19);"

Doing a select reveals the following data:

     $ sqlite3 test.db "select * from t1";

1|This is sample data|3|
2|More sample data|6|
3|And a little more|9|
4|First entry with timeEnter|19|2004-10-02 15:12:19

If you look at the statement above, the last value has the timeEnter filled in automatically with Coordinated Universal Time - or (UTC). If you want local time, then, use select datetime('now','localtime'). See the note at the end of this section regarding UTC and local time.

For examples that follow the table "exam" and the database "examScript" will be used. The table and trigger are defined below. Just like the trigger above, UTC time will be used.

     -- *******************************************************************

-- examScript: Script for creating exam table
-- Usage:
-- $ sqlite3 examdatabase < timeenter =" DATETIME('NOW')" rowid =" new.rowid;">

After the script file, it can be executed, by redirecting the contents of the script file into the sqlite3 command, followed by the database name. See the example below:

     $ sqlite3 examdatabase <>  

And, as a check, the PRIMARY KEY and current UTC time have been updated correctly, as seen from the above example.

Logging All Inserts, Updates, and Deletes

The script below creates the table examlog and three triggers update_examlog, insert_examlog, and delete_examlog to record update, inserts, and deletes made to the exam table. In other words, anytime a change is made to the exam table, the changes will be recorded in the examlog table, including the old value and the new value. By the way if you are familiar with MySQL, the functionality of this log table is similar to MySQL's binlog. See (TIP 2, TIP 24 and TIP 25) if you would like more information on MySQL's log file.

     -- *******************************************************************

-- examLog: Script for creating log table and related triggers
-- Usage:
-- $ sqlite3 examdatabase <>

Since the script above has been created in the file examLOG, you can execute the commands in sqlite3 as shown below. Also shown below is a record insert, and an update to test these newly created triggers.

     $ sqlite3 examdatabase < score="82" ln="'Anderson'" fn="'Bob'" exam="2">  

Now, by doing the select statement below, you will see that examlog contains an entry for the insert statement, plus two updates. Although we only did one update on the command line, the trigger "insert_exam_timeEnter" performed an update for the field timeEnter -- this was the trigger defined in "examScript". On the second update we can see that the score has been changed. The trigger is working. Any change made to the table, whether by user interaction or another trigger is recorded in the examlog.

  $ sqlite3 examdatabase "select * from examlog"


1|2||Bob||Anderson||2||80||INSERT|||2004-10-02 15:33:16
2|2|2|Bob|Bob|Anderson|Anderson|2|2|80|80|UPDATE||2004-10-02 15:33:16|2004-10-02 15:33:16
3|2|2|Bob|Bob|Anderson|Anderson|2|2|82|80|UPDATE|2004-10-02 15:33:16|2004-10-02 15:33:26|2004-10-02 15:33:26

Again, pay particular attention to the AFTER keyword. Remember by default triggers are BEFORE, so you must specify AFTER to insure that all new values will be available, if your trigger needs to work with any new values.

UTC and Local time

Note, select DATETIME('NOW') returns UTC or Coordinated Universal Time. But select datetime('now','localtime') returns the current time.

     sqlite> select datetime('now');

2004-10-18 23:32:34

sqlite> select datetime('now','localtime');
2004-10-18 19:32:46

There is an advantage to inserting UTC time like we did with the triggers above, since UTC can easily be converted to local time after UTC has been entered in the table. See the command below. By inserting UTC, you avoid problems when working with multiple databases that may not share the same time zone and or daylight savings time settings. By starting with UTC, you can always obtain the local time.
(Reference: Working with Time)

     CONVERTING TO LOCAL TIME:


sqlite> select datetime(timeEnter,'localtime') from exam;

Other Date and Time Commands

If you look in the sqlite3 source file "./src/date.c", you will see that datetime takes other options. For example, to get the local time, plus 3.5 seconds, plus 10 minutes, you would execute the following command:

     sqlite> select datetime('now','localtime','+3.5 seconds','+10 minutes');

2004-11-07 15:42:26

It is also possible to get the weekday where 0 = Sunday, 1 = Monday, 2 = Tuesday ... 6 = Saturday.

       sqlite> select datetime('now','localtime','+3.5 seconds','weekday 2');

2004-11-09 15:36:51

The complete list of options, or modifiers as they are called in this file, are as follows:

       NNN days

NNN hours
NNN minutes
NNN.NNNN seconds
NNN months
NNN years
start of month
start of year
start of week
start of day
weekday N
unixepoch
localtime
utc

In addition, there is the "strftime" function, which will take a time string, and convert it to the specified format, with the modifications. Here is the format for this function:

     **    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)

**
** Return a string described by FORMAT. Conversions as follows:
**
** %d day of month
** %f ** fractional seconds SS.SSS
** %H hour 00-24
** %j day of year 000-366
** %J ** Julian day number
** %m month 01-12
** %M minute 00-59
** %s seconds since 1970-01-01
** %S seconds 00-59
** %w day of week 0-6 sunday==0
** %W week of year 00-53
** %Y year 0000-9999

Below is an example.

     sqlite> select strftime("%m-%d-%Y %H:%M:%S %s %w %W",'now','localtime');

11-07-2004 16:23:15 1099844595 0 44

Simple Everyday Application

Keeping Notes in a Database

This simple bash script (part of the sqlite_examples tarball) allows you to take notes. The notes consist of a line of text followed by an optional category without the additional typing.

 "sqlite3  ",

Instead, it is a simple one letter command.

     $ n 'Take a look at sqlite3 transactions -

http://www.sqlite.org/lang.html#transaction' 'sqlite3'

The above statement enters the text into a notes table under the category 'sqlite3'. Anytime a second field appears, it is considered the category. To extract records for the day, I enter "n -l", which is similar to "ls -l", to "note list".

With just "n" help is listed on all the commands.

     $ n

This command is used to list notes in
a database.

n
-l list all notes
-t list notes for today
-c list categories
-f search for text
-e execute command and add to notes
-d delete last entry

Bash Cheat Sheet

Common SSH Commands or Linux Shell Commands:

Taken from: www.sshhelp.com

alias: Create an alias
apropos: Search Help manual pages (man -k)
awk: Find and Replace text, database sort/validate/index
break: Exit from a loop
builtin: Run a shell builtin
bzip2: Compress or decompress named file(s)

cal: Display a calendar
case: Conditionally perform a command
cat: Display the contents of a file
cd: Change Directory
cfdisk: Partition table manipulator for Linux
chgrp: Change group ownership
chmod: Change access permissions
chown: Change file owner and group
chroot: Run a command with a different root directory
cksum: Print CRC checksum and byte counts
clear: Clear terminal screen
cmp: Compare two files
comm: Compare two sorted files line by line
command Run a command: - ignoring shell functions
continue: Resume the next iteration of a loop
cp: Copy one or more files to another location
cron: Daemon to execute scheduled commands
crontab: Schedule a command to run at a later time
csplit: Split a file into context-determined pieces
cut: Divide a file into several parts

date: Display or change the date & time
dc: Desk Calculator
dd: Data Dump - Convert and copy a file
declare: Declare variables and give them attributes
df: Display free disk space
diff: Display the differences between two files
diff3: Show differences among three files
dig: DNS lookup
dir: Briefly list directory contents
dircolors: Colour setup for `ls’
dirname: Convert a full pathname to just a path
dirs: Display list of remembered directories
du: Estimate file space usage

echo: Display message on screen
egrep: Search file(s) for lines that match an extended expression
eject: Eject removable media
enable: Enable and disable builtin shell commands
env: Environment variables
ethtool: Ethernet card settings
eval Evaluate several commands/arguments
exec: Execute a command
exit: Exit the shell
expand: Convert tabs to spaces
export: Set an environment variable
expr: Evaluate expressions

false: Do nothing, unsuccessfully
fdformat Low:-level format a floppy disk
fdisk: Partition table manipulator for Linux
fgrep: Search file(s) for lines that match a fixed string
file: Determine file type
find: Search for files that meet a desired criteria
fmt: Reformat paragraph text
fold: Wrap text to fit a specified width.
for: Expand words, and execute commands
format: Format disks or tapes
free: Display memory usage
fsck: File system consistency check and repair
ftp: File Transfer Protocol
function: Define Function Macros

gawk: Find and Replace text within file(s)
getopts: Parse positional parameters
grep: Search file(s) for lines that match a given pattern
groups: Print group names a user is in
gzip: Compress or decompress named file(s)

hash: Remember the full pathname of a name argument
head: Output the first part of file(s)
history: Command History
hostname: Print or set system name

id: Print user and group id’s
if: Conditionally perform a command
ifconfig: Configure a network interface
import: Capture an X server screen and save the image to file
install: Copy files and set attributes

join: Join lines on a common field

kill : Stop a process from running

less: Display output one screen at a time
let: Perform arithmetic on shell variables
ln: Make links between files
local: Create variables
locate: Find files
logname: Print current login name
logout: Exit a login shell
look: Display lines beginning with a given string
lpc: Line printer control program
lpr: Off line print
lprint: Print a file
lprintd: Abort a print job
lprintq: List the print queue
lprm: Remove jobs from the print queue
ls: List information about file(s)
lsof : List open files

make: Recompile a group of programs
man: Help manual
mkdir: Create new folder(s)
mkfifo: Make FIFOs (named pipes)
mkisofs: Create an hybrid ISO9660/JOLIET/HFS filesystem
mknod: Make block or character special files
more: Display output one screen at a time
mount: Mount a file system
mtools: Manipulate MS-DOS files
mv: Move or rename files or directories

netstat: Networking information
nice: Set the priority of a command or job
nl: Number lines and write files
nohup: Run a command immune to hangups
nslookup: Query Internet name servers interactively

passwd: Modify a user password
paste: Merge lines of files
pathchk: Check file name portability
ping: Test a network connection
popd: Restore the previous value of the current directory
pr: Prepare files for printing
printcap: Printer capability database
printenv: Print environment variables
printf: Format and print data
ps: Process status
pushd: Save and then change the current directory
pwd: Print Working Directory

quota: Display disk usage and limits
quotacheck: Scan a file system for disk usage
quotactl: Set disk quotas

ram: ram disk device
rcp: Copy files between two machines.
read : read a line from standard input
readonly: Mark variables/functions as readonly
remsync: Synchronize remote files via email
return: Exit a shell function
rm: Remove files
rmdir: Remove folder(s)
rsync: Remote file copy (Synchronize file trees)

screen: Terminal window manager
scp: Secure copy (remote file copy)
sdiff : Merge two files interactively
sed: Stream Editor
select: Accept keyboard input
seq : Print numeric sequences
set : Manipulate shell variables and functions
sftp: Secure File Transfer Program
shift: Shift positional parameters
shopt: Shell Options
shutdown: Shutdown or restart linux
sleep: Delay for a specified time
sort: Sort text files
source: Run commands from a file `.’
split: Split a file into fixed-size pieces
ssh: Secure Shell client (remote login program)
strace: Trace system calls and signals
su : Substitute user identity
sum: Print a checksum for a file
symlink: Make a new name for a file
sync: Synchronize data on disk with memory

tail : Output the last part of files
tar: Tape ARchiver
tee : Redirect output to multiple files
test: Evaluate a conditional expression
time: Measure Program running time
times : User and system times
touch: Change file timestamps
top: List processes running on the system
traceroute: Trace Route to Host
trap: Run a command when a signal is set(bourne)
tr: Translate, squeeze, and/or delete characters
true: Do nothing, successfully
tsort: Topological sort
tty: Print filename of terminal on stdin
type: Describe a command

ulimit: Limit user resources
umask: Users file creation mask
umount: Unmount a device
unalias: Remove an alias
uname: Print system information
unexpand: Convert spaces to tabs
uniq: Uniquify files
units: Convert units from one scale to another
unset: Remove variable or function names
unshar: Unpack shell archive scripts
until: Execute commands (until error)
useradd: Create new user account
usermod: Modify user account
users: List users currently logged in
uuencode: Encode a binary file
uudecode: Decode a file created by uuencode

v : Verbosely list directory contents (`ls -l -b’)
vdir: Verbosely list directory contents (`ls -l -b’)
vi: Text Editor

watch : Execute/display a program periodically
wc : Print byte, word, and line counts
whereis: Report all known instances of a command
which: Locate a program file in the user’s path.
while: Execute commands
who: Print all usernames currently logged in
whoami : Print the current user id and name (`id -un’)
Wget: Retrieve web pages or files via HTTP, HTTPS or FTP

xargs: Execute utility, passing constructed argument list(s)
yes: Print a string until interrupted

.period: Run commands from a file
###: Comment / Remark

ls : list files/directories in a directory, comparable to dir in windows/dos.
ls -al : shows all files (including ones that start with a period), directories, and details
attributes for each file.

cd : change directory · · cd /usr/local/apache : go to /usr/local/apache/ directory
cd ~ : go to your home directory
cd - : go to the last directory you were in
cd .. : go up a directory cat : print file contents to the screenv

cat filename.txt : cat the contents of filename.txt to your screen

tail : like cat, but only reads the end of the file
tail /var/log/messages : see the last 20 (by default) lines of /var/log/messages
tail -f /var/log/messages : watch the file continuously, while it’s being updated
tail -200 /var/log/messages : print the last 200 lines of the file to the screen

more : like cat, but opens the file one screen at a time rather than all at once
more /etc/userdomains : browse through the userdomains file. hit to go to the next
page, to quit

pico : friendly, easy to use file editor
pico /home/burst/public_html/index.html : edit the index page for the user’s website.

vi : another editor, tons of features, harder to use at first than pico
vi /home/burst/public_html/index.html : edit the index page for the user’s website.

grep : looks for patterns in files
grep root /etc/passwd : shows all matches of root in /etc/passwd
grep -v root /etc/passwd : shows all lines that do not match root
touch : create an empty file
touch /home/burst/public_html/404.html : create an empty file called 404.html in the directory /home/burst/public_html/

ln : create’s “links” between files and directories
ln -s /usr/local/apache/conf/httpd.conf /etc/httpd.conf : Now you can edit
/etc/httpd.conf rather than the original. changes will affect the orginal, however
you can delete the link and it will not delete the original.

rm : delete a file
rm filename.txt : deletes filename.txt, will more than likely ask if you really want to
delete it rm -f filename.txt : deletes filename.txt, will not ask for confirmation before deleting.
rm -rf tmp/ : recursively deletes the directory tmp, and all files in it, including
subdirectories. BE VERY CAREFULL WITH THIS COMMAND!!!

last : shows who logged in and when
last -20 : shows only the last 20 logins
last -20 -a : shows last 20 logins, with the hostname in the last field

w : shows who is currently logged in and where they are logged in from.

netstat : shows all current network connections.
netstat -an : shows all connections to the server, the source and destination ips and
ports.
netstat -rn : shows routing table for all ips bound to the server.

top : shows live system processes in a nice table, memory information, uptime and
other useful info. This is excellent for managing your system processes,
resources and ensure everything is working fine and your server isn’t bogged
down. top then type Shift + M to sort by memory usage or Shift + P to sort by CPU usage

ps: ps is short for process status, which is similar to the top command. It’s used to
show currently running processes and their PID.
A process ID is a unique number that identifies a process, with that you can kill or
terminate a running program on your server (see kill command).
ps U username : shows processes for a certain user
ps aux : shows all system processes
ps aux –forest : shows all system processes like the above but organizes in a
hierarchy that’s very useful!v

file : attempts to guess what type of file a file is by looking at it’s content.
file * : prints out a list of all files/directories in a directory

du : shows disk usage.
du -sh : shows a summary, in human-readble form, of total disk space used in the
current directory, including subdirectories.
du -sh * : same thing, but for each file and directory. helpful when finding large files
taking up space.

wc : word count
wc -l filename.txt : tells how many lines are in filename.txt

cp : copy a file
cp filename filename.backup : copies filename to filename.backup
cp -a /home/burst/new_design/* /home/burst/public_html/ : copies all files, retaining
permissions form one directory to another.

kill: terminate a system process
kill -9 PID EG: kill -9 431
kill PID EG: kill 10550
Use top or ps ux to get system PIDs (Process IDs)

EG:
PID TTY TIME COMMAND
10550 pts/3 0:01 /bin/csh

10574 pts/4 0:02 /bin/csh

10590 pts/4 0:09 APP

Each line represents one process, with a process being loosely defined as a running instance of a program. The column headed PID (process ID) shows the assigned process numbers of the processes. The heading COMMAND shows the location of the executed process.

Putting commands together:

Often you will find you need to use different commands on the same line. Here are
some examples. Note that the | character is called a pipe, it takes date from
one program and pipes it to another.
> means create a new file, overwriting any content already there.
>> means tp append data to a file, creating a newone if it doesn not already exist.
<>