Sqlite3 - 如何从csv导入NULL值

时间:2016-04-21 15:31:47

标签: mysql csv sqlite

我已将mysql表转储为CSV格式。在此CSV文件中,NULL值写为\N
现在我想将这些数据导入sqlite数据库,但是我无法告诉sqlite \N是空值。它将它视为一个字符串,并将列值存储为" \ N"而不是NULL。

任何人都可以指导如何使用sqlite中的.nullvalue dot命令。我无法将\N设置为nullvalue。

sqlite> .show
nullvalue: ""
sqlite> .nullvalue \N
sqlite> .show
nullvalue: "N"
sqlite> .nullvalue '\N'
sqlite> .show
nullvalue: "\\N"
sqlite> .nullvalue "\N"
sqlite> .show
nullvalue: "N"
sqlite> .nullvalue \\N
sqlite> .show
nullvalue: "\\N"
sqlite> .nullvalue '\'N
Usage: .nullvalue STRING
sqlite> .nullvalue '\\'N
Usage: .nullvalue STRING
sqlite> .nullvalue \\N
sqlite> .show
nullvalue: "\\N"
sqlite>

这是nullvalue

的每个值之后的输出
sqlite> .import /tmp/mysqlDump.csv employee
sqlite> select count(*) from employee where updatedon='\N';
94143
sqlite> select count(*) from employee where updatedon is null;
0

如何告诉sqlite将\N视为NULL值?我不能将空字符串用作NULL值,因为我的数据包含空字符串。

2 个答案:

答案 0 :(得分:8)

CSV文件仅包含文本值。无法从CSV文件中导入NULL值。

要将\N值转换为NULL,请稍后使用UPDATE:

UPDATE employee SET updatedon = NULL WHERE updatedon = '\N';

答案 1 :(得分:1)

将sqlite配置为检查外键引用时,将无法使用依赖于导入后进行更新的方法,因为导入会失败(外键约束会失败),并且没有行要更新。

为此,在导入后无法进行更新的情况下,必须在合并中修改shell.c文件(如下所示),并编译新的sqlite(.exe)二进制文件。

要进行的更改是,当字段为空时(使用sqlite3_bind_null将字段的参数绑定为NULL,而不是像目前所做的那样使用sqlite3_bind_text无条件地将其绑定为文本字段

以下是对sqlite版本3.33.0 2020-08-14进行更改的示例(作为补丁差异)。

该示例在新的编译时选项SQLITE_IMPORT_NULL_IF_EMPTY后面进行了更改,因此要启用它,您需要在编译时像这样定义它:

cc -DSQLITE_IMPORT_NULL_IF_EMPTY <other options> shell.c sqlite3.c -o sqlite3

带有建议选项(以及其他一些设置)的完整编译命令示例:

cc -Os -DSQLITE_IMPORT_NULL_IF_EMPTY -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_USE_ALLOCA -DSQLITE_OMIT_AUTOINIT -DSQLITE_DEFAULT_FOREIGN_KEYS=1 -DSQLITE_ENABLE_NULL_TRIM -DSQLITE_ENABLE_RBU -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DHAVE_USLEEP -DHAVE_READLINE shell.c sqlite3.c -lreadline -lncurses -o sqlite3

补丁文件内容:

--- sqlite-amalgamation-3330000/shell.c 2020-08-14 13:42:48.000000000 +0000
+++ shell.c     2020-10-07 13:23:39.000000000 +0000
@@ -17845,7 +17845,12 @@
         ** the remaining columns.
         */
         if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
+#ifdef SQLITE_IMPORT_NULL_IF_EMPTY
+        if (z==0 || z[0]=='\0') sqlite3_bind_null(pStmt, i+1);
+        else sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
+#else
         sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
+#endif
         if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
           utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
                           "filling the rest with NULL\n",