Skip to content

Database Activities

Version: 1.0.3  ·  ID: zoan-packages-database  ·  Author: Zoan Software

The Database package lets your automation read and modify databases directly with SQL. It is the most efficient way to work with large volumes of data when you have access to the database: query thousands of records, insert results, update statuses. It supports SQL Server, PostgreSQL, MySQL and any source via ODBC.

Working with a database follows the open → use → close pattern:

  1. DB Connect opens a connection and returns a session (ZoanDbSession).
  2. You run one or more queries with DB Query, DB Execute or DB Scalar.
  3. DB Close closes the connection.

As with other session packages, there are two ways:

Section titled “Option A — DB Connect with body (recommended)”

Activities inside the body inherit the connection automatically (you don’t set session), and the connection closes by itself when it ends.

DB Connect provider = sqlserver connectionString = credential("db-sales")["value"]
└─ body:
DB Query sql = "SELECT * FROM Customers WHERE Active = 1" → output: customers
DB Execute sql = "UPDATE Jobs SET LastRun = GETDATE()"

DB Connect stores the session in a variable; each activity receives it in session, and you close it with DB Close.

DB Connect provider = postgres connectionString = credential("db")["value"] → output: db
DB Query session = db sql = "SELECT * FROM orders" → output: orders
DB Close session = db
providerEngine
sqlserverMicrosoft SQL Server
postgresPostgreSQL
mysqlMySQL / MariaDB
odbcAny source with an ODBC driver installed on the robot’s machine

In expressions the aliases mssql, sql server, postgresql, pg and mariadb are accepted too. Each engine uses its .NET driver (Microsoft.Data.SqlClient, Npgsql, MySqlConnector); for odbc you install the driver on the robot’s machine.

The connection string (connectionString) is the standard ADO.NET text that sets server, database and credentials:

Server=db.example.com;Database=sales;User Id=bot;Password=...;

Never put variable values straight into the SQL text by concatenating. Use parameters instead: put @name in the query and pass the values in the params field (an object { name: value }).

DB Query
sql = "SELECT * FROM Customers WHERE City = @city AND Active = @active"
params = { "city": targetCity, "active": true }
→ output: result
  • Each params key is sent as @key; you can write the key with or without @.
  • Values can be expressions (customerId); text, numbers, true/false and null reach the engine with their type.
  • With odbc, the package replaces each @name in the SQL with ? in order of appearance: a repeated name sends its value again and a name with no value in params is sent as NULL. Avoid writing @ inside SQL string literals when you use ODBC.
  • Parameters are for values, not for table or column names. If a table name comes from a variable, validate it against a list of allowed values before building the SQL.
  • Autocommit: each statement is committed as it runs; the package does not open transactions. To make several statements apply all or nothing, send them in the same DB Execute inside the engine’s transaction (BEGIN TRAN … COMMIT in SQL Server, BEGIN; … COMMIT; in PostgreSQL) or use a stored procedure.
  • Timeouts: the activities have no timeout parameter; the driver’s apply. Adjust them in the connection string with the driver’s keywords if you need to.
  • Errors: engine errors (syntax, constraints, locks, connection) arrive with the database’s original message. Combine them with Try / Catch and Retry.
ActivityPurposeReturns
DB QuerySELECT returning several rowsDataTable (0 rows if nothing matches)
DB ScalarSELECT returning a single value (a COUNT, a MAX)the value (null if there are no rows)
DB ExecuteINSERT / UPDATE / DELETEnumber of affected rows
ActivityTypeOutputWhat it does
DB Connectdb-connectZoanDbSessionOpens a connection and returns a session
DB Querydb-queryDataTableRuns a SELECT and returns the rows
DB Scalardb-scalarobjectRuns a SELECT and returns a single value
DB Executedb-executeintRuns INSERT/UPDATE/DELETE; returns affected rows
DB Closedb-close—Closes the connection

Read pending orders and mark them as processed:

DB Connect provider = sqlserver connectionString = credential("db-erp")["value"]
└─ body:
DB Query sql = "SELECT * FROM Orders WHERE Status = @s" params = { "s": "pending" } → output: orders
For Each items = orders itemVariable = row
└─ activities:
... process ...
DB Execute sql = "UPDATE Orders SET Status = 'processed' WHERE Id = @id" params = { "id": row["Id"] }