sd <
sha...@hotmail.com> wrote:
> Greetings All,
> I'm using SQLite with TCL and had problems inserting numbers with
> leading 0's into SQLite tables, such as:
> db eval {INSERT INTO tablename VALUES($v1,$v2)}
> if v1 or v2 looks like an octal (ie. 064530) it is unfortunately
> inserted into SQLite as 176022. A while back I read somewhere on this
> forum that somehow using @ instead of $ works:
I suspect you may be blaming the wrong spot. I'm not seeing this
behavior here:
$ rlwrap tclsh
% package require sqlite3
3.8.0
% db eval {create table int(a integer);}
invalid command name "db"
% sqlite3 db :memory
% exit
rellis@d820:~$ rm \:memory
rellis@d820:~$ rlwrap tclsh
% package require sqlite3
3.8.0
% sqlite3 db :memory
% db eval {create table int(a integer);}
% set x 064530
064530
% db eval {insert into int(a) values ($x);}
% db eval {select * from int;};
64530
The Tcl parser, however, does interpret leading zero decimal numbers as
octal. Therefore I suspect that what you have happening is somewhere
prior to your insert into Sqlite you have asking Tcl to interpret the
leading zero string as an integer value, and it is at that point where
the octal conversion is happening. note:
% set x 064530
064530
% expr {$x}
26968
% set x
064530
% set y [expr {$x + 1}]
26969
> It worked for me although I couldn't find any rationale behind it.
> Now I found out my variables are interpreted as octal in other parts
> of my script when using UPDATE and WHERE commands in SQLite:
...
> Anyone knows why @ works? Also, wouldn't it be a good idea to always
> use @ instead of "$" even if some variables will never have a leading
> 0? After all, in TCL everything's a string.
It is explained in the Sqlite docs:
https://www.sqlite.org/tclsqlite.html
To force a value to be inserted as a BLOB even if it also has a text
representation, us a "@" character to in place of the "$". Like this:
db1 eval {INSERT INTO t1 VALUES(5,@bigstring)}
If the variable does not have a bytearray representation, then "@"
works just like "$". Note that ":" works like "$" in all cases so the
following is another way to express the same statement:
By inserting as a "byte array" you'll _usually_ get the original 8-bit
ascii values you put in to the variable. I say _usually_ because if
you do something that causes the string you put in to be invalidated
(by updating the variable) and then regenerated, the string you get
back will be created from the alternate representation (integer, float,
etc.) and may no longer look like the original string that went in:
% set x ; # x contains just a string
064530
% incr x 0 ; # this invalidates the string representation
26968
% set x ; # this regenerates a new string rep, from the integer value
26968