我已将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值,因为我的数据包含空字符串。
答案 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",