matlab-write-database

$npx mdskill add matlab/matlab-agentic-toolkit/matlab-write-database

Writes MATLAB data to relational databases and executes SQL operations.

  • Inserts, updates, or deletes data in database tables from MATLAB.
  • Depends on MATLAB Database Toolbox and a database connection.
  • Selects appropriate function based on user intent and operation type.
  • Returns success status, affected rows, or execution results to the agent.

SKILL.md

.github/skills/matlab-write-databaseView on GitHub ↗
---
name: matlab-write-database
description: "Writes data from MATLAB to relational databases and performs database operations. Use when writing data with sqlwrite, updating rows with sqlupdate, executing SQL with execute, running stored procedures, managing transactions with commit/rollback, creating tables, or using SQL prepared statements."
license: MathWorks BSD-3-Clause
metadata:
  author: MathWorks
  version: "1.1"
---

# MATLAB Database Export Architect

Use when writing data to relational databases, executing SQL statements, managing transactions, running stored procedures, or using SQL prepared statements. Covers all Database Toolbox operations that modify the database.

## When to Use This Skill

- Writing/inserting MATLAB data into a database table
- Updating existing rows in a database table
- Deleting data from a database
- Executing arbitrary SQL statements (DDL, DML)
- Running stored procedures or custom database functions
- Managing transactions (commit/rollback)
- Using SQL prepared statements for parameterized queries
- Creating or altering database table structures
- User mentions keywords: write, export, insert, sqlwrite, sqlupdate, update, delete, execute, stored procedure, runstoredprocedure, transaction, commit, rollback, DDL, CREATE TABLE, ALTER, prepared statement, bulk insert

## When NOT to Use

- Reading/importing data from a database — use `sqlread`/`fetch` with `RowFilter` and `databaseImportOptions`
- Object-oriented writes with class mapping — use ORM (`ormwrite`/`ormupdate` with `Mappable` classes)
- MongoDB, Cassandra, or Neo4j writes — these have their own document/graph-specific write interfaces
- Large data that doesn't fit in memory — use `DatabaseDatastore` + chunked processing for reads, or chunked `sqlwrite` loops for writes

## Critical Rules

### Credential Security
- **NEVER** hardcode passwords or credentials in generated code.
- **ALWAYS** use `setSecret` / `getSecret` (R2024a+) for credential storage.

### Database Connection
- **ALWAYS** establish and verify a connection before any export operation. Check `isopen(conn)` after connecting.
- **ALWAYS** close connections with `close(conn)` when done.

### Transaction Safety
- **ALWAYS** set `AutoCommit` to `off` when using `commit` / `rollback` for transaction control.
- **ALWAYS** wrap multi-statement operations in a transaction when atomicity is required.
- **ALWAYS** use `rollback` in error-handling blocks to undo partial changes on failure.

### Destructive Operations
- **ALWAYS** ask the user for explicit confirmation before executing any SQL that could irreversibly destroy or alter data. This includes: `DROP`, `TRUNCATE`, `DELETE`, and `ALTER` statements that remove columns or modify constraints.
- **NEVER** execute a destructive SQL statement via `execute()` without first presenting the exact SQL to the user and receiving explicit approval.
- The confirmation prompt must include the exact SQL statement or a clear description of what will be affected (e.g., "This will drop table `employees`. All data will be permanently lost. Proceed?").


## Decision Framework

| Goal | Function | When to Use |
|------|----------|-------------|
| Write MATLAB table to DB table | `sqlwrite` | Bulk insert of tabular data; creates table if needed |
| Modify existing rows | `sqlupdate` | Update specific rows matching a filter (R2023a+) |
| Run DDL or raw SQL | `execute` | CREATE TABLE, DROP, ALTER, simple CALL statements |
| Repeated parameterized inserts | `databasePreparedStatement` | High-frequency inserts with varying values |
| Stored procedure with typed outputs | `runstoredprocedure` | Need typed output arguments from stored procedure (JDBC/ODBC only) |
| Simple stored procedure call | `execute` with CALL | No typed output args needed; result sets returned |

> **`execute` vs `runstoredprocedure`:** Use `runstoredprocedure` when you need typed output arguments. Use `execute` with CALL for simple invocation or when you only need result sets.

## Function Reference

| Function | Purpose | Since |
|----------|---------|-------|
| `sqlwrite` | Insert MATLAB table into database table | R2018a |
| `sqlupdate` | Update rows in database table matching a filter | R2023a |
| `update` | Replace data in database table (legacy) | R2006a |
| `execute` | Execute any SQL statement (DDL, DML, stored procs) | R2018b |
| `runstoredprocedure` | Call stored procedure with input/output arguments (JDBC/ODBC only) | R2006b |
| `commit` | Make database changes permanent | R2006a |
| `rollback` | Undo database changes | R2006a |
| `databasePreparedStatement` | Create SQL prepared statement (JDBC only) | R2019b |
| `bindParamValues` | Bind values to prepared statement parameters | R2019b |

### Edge Cases

- **NULL values:** MATLAB `missing`, `NaN`, or empty `""` map to SQL NULL in `sqlwrite`
- **Type mismatches:** Ensure MATLAB column types match DB column types (e.g., `int32` not `double` for INTEGER columns)
- **Auto-increment PKs:** Omit the auto-increment column from the MATLAB table before calling `sqlwrite`

## Core Concepts

See knowledge cards for detailed usage and examples:
- **Insert and update data**: `reference/cards/sqlwrite-sqlupdate.md`
- **Execute SQL and stored procedures**: `reference/cards/execute-storedproc.md`
- **Transaction management**: `reference/cards/transactions.md`
- **Prepared statements (JDBC only)**: `reference/cards/prepared-statements.md`

## Complete Examples

See knowledge cards for complete examples:
- **Insert computed results**: `reference/cards/sqlwrite-sqlupdate.md`
- **Atomic multi-table update with transaction**: `reference/cards/transactions.md`
- **Parameterized insert with prepared statement**: `reference/cards/prepared-statements.md`

### Common Mistakes

```matlab
% 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);
```

## Best Practices

- **ALWAYS** use `sqlwrite` for inserting MATLAB tables — it handles type mapping automatically.
- **ALWAYS** prefer `sqlupdate` (R2023a+) over raw SQL UPDATE — it uses `rowfilter` for type-safe filtering.
- **ALWAYS** close connections with `close(conn)` when done.
- Prefer transactions (`commit`/`rollback`) for multi-statement operations requiring atomicity.
- For very large inserts, chunk the MATLAB table manually in a loop to avoid memory issues.
- Use prepared statements for repeated parameterized operations — they improve performance and prevent SQL injection.
- Prepared statements are **JDBC only** — not available for ODBC or native connections.
- `runstoredprocedure` is **JDBC/ODBC only** (`database()` connections) — not available for native connections (sqlite, postgresql, mysql, duckdb). Use `execute` with a CALL statement instead.
- **ALWAYS** confirm destructive intent with the user before running `DROP`, `TRUNCATE`, `DELETE`, or column-dropping `ALTER` — present the SQL and wait for explicit approval, even if the user's request implied the operation.

## Common Patterns

### Pattern 1: Insert-Verify

```matlab
sqlwrite(conn, "myTable", data);
result = sqlread(conn, "myTable");
disp("Rows after insert: " + height(result));
```

### Pattern 2: Transaction-Protected Update

```matlab
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';
```

### Pattern 3: DDL-then-Insert

```matlab
execute(conn, "CREATE TABLE IF NOT EXISTS results (ID INT, Value DOUBLE)");
sqlwrite(conn, "results", data);
```

## Checklist

Before finalizing, verify:
- [ ] Database connection established and verified (`isopen(conn)`)
- [ ] No hardcoded credentials — uses `getSecret` or placeholders
- [ ] `sqlwrite` used for table inserts (not raw SQL INSERT for MATLAB data)
- [ ] Transactions used for multi-statement atomic operations
- [ ] `AutoCommit` restored to `'on'` after transaction blocks
- [ ] Prepared statements closed with `close(pstmt)`
- [ ] Connection closed with `close(conn)` at the end
- [ ] Destructive SQL (`DROP`, `TRUNCATE`, `DELETE`, `ALTER`) confirmed with user before execution

## Troubleshooting

**Issue**: `sqlwrite` fails with "table already exists"
- **Solution**: `sqlwrite` creates the table if it doesn't exist but errors if the table exists with a different schema. Use `sqlwrite` to append to an existing table — column names and types must match.

**Issue**: `sqlupdate` not recognized
- **Solution**: `sqlupdate` requires R2023a or later. For older releases, use `update` or execute a raw SQL UPDATE statement with `execute`.

**Issue**: `sqlupdate` errors with "Number of filters must match the height of the table"
- **Solution**: For multi-row updates, pass a **cell array of RowFilter objects** (one filter per data row). A single `RowFilter` only works with a 1-row data table (broadcasts to all matching rows). Do not pass a single filter that matches N rows with an N-row data table — this errors.

**Issue**: Transaction changes not visible after `commit`
- **Solution**: Verify `AutoCommit` was set to `'off'` before the transaction. If `AutoCommit` is `'on'`, each statement auto-commits immediately.

**Issue**: Prepared statement errors with "parameter index out of range"
- **Solution**: Verify the parameter indices in `bindParamValues` match the number of `?` placeholders in the SQL statement. Indices are 1-based.

**Issue**: Bulk insert runs out of memory
- **Solution**: `sqlwrite` has no `BatchSize` parameter. Chunk the MATLAB table manually in a loop — split `data` into slices of 5,000–50,000 rows and call `sqlwrite` on each slice.

**Issue**: `runstoredprocedure` fails with "wrong number of arguments"
- **Solution**: Verify the input argument count matches the stored procedure definition. For JDBC connections, output types must use `java.sql.Types` constants.


----

Copyright 2026 The MathWorks, Inc.

----

More from matlab/matlab-agentic-toolkit

SkillDescription
matlab-access-datafeed>
matlab-add-awgnRead BEFORE writing any code that adds Additive White Gaussian Noise (AWGN) to signals and converts between SNR, Eb/No, Es/No, and per-subcarrier SNR for communications simulations, using awgn(), convertSNR(), berawgn(). The default MATLAB patterns for AWGN (e.g., 'measured' option, manual SNR formulas) produce subtly incorrect results. This skill specifies the correct calling conventions, required function usage, and critical anti-patterns that must be avoided.
matlab-analyze-ams-waveformAnalyze AMS waveform data using Mixed-Signal Blockset utilities: phase noise measurement, clock jitter, anti-aliased resampling, timing measurements, lock time, INL/DNL, ADC/DAC calibration, HSpice import. Use when analyzing time-domain voltage from PLL/VCO/clock simulations, measuring phase noise from variable-step solver output, computing jitter, or resampling non-uniform data.
matlab-analyze-dataAnalyze data using MATLAB. Use when the task involves tables, timetables, time-series data, numeric arrays, sensor matrices, or gridded data — including but not limited to exploring, filtering, sorting, cleaning, transforming, aggregating, smoothing, padding, trimming, and answering questions about data. MATLAB provides extensive, easy-to-use built-in functions for these workflows with no additional products required.
matlab-analyze-dependenciesAnalyze the effective toolbox file set to produce a Dependency Manifest — classify all transitive dependencies as included, product, add-on, or external-unresolved, then present resolution options with tradeoffs. Use after matlab-define-toolbox-api when the spec is approved.
matlab-analyze-emS-parameters, insertion loss, fields, currents, mesh control, and solver selection for RF PCB performance validation. TRIGGER: user asks to compute S-parameters, analyze insertion/return loss, extract fields or currents, compare MoM vs FEM, or control mesh for any RF PCB component. Invoke BEFORE writing sparameters() or solver code — API is non-obvious. SKIP: designing or creating components (use the specific matlab-design-pcb-* skill), material/stackup setup only (use matlab-manage-pcb-material), optimization sweeps (use matlab-optimize-pcb-design), PDN/IR-drop analysis (use matlab-analyze-pcb-pdn).
matlab-analyze-installed-antennaAnalyze antennas installed on electrically large conducting platforms using MATLAB Antenna Toolbox. Loads platform geometry from STL/STEP/IGES, installs antenna elements, selects electromagnetic solvers (MoM-PO, FMM, MoM), and computes patterns, impedance, coupling, and efficiency. Use when the user wants to model an antenna on a vehicle, aircraft, ship, satellite, or other large structure.
matlab-analyze-pcb-pdnPDN DC voltage/current analysis, IR drop, design rule checking, and multi-net batch analysis on imported PCB layouts. TRIGGER: user asks about power integrity, PDN analysis, IR drop, voltage distribution, current density, power nets, or design rule checking on a PCB. Invoke BEFORE writing code — the PDN API chain is specialized and non-obvious. SKIP: importing a PCB file (use matlab-read-pcb-layout), EM field/S-parameter extraction (use matlab-analyze-em), material/stackup setup only (use matlab-manage-pcb-material), transmission line design (use matlab-design-pcb-txline).
matlab-analyze-rcsCalculate and visualize monostatic and bistatic radar cross section (RCS) using MATLAB Antenna Toolbox. Computes RCS of platforms, antennas, and arrays with PO, MoM, and FMM solvers, supporting HH/VV/HV/VH polarization, GPU acceleration, and near-field observation. Use when the user wants to compute, plot, or analyze radar cross section.
matlab-analyze-rf-propagationAnalyze RF propagation and plan wireless sites using MATLAB Antenna Toolbox. Creates transmitter/receiver sites, computes signal strength, coverage maps, SINR, line-of-sight, and ray tracing in geographic or indoor environments. Supports multiple propagation models (free-space, close-in, Longley-Rice, ray tracing, rain/gas/fog), custom terrain, building data, and directional antennas. Use when the user wants to compute coverage, signal strength, path loss, SINR, ray tracing, or plan a wireless network.