Hi Daniele,


Daniele Nicolucci (Jollino) wrote:

Hello,
I'm using sqlite 3.0.7 on OS X and I'm having a hard time using the .import function to import data which includes NULL values.
I made a test database to describe the problem.


This is the schema of the table:

sqlite> .schema
CREATE TABLE quest (id integer primary key default null, sesso, eta, dom1, dom2, dom3, dom4);


As you can see it's pretty basic, the only notable thing is the auto-incremental "id" field.
The "quest" table already has some data, and inserting new records using SQL works just fine:


sqlite> select * from quest;
1|m|40|a|b|a|c
2|m|40|a|b|a|c
sqlite> insert into quest values(null,'f',25,'a','b','c','d');
sqlite> insert into quest(sesso,eta,dom1,dom2,dom3,dom4) values('f', 32, 'c', 'd', 'a', 'a');
sqlite> select * from quest;
1|m|40|a|b|a|c
2|m|40|a|b|a|c
3|f|25|a|b|c|d
4|f|32|c|d|a|a



The problem arises when using .import. I have a hand-made CSV file, and it looks like this:


innocence:~/Temp jollino$ cat valori.csv
null,f,35,c,d,a,a
null,f,48,a,b,c,d
null,m,22,b,c,d,a

but sqlite doesn't like it:

sqlite> .import valori.csv quest
Error: datatype mismatch


I tried removing "null" from, therefore having a literally null field, and it still doesn't work:


innocence:~/Temp jollino$ cat valori.csv
,f,35,c,d,a,a
,f,48,a,b,c,d
,m,22,b,c,d,a

sqlite> .import valori.csv quest
Error: datatype mismatch


I even tried using a 0 for that field, but of course it complains:

innocence:~/Temp jollino$ cat valori.csv
0,f,35,c,d,a,a
0,f,48,a,b,c,d
0,m,22,b,c,d,a

sqlite> .import valori.csv quest
Error: PRIMARY KEY must be unique


And I tried removing the field altogether, to no avail:

innocence:~/Temp jollino$ cat valori.csv
f,35,c,d,a,a
f,48,a,b,c,d
m,22,b,c,d,a

sqlite> .import valori.csv quest
valori.csv line 1: expected 7 columns of data but found 6


So the question is: how do I import NULL values?
I searched the mailing list archives and I found that the same question has been asked a month ago, but it got no replies. (http://www.mail-archive.com/sqlite-users@sqlite.org/msg05168.html)
I also had a look at the documentation but I couldn't find any detailed explanation for the .dot commands at all, but I might have missed it.


Could anyone point me to the right direction, please?



I checked the code (in src/shell.c). As far as I can see, what you are trying to do isn't possible with the current implementation. The code in question is line 1094 (in version 3.0.8), which I've marked with a star below:


if( i+1!=nCol ){
fprintf(stderr,"%s line %d: expected %d columns of data but found %d\n",
zFile, lineno, nCol, i+1);
zCommit = "ROLLBACK";
break;
}
for(i=0; i<nCol; i++){
* sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
}
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
free(zLine);


As you can see, sqlite3_bind_text is used for all columns. You would have to write some ad-hoc code inside the loop that checked whether the value in azCol[i] was "null" or "NULL", and then used sqlite3_bind_null if that was the case, instead of sqlite3_bind_text.

Search for the string "import" in the shell.c code, and you will find the place where this is implemented.

HTH

Ulrik P.

--
Ulrik Petersen, MA, B.Sc.
University of Aalborg, Denmark





Reply via email to