关于 matlab-write-database
面向 MATLAB 用户的数据库写入技能,涵盖关系数据库导出、SQL 操作、事务和存储过程。它梳理 Database Toolbox 函数的适用场景,并强调凭据保护与破坏性操作确认。
主要功能
- 01用 sqlwrite 插入 MATLAB 表
- 02用 sqlupdate 更新匹配行
- 03执行 SQL 和存储过程
- 04管理提交与回滚
- 05使用参数化预处理语句
- 06保护凭据并确认破坏性操作
适用场景
- 01将 MATLAB 计算结果导出到数据库
- 02以事务方式修改多个表
- 03运行带输出参数的存储过程
- 04重复执行参数化插入
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-write-database安装后在 Claude Code 中输入/matlab-write-database确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreference/cards/execute-storedproc.mdprepared-statements.mdsqlwrite-sqlupdate.mdtransactions.md详细介绍
MATLAB 数据库导出架构师
适用于向关系数据库写入数据、执行 SQL 语句、管理事务、运行存储过程或使用 SQL 预备语句。涵盖所有会修改数据库的 Database Toolbox 操作。
何时使用此技能
- 将 MATLAB 数据写入/插入数据库表
- 更新数据库表中的现有行
- 从数据库中删除数据
- 执行任意 SQL 语句(DDL、DML)
- 运行存储过程或自定义数据库函数
- 管理事务(提交/回滚)
- 使用 SQL 预备语句执行参数化查询
- 创建或更改数据库表结构
- 用户提到以下关键词:write、export、insert、sqlwrite、sqlupdate、update、delete、execute、stored procedure、runstoredprocedure、transaction、commit、rollback、DDL、CREATE TABLE、ALTER、prepared statement、bulk insert
何时不使用
- 从数据库读取/导入数据 — 使用
sqlread/fetch,并配合RowFilter和databaseImportOptions - 使用类映射进行面向对象的写入 — 使用 ORM(通过
Mappable类调用ormwrite/ormupdate) - 写入 MongoDB、Cassandra 或 Neo4j — 这些数据库各自有专用的文档/图写入接口
- 数据量过大,无法装入内存 — 读取时使用
DatabaseDatastore和分块处理;写入时使用分块的sqlwrite循环
关键规则
凭据安全
- 绝不在生成的代码中硬编码密码或凭据。
- 始终使用
setSecret/getSecret(R2024a 及更高版本)存储凭据。
数据库连接
- 始终在执行任何导出操作前建立并验证连接。连接后检查
isopen(conn)。 - 始终在使用完毕后通过
close(conn)关闭连接。
事务安全
- 使用
commit/rollback控制事务时,始终将AutoCommit设为off。 - 需要原子性时,始终将多语句操作封装在事务中。
- 始终在错误处理代码块中使用
rollback,以便在失败时撤销部分更改。
破坏性操作
- 执行任何可能不可逆地破坏或更改数据的 SQL 前,始终征求用户的明确确认。这包括:
DROP、TRUNCATE、DELETE,以及删除列或修改约束的ALTER语句。 - 未先向用户展示完整 SQL 并获得明确批准,绝不通过
execute()执行破坏性 SQL 语句。 - 确认提示必须包含完整 SQL 语句,或清楚说明将受影响的内容(例如:“这将删除表
employees。所有数据都将永久丢失。是否继续?”)。
决策框架
| 目标 | 函数 | 使用场景 |
|---|---|---|
| 将 MATLAB 表写入数据库表 | sqlwrite | 批量插入表格数据;必要时创建表 |
| 修改现有行 | sqlupdate | 更新符合筛选条件的特定行(R2023a 及更高版本) |
| 运行 DDL 或原始 SQL | execute | CREATE TABLE、DROP、ALTER、简单的 CALL 语句 |
| 重复执行参数化插入 | databasePreparedStatement | 高频插入且值不断变化 |
| 调用具有类型化输出的存储过程 | runstoredprocedure | 需要存储过程的类型化输出参数(仅限 JDBC/ODBC) |
| 调用简单存储过程 | execute with CALL | 无需类型化输出参数;返回结果集 |
execute与runstoredprocedure的区别: 需要类型化输出参数时,使用runstoredprocedure。对于简单调用或只需要结果集时,使用executewith CALL。
函数参考
| 函数 | 用途 | 起始版本 |
|---|---|---|
sqlwrite | 将 MATLAB 表插入数据库表 | R2018a |
sqlupdate | 更新数据库表中符合筛选条件的行 | R2023a |
update | 替换数据库表中的数据(旧版) | R2006a |
execute | 执行任意 SQL 语句(DDL、DML、存储过程) | R2018b |
runstoredprocedure | 使用输入/输出参数调用存储过程(仅限 JDBC/ODBC) | R2006b |
commit | 永久保存数据库更改 | R2006a |
rollback | 撤销数据库更改 | R2006a |
databasePreparedStatement | 创建 SQL 预处理语句(仅限 JDBC) | R2019b |
bindParamValues | 为预处理语句参数绑定值 | R2019b |
边缘情况
- NULL 值: MATLAB 的
missing、NaN或空字符串""在sqlwrite中会映射为 SQL NULL - 类型不匹配: 确保 MATLAB 列类型与数据库列类型相符(例如,INTEGER 列应使用
int32,而非double) - 自增主键: 调用
sqlwrite前,从 MATLAB 表中省略自增列
核心概念
详细用法和示例请参阅知识卡片:
- 插入和更新数据:
reference/cards/sqlwrite-sqlupdate.md - 执行 SQL 和存储过程:
reference/cards/execute-storedproc.md - 事务管理:
reference/cards/transactions.md - 预处理语句(仅限 JDBC):
reference/cards/prepared-statements.md
完整示例
完整示例请参阅知识卡片:
- 插入计算结果:
reference/cards/sqlwrite-sqlupdate.md - 使用事务原子性地更新多个表:
reference/cards/transactions.md - 使用预处理语句执行参数化插入:
reference/cards/prepared-statements.md
常见错误
% INCORRECT — inserting rows one at a time in a loop (very slow)
for i = 1:height(data)
sqlwrite(conn, "orders", data(i,:));
end
% CORRECT — batch insert the entire table at once
sqlwrite(conn, "orders", data);
% INCORRECT — no transaction control for multi-table writes
sqlwrite(conn, "orders", orderData);
sqlwrite(conn, "order_items", itemData); % if this fails, orders are orphaned
% CORRECT — use transaction control for atomic multi-table writes
conn.AutoCommit = 'off';
try
sqlwrite(conn, "orders", orderData);
sqlwrite(conn, "order_items", itemData);
commit(conn);
catch ME
rollback(conn);
conn.AutoCommit = 'on'; %#ok<NASGU> restore before rethrowing
rethrow(ME);
end
conn.AutoCommit = 'on';
% INCORRECT — including auto-increment column in sqlwrite
data = table(1, "Widget", 9.99, VariableNames=["ID", "Name", "Price"]);
sqlwrite(conn, "products", data); % Error if ID is auto-increment
% CORRECT — omit auto-increment column
data = table("Widget", 9.99, VariableNames=["Name", "Price"]);
sqlwrite(conn, "products", data);
% INCORRECT — single filter with multi-row data table
rf = rowfilter("Category");
filter = rf.Category == "Widgets"; % matches 2 rows
data = table([8.99; 12.99], VariableNames="Price"); % 2 rows
sqlupdate(conn, "products", data, filter); % Error: filters must match table height
% CORRECT — cell array of filters for multi-row update
rf = rowfilter("ProductID");
filters = {rf.ProductID == 1; rf.ProductID == 2};
data = table([8.99; 12.99], VariableNames="Price");
sqlupdate(conn, "products", data, filters);
最佳实践
- 始终使用
sqlwrite插入 MATLAB 表——它会自动处理类型映射。 - 始终优先使用
sqlupdate(R2023a+),而非原始 SQL UPDATE——它使用rowfilter进行类型安全的筛选。 - 始终在使用完连接后调用
close(conn)关闭连接。 - 对于需要原子性的多语句操作,优先使用事务(
commit/rollback)。 - 对于非常大的插入操作,在循环中手动分块处理 MATLAB 表,以避免内存问题。
- 对于重复的参数化操作,使用预处理语句——它们可以提升性能并防止 SQL 注入。
- 预处理语句仅限 JDBC——ODBC 或原生连接不支持。
runstoredprocedure仅限 JDBC/ODBC(database()连接)——原生连接(sqlite、postgresql、mysql、duckdb)不支持。请改用带 CALL 语句的execute。- 执行
DROP、TRUNCATE、DELETE或会删除列的ALTER之前,始终先向用户确认是否确实要执行破坏性操作——展示 SQL 并等待明确批准,即使用户的请求已暗示要执行该操作也不例外。
常见模式
模式 1:插入并验证
sqlwrite(conn, "myTable", data);
result = sqlread(conn, "myTable");
disp("Rows after insert: " + height(result));
模式 2:使用事务保护更新
conn.AutoCommit = 'off';
try
execute(conn, sqlStatement);
commit(conn);
catch e
rollback(conn);
conn.AutoCommit = 'on'; %#ok<NASGU> restore before rethrowing
rethrow(e);
end
conn.AutoCommit = 'on';
模式 3:先执行 DDL,再插入
execute(conn, "CREATE TABLE IF NOT EXISTS results (ID INT, Value DOUBLE)");
sqlwrite(conn, "results", data);
检查清单
完成前,请确认:
- 已建立并验证数据库连接(
isopen(conn)) - 未硬编码凭据——使用
getSecret或占位符 - 插入表数据时使用了
sqlwrite(而非原始 SQL INSERT) - 多语句原子性操作使用了事务
- 事务代码块结束后,
AutoCommit已恢复为'on' - 已使用
close(pstmt)关闭预处理语句 - 最后已使用
close(conn)关闭连接 - 执行前已向用户确认破坏性 SQL(
DROP、TRUNCATE、DELETE、ALTER)
故障排除
问题:sqlwrite 失败,并提示“table already exists”
- 解决方案:如果表不存在,
sqlwrite会创建该表;但如果表已存在且架构不同,则会报错。使用sqlwrite向现有表追加数据时,列名和类型必须匹配。
问题:无法识别 sqlupdate
- 解决方案:
sqlupdate需要 R2023a 或更高版本。对于更早的版本,请使用update,或使用execute执行原始 SQL UPDATE 语句。
问题:sqlupdate 报错,提示“Number of filters must match the height of the table”
- 解决方案:对于多行更新,请传入 RowFilter 对象的元胞数组(每行数据对应一个筛选器)。单个
RowFilter仅适用于只有 1 行的数据表(会广播到所有匹配的行)。请勿传入一个匹配 N 行的单个筛选器,并同时传入一个有 N 行的数据表,否则会报错。
问题:commit 后看不到事务更改
- 解决方案:确认在事务开始前已将
AutoCommit设置为'off'。如果AutoCommit为'on',每条语句都会立即自动提交。
问题:预处理语句报错,提示“parameter index out of range”
- 解决方案:确认
bindParamValues中的参数索引与 SQL 语句中?占位符的数量一致。索引从 1 开始。
问题:批量插入时内存不足
- 解决方案:
sqlwrite没有BatchSize参数。请在循环中手动分块处理 MATLAB 表,将data拆分为每块 5,000–50,000 行的切片,并对每个切片调用sqlwrite。
问题:runstoredprocedure 失败,并提示“wrong number of arguments”
- 解决方案:确认输入参数的数量与存储过程定义一致。对于 JDBC 连接,输出类型必须使用
java.sql.Types常量。
Copyright 2026 The MathWorks, Inc.
评论
支持 Markdown