You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MatLab SQLite读取列首为NaN的字段时报错求助

MatLab SQLite查询报错:列首为NaN时fetch执行失败

问题现象

使用MatLab的sqlwrite创建SQLite数据库和数据表后,执行fetch查询时:

  • 若某列的首行值为NaN,查询该列时会抛出错误
  • 若NaN不在列首,即使列中存在其他NaN,查询也能正常完成

报错信息

Error using matlab.depfun.internal.database.SqlDbConnector/fetchRows
Unexpected NULL; (zero-based) column index: 0. Details: [initVecVarVecFromSqldbTypes].

Error in sqlite/fetchHook

Error in database.relational.connection/fetch (line 234)
        data = fetchHook(connect,second_input,optsObject,isDynamicQuery,dynamicQuery,maxRows,preserveNames,dataReturnFormat,nvPairs{:});

复现代码

业务场景代码

dati_Osp = readtable("OSPEDALE1_Reg2.xls");
dati_Osp = renamevars(dati_Osp, 1:width(dati_Osp), ["ANNO", "AZIENDA", "ISTITUTO", "DISCIPLINA_DIMISSIONE", "PROGRESSIVO_REPARTO", "REGIME_DI_RICOVERO", "PROVENIENZA", "DRG", "GIORNATE_DEGENZA", "ACCESSI_IN_DH", "IMPORTO_REGIONALE", "DATA_DIMISSIONE", "COMUNE_DI_RESIDENZA", "ETA", "SESSO", "DIAGNOSI_PRINCIPALE", "DIAGNOSI_CONCOMITANTE1", "DIAGNOSI_CONCOMITANTE2", "DIAGNOSI_CONCOMITANTE3", "DIAGNOSI_CONCOMITANTE4", "INTERVENTO_PRINCIPALE", "INTERVENTO_SECONDARIO1", "INTERVENTO_SECONDARIO2", "INTERVENTO_SECONDARIO3", "INTERVENTO_SECONDARIO4", "MODALITA_DI_ACCESSO", "MODALITA_DI_DIMISSIONE", "TIPO_DI_RICOVERO", "DATA_INGRESSO", "TIPO_PRESCRITTORE", "CODICE_NOSOLOGICO"]);
dati_Osp(:, [28, 30]) = [];

% 创建/连接数据库
conn_Osp = sqlite("DB_Osp");
sqlwrite(conn_Osp, "dati_Osp", dati_Osp);

% 查询首行为NaN的列会报错
fetch(conn_Osp, 'SELECT ACCESSI_IN_DH FROM dati_Osp')

测试用例

conn = sqlite("DBPROVA", 'create');
T = readtable("pratica.txt");
sqlwrite(conn, "pratica", T);
fetch(conn,'select * from pratica')
close(conn)

pratica.txt内容:

PRATICA GIORNI_DEGENZA  COD_REP DRG IMPORTO
2003003986  103 NaN 297 10814
2003004403  78  NaN 462 8490
2003004467  69  7501    012 20941
2003004529  65  7501    012 20173
2003004716  55  3203    014 6289
2003004873  47  NaN 012 15049
2003004980  34  7501    012 10887
2003005005  41  7501    012 13128
2003005050  42  7501    013 13448

问题原因

MatLab通过sqlwrite写入SQLite时,会根据数据表第一行的数据自动推断SQLite列的类型。如果列首是NaN(对应SQLite的NULL值),MatLab无法确定该列的正确数据类型,导致后续fetch查询时解析数据出错。而当列首为有效值时,类型推断正常,后续的NULL(NaN)也能被正确处理。

解决办法

方法1:提前填充NaN值

根据列的业务类型,用合适的默认值替换NaN后再写入数据库:

  • 数值型列:可替换为0、列均值等(根据业务场景选择)
  • 字符串型列:可替换为空字符串''

示例代码(处理测试用例):

conn = sqlite("DBPROVA", 'create');
T = readtable("pratica.txt");
% 填充COD_REP列的NaN为0(数值型列)
T.COD_REP = fillmissing(T.COD_REP, 'constant', 0);
sqlwrite(conn, "pratica", T);
fetch(conn,'select * from pratica')
close(conn)

方法2:手动指定SQLite表结构

提前创建表并明确指定各列的数据类型,避免自动推断错误:

conn_Osp = sqlite("DB_Osp", "create");
% 手动创建表,指定列类型(示例,需根据实际列调整)
sqlquery = "CREATE TABLE dati_Osp (ANNO INTEGER, AZIENDA TEXT, GIORNATE_DEGENZA INTEGER, ACCESSI_IN_DH REAL, IMPORTO_REGIONALE REAL)";
sqlwrite(conn_Osp, sqlquery);
% 插入数据
sqlwrite(conn_Osp, "dati_Osp", dati_Osp);

方法3:调整行顺序(临时方案)

将包含有效值的行移至首行,写入数据库后再恢复原顺序:

% 找到列中第一个非NaN的行索引
nonNaNIdx = find(~isnan(dati_Osp.ACCESSI_IN_DH), 1);
% 交换首行和非NaN行
tempRow = dati_Osp(1, :);
dati_Osp(1, :) = dati_Osp(nonNaNIdx, :);
dati_Osp(nonNaNIdx, :) = tempRow;
% 写入数据库
sqlwrite(conn_Osp, "dati_Osp", dati_Osp);
% 查询完成后若需要,可再将行顺序恢复

内容的提问来源于stack exchange,提问作者BlobFish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:35:35