MySQL
MySQL node reference - all 23 operations, the credential it needs, and a worked example.
Read and write a MySQL database without writing SQL: select, insert, update, upsert, replace and delete rows, bulk writes, transactions, stored procedures, and schema discovery. Raw SQL is still there when you want it.
Credential: MySQL connection string - see Credentials.
Privileges
Each operation below lists the privilege it needs. Privileges are GRANTed to the MySQL account in the connection string. MySQL has no scopes and no consent screen - the equivalent question is which privilege the connecting account holds on the object, which is exactly what a command denied to user ... error is asking for. Narrow the blast radius by connecting as an account granted only what the workflow needs. If a run fails with a permission error, the node names the missing privilege in the error - grant it and re-run; you do not need to rebuild the workflow.
Operations (23)
Rows — read
| Operation | What it does | Privilege |
|---|---|---|
selectRows | Select rows | SELECT on the table |
getRow | Get one row | SELECT on the table |
countRows | Count rows | SELECT on the table |
Rows — write
| Operation | What it does | Privilege |
|---|---|---|
insertRow | Insert a row | INSERT on the table |
insertRows | Insert many rows | INSERT on the table |
updateRows | Update rows | UPDATE on the table (and SELECT for the filter) |
upsertRow | Insert or update a row | INSERT and UPDATE on the table |
upsertRows | Insert or update many rows | INSERT and UPDATE on the table |
replaceRow | Replace a row | INSERT and DELETE on the table |
replaceRows | Replace many rows | INSERT and DELETE on the table |
deleteRows | Delete rows | DELETE on the table (and SELECT for the filter) |
truncateTable | Empty a table (truncate) | DROP on the table (TRUNCATE is DDL in MySQL) |
SQL
| Operation | What it does | Privilege |
|---|---|---|
executeQuery | Run a SQL query | Whatever the statement itself needs |
executeTransaction | Run statements in a transaction | Whatever the statements themselves need |
explainQuery | Explain a query plan | SELECT on everything the plan touches |
Procedures & functions
| Operation | What it does | Privilege |
|---|---|---|
callProcedure | Call a stored procedure | EXECUTE on the procedure |
callFunction | Call a function | EXECUTE on the function |
Schema
| Operation | What it does | Privilege |
|---|---|---|
listDatabases | List databases | Connect — information_schema shows only what you can see |
listTables | List tables | Connect — information_schema shows only what you can see |
listColumns | List columns | Connect — information_schema shows only what you can see |
listIndexes | List indexes | Connect — information_schema shows only what you can see |
listConstraints | List keys and constraints | Connect — information_schema shows only what you can see |
getServerInfo | Get server info | Connect |
Example
Learn the id of the row you just inserted
MySQL has no RETURNING clause, so the only way to find out the primary key of a row you just created is insertId — and until SW20.2 this node discarded it. Every write reported rows: [] and rowCount: 0 because mysql2 resolves a write to a ResultSetHeader object rather than an array, and the node kept Array.isArray(rows) ? rows : [].
Set Operation to insertRow, then fill in:
| Field | Value | Notes |
|---|---|---|
table | signups | Identifiers are escape-quoted, never interpolated into the statement |
values | {"email": "{{ myTrigger.email }}", "source": "{{ myTrigger.utmSource }}"} | Bound parameters — an expression here is a value, never SQL |
Sets {{signup.insertId}} (the AUTO_INCREMENT key — the whole point of this operation on MySQL), {{signup.rowCount}} (affected rows) and {{signup.rows}}.