mcpField
M
matlab-write-database

matlab-write-database

github.com/matlab数据与数据库1.2k55 次安装2 天前更新
代码仓库

关于 matlab-write-database

面向 MATLAB 用户的数据库写入技能,涵盖关系数据库导出、SQL 操作、事务和存储过程。它梳理 Database Toolbox 函数的适用场景,并强调凭据保护与破坏性操作确认。

主要功能

  1. 01用 sqlwrite 插入 MATLAB 表
  2. 02用 sqlupdate 更新匹配行
  3. 03执行 SQL 和存储过程
  4. 04管理提交与回滚
  5. 05使用参数化预处理语句
  6. 06保护凭据并确认破坏性操作

适用场景

  1. 01将 MATLAB 计算结果导出到数据库
  2. 02以事务方式修改多个表
  3. 03运行带输出参数的存储过程
  4. 04重复执行参数化插入

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-write-database

安装后在 Claude Code 中输入/matlab-write-database确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

manifest.yaml
reference/cards/
execute-storedproc.md
prepared-statements.md
sqlwrite-sqlupdate.md
transactions.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 或原始 SQLexecuteCREATE TABLE、DROP、ALTER、简单的 CALL 语句
重复执行参数化插入databasePreparedStatement高频插入且值不断变化
调用具有类型化输出的存储过程runstoredprocedure需要存储过程的类型化输出参数(仅限 JDBC/ODBC)
调用简单存储过程execute with CALL无需类型化输出参数;返回结果集

execute 与 runstoredprocedure 的区别: 需要类型化输出参数时,使用 runstoredprocedure。对于简单调用或只需要结果集时,使用 execute with 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