Introduction | Overview | Documentation | Summary | Sourceforge | Download |
ShellSQL - Commands
1 - Connection Commands.
1.1 - Introduction
These sets of commands establish a connection to the database. They all operate in a similar way in so far as much they initiate a background SQL client and output a handle that is used in subsequent ShellSQL commands to use it. For example....
HANDLE=`shpostgres dbname=test`
Note the backquotes there.
On success it returns 0. On an error they output nothing and effect a return code of 1. An error message may appear on the standard error output.
1.2 - shpostgres
This initiates a PostgreSQL connection. The syntax is....
shpostgres connectarg [connectarg] ...
The connectarg(s) are concatonated together separated by spaces. So for example, the following is perfectlly legal....
shpostgres dbname=test user=myuser
which does the same thing as
shpostgres "dbname=test user=myuser"
Either way, the arguments of the engne take the form of name=value
where name
is one of the following. The are the same as the ones used
in PQconnectdb()
in PostgreSQL's libpq library. Most have sensible defaults.
host |
The host name of the server |
hostaddr |
The host IP address of the server |
port |
The TCP port number to connect to on the server |
dbname |
The database name |
user |
The user name for the connection |
password |
The password for the user |
connect_tomeout |
The connection timeout in seconds, 0 is indefinate |
options |
Command line options to be sent to the server. See Postgres documentation for more details. |
sslmode |
the SSL mode for the connection, This is either disable , allow , prefer or require . |
service |
Name of service that holds extra parameters. See Postgres documentation for more details. |
If you are using the password assignment in the connection then you should use the "password=mysecret" string as a separate parameter. The reason for this is that "shpostgres" will detect it and blank it out in the process table so someone else doing a "ps" cannot see it.
1.3 - shmysql
This initiates a MySQL connection. The syntax is....
shmysql connectarg [connectarg] ...
The connectarg(s) are concatonated together separated by spaces. So for example, the following is perfectlly legal....
shmysql dbname=test user=myuser
which does the same thing as
shmysql "dbname=test user=myuser"
Either way, the arguments of the engne take the form of name=value
where name
is one of the following. Most have sensible defaults.
host |
The host name or IP address of the server |
port |
The TCP port number to connect to on the server |
dbname |
The database name |
user |
The user name for the connection |
password |
The password for the user |
socket |
The name of the UNIX socket if applicable |
flag |
Usually not defined or zero, but can be used in special circumstances, see the documentation in MySQL for further information. |
If you are using the password assignment in the connection then you should use the "password=mysecret" string as a separate parameter. The reason for this is that "shpostgres" will detect it and blank it out in the process table so someone else doing a "ps" cannot see it.
1.4 - shsqlite3
This initiates a SQLITE3 connection. The syntax is
shsqlite3 databasefilename
Where databasefilename is the name of the SQLITE3 database to open.
1.5 - shsqlite
This initiates a SQLITE version 2 connection. The syntax is
shsqlite databasefilename
Where databasefilename is the name of the SQLITE version 2 database to open.
1.6 - shodbc
This initiates an ODBC connection. The syntax is
shodbc user password connectionstriing
where the user and password (which need to be there own parameters, NOT incorporated in the connection string) are just that, and the connection string is a (number of) parameters that constitute the connection string.
There is another parameter that can be passed using the environment variable ODBC_TIMEOUT, which contains the login timeout in seconds. This defaults to 20 if not defined.
1.7 - shfreetds
This initiates a FreeTDS connection, which can be used to connect to MS-SQL and SyBase (amongst others). The syntax is....
shfreetds connectarg [connectarg] ...
The connectarg(s) are concatonated together separated by spaces. So for example, the following is perfectlly legal....
shfreetds server=test dbname=test user=myuser
which does the same thing as
shfreetds "server=test dbname=test user=myuser"
Either way, the arguments of the engne take the form of name=value where name is one of the following. Most have sensible defaults.
server |
The server name (as in the freetds.conf file) - required. |
port |
The TCP port number to connect to on the server |
dbname |
The database name |
user |
The user name for the connection |
password |
The password for the user |
appname |
The application name used for the connection |
host |
The host name or IP address of the server |
If you are using the password assignment in the connection then you should use the "password=mysecret" string as a separate parameter. The reason for this is that "shfreetds" will detect it and blank it out in the process table so someone else doing a "ps" cannot see it.
To use this it is important that you have read the FreeTDS implementation documentation, especially in creating the "freetds.conf" file correctly. Also, at time of writing, freetds's "ct" library interface has a bug in it and should be corrected and recompiled. This is documented in the "README.freetds" file.
1.8 - shsqlstart
This is a generic connection routine. This looks at the environment variable "SHSQL", and expects it to be "postgres", "sqlite3" or any of the other engines then starts the respective program with the appropriate parameters. If it is not recognizeable it starts using "shpostgres".
An example of this working.....
SHPROG=postgres export SHPROG HANDLE=`shsqlstart dbname=test`
and so on.
shsqlstart is a small wrapper program. It expects the appropriate connection program to be in the same directory as it ("shsqlstart"). This is the reccomended way of starting "shsql" connection as the "SHSQL" environment variables can be used in other utilities.
2 - Execution command
2.1 - shsql
The command shsql performs the actual SQL queries. As it's first parameter it takes the handle obtained from the connection routine above. Subsequent parameters represent the query itself. So an example here is....
shsql $HANDLE "insert into a (b, c) values ('x', 'y')"
Alternatively the SQL parameter can be split. shsql concatonates them together separating them with a space....
shsql $HANDLE "insert into a (b, c)" \ "values ('x', 'y')"
Should the query generate rows, then each row is represented by a value inclosed by double quotes, each field on the row being separated with a space, and each row separated by a new line character.
Therefore, the following query....
shsql $HANDLE "select keyfield, datafield from mydata"
could print on the standard output something like
"FRED" "FRED BLOGS" "DAVID" "DAVID COPERFIELD" "JOAN" "JOAN BLOGS"
Should one of the fields contain a double quote character then that is replaced by 2 double quote characters together.
However - a means to alter the output is to place an optional format parameter after the handle, this is one of the following:
--csv = Comma Separated Variable output --colon = Colon(: character) delimeted output - not quoted --pipe = Pipe (| character) delimited output - not quoted --tab = Tab delimited output - not quoted --shell = Shell (the default, desribed above) output
For example...
shsql $HANDLE --csv "select keyfield, datafield from mydata"
would produce..
"FRED","FRED BLOGS" "DAVID","DAVID COPERFIELD" "JOAN","JOAN BLOGS"
or
shsql $HANDLE --pipe "select keyfield, datafield from mydata"would produce
FRED|FRED BLOGS DAVID|DAVID COPERFIELD JOAN|JOAN BLOGS
If no parameters (apart from the HANDLE) are provided then shsql
takes the standar input as the SQL command:
echo "insert into a (b, c) values('x', 'y')" | shsql $HANDLE
2.2 - Caveats
At time of writing no more than one "shsql" command can be actime on the same handle (or connection) at any one time. Should transaction processing be required you should save the output of the query to a file...
shsql $HANDLE "select keyfield, datafield from mydata" > tempfile # Now for the transaction processing.... cat tempfile ( while ROW=`shsqlline` do eval set $ROW shsql $HANDLE "update stats" \ "set totallen = totallen + length('$2')"\ "where initialkey = substr('$1', 1, 1)" done )
or something like that.
Another caveat is that shsql does not really handle binary fields. Should this be required then you should escape them in the SQL itself.
2.3 - The shsqlinp command
This command would primarily be used to import data into a table, though it can be used for other updates as well. Primarily what it does is execute (the same) SQL statement for every line of standard input it receives performing a rudimentary parameter substitution. An example of thos could be....
shsqlinp $HANDLE "insert into mydata (keyfield, datafield)" \ "values (?, ?)" \ << _EOF "JAMES" "JAMES BOND 007" "MARY" "MARY QUEEN OF SCOTTS" _EOF
or even
shsqlinp $HANDLE "insert into xxx (yyy, zzz) values(?, ?)" < file.txt
Also, perhaps an output from a shsql from another database....
shsql $HANDLE_A "select a, b from cc" | \ shsqlinp $HANDLE_B "insert into cc(a, b) values(?, ?)"
However - please note that you cannot use this method to copy data from one table to another, or to perform other updates, in the same database connection. The "client back end" can only execute one statement at a time, so in order to use ShellSQL to update a table based on another you need to go through a temporary file...
shsql $HANDLE "select a, b from cc" > temp.txt shsqlinp $HANDLE "insert into cc(a, b) values(?, ?)" < temp.txt
The above will work for string, or varchar, type datatypes. If a number is to be included then either casting needs to be done in the SQL command itself, or you can append a "#" to the "?"parameter. To specify a string you can apend a "@" character, however, this is not neccessary as this is the default.
shsqlinp $HANDLE "insert into aa (numf, charf) values (?#, ?@)" << _EOF "123" "ORDER ONE-TWO-THREE" "-2" "MINUS TWO" _EOF
This need not be just used for importing, but can be used for updating, deleting or other DML type operations..
shsqlinp $HANDLE "update atable set bfield = ? where ckey = ?" << _EOF "NEW DATA FOR A" "KEYA" "NEW DATA FOR B" "KEYB" _EOF
The format of the input file can be controlled by an optional parameter after the HANDLE. These are the same for those in shsql....
--csv = Comma Separated Variable output --colon = Colon(: character) delimeted output - not quoted --pipe = Pipe (| character) delimited output - not quoted --tab = Tab delimited output - not quoted --shell = Shell (the default, desribed above) output
3 - shsqlend
This simply terminates the connection and background process...
shsqlend $HANDLE
It is important that the handle/connection is not accessed after this is called.
It is important to call this however, should you do not then processes
and message queues will remain running in the background. Should this
happen then these processes can be killed using the LINUX/UNIX kill
,
or the LINUX killall
command. Though if this is done then
the -9
option should not be used.
4 - Sundry Utilities
4.1 - Introduction
Some utilities accompany the suite to assist with the shell scripts, these do not connect to the SQL client background process in the same way as the above but they are designed to work with the suite.
4.2 - shsqlline
First the technological description - this is complicated so please feel free to ignore it and go straight to the example below...
This takes a rowset as produced by a select query using "shsql" as a standard input, and prints out the first row of this returning 0. If the end of file is reached then it fails by returning 1.
Example:
shsql $HANDLE "select * from mytable" > tempfile cat tempfile | ( while ROW=`shsqlline` do eval set $ROW .... done ) rm tempfile
This can be shoertened to...
shsql $HANDLE "select * from mytable" | ( while ROW=`shsqlline` do eval set $ROW .... done )
To go through it line by line.....
shsql $HANDLE "select * from mytable" | (
This runs sgsql then pipes the rowset (standartd output) to a sub-shell which...
while ROW=`shsqlline` do
goes into a loop that reads the first then next line of the rowset and placing it into a variable called ROW, the loop then...
eval set $ROW
places the first field in $1, second in $2 and so on. The "eval" appears to be needed to properly evaluate the double quotes and spaces in variables.
If you have not fully uderstood this it is unimportant as long as you know how to enumerate the row set.
Please not too, that if you wish to perform other transactions on the same $HANDLE in the loop you need to use the "tempfile" method.
4.3 - shsqlesc
This takes as it's parameter(s) and prints on the standard output a string that has the quotes etc escaped suitable for string parameters in SQL queries. Please note it places the preceding and postceding 's on the string too. Bear in mind that different SQL engines use different escape routines so this uses the SHSQL parameter to control precisely how it behaves (defaulting to postgres). Example:
SQLPAR=`shsqlesc "Bobby's Girl"`
would place the value
'Bobb''s Girl'
including all the quotes into SQLPAR.
The behaviour of this command is effected by the SHSQL
environment variable. Different engines have slightly different
escape rules, and shsqlesc
will alter the way
it behaves accordingly, so SHSQL
should be set
accordingly (as in the shsqlstart
program). If
it is not it defaults to postgres
.