Datasets Module (How-to Guide) walks you through configuring the Datasets module for bi-directional database communication. You'll create database connections, build queries, map tables to tags, and integrate query results with displays and scripts.
Every solution includes four pre-configured SQLite databases:
| Database | Purpose | File Location |
|---|---|---|
| TagHistorian | Time-series data | <SolutionName>.dbTagHistorian |
| AlarmHistorian | Alarm events & audit | <SolutionName>.dbAlarmHistorian |
| Retentive | Persistent tag values | <SolutionName>.dbRetentive |
| RuntimeUsers | Dynamic users | <SolutionName>.dbRuntimeUsers |
| Database | Provider | Connection String |
|---|---|---|
| SQL Server | SqlClient | Server=.\SQLEXPRESS;Database=MyDB; |
| PostgreSQL | PostgreSQL | Server=localhost;Database=MyDB;Port=5432; |
| MySQL | ODBC | Driver={MySQL};Server=localhost;Database=MyDB; |
| Oracle | OracleClient | Data Source=//localhost:1521/XE; |
Use curly brackets to embed tag values:
Static Query:
sql
SELECT * FROM Products WHERE Price > 100Dynamic Query with Tags:
sql
SELECT * FROM Products
WHERE Price > {{Tag.MinPrice}}
AND Category = '{{Tag.Category}}'For complex queries without SQL knowledge:
Use tags in file paths:
C:\Recipes\Recipe_{{Tag.RecipeID}}.xmlUsing DataGrid Control:
Dataset.Query.QueryNameUsing Scripts:
csharp
// Execute query
DataTable result = @Dataset.Query.MyQuery.SelectCommand();
// Process results
foreach(DataRow row in result.Rows)
{
@Tag.Value = row["ColumnName"];
}Synchronous - Blocks until complete:
csharp
DataTable dt = @Dataset.Query.MyQuery.SelectCommand();Asynchronous - Non-blocking:
csharp
@Dataset.Query.MyQuery.ExecuteAsync();
// Check LastStatus property for completionFor critical data operations:
Connection Failed
Query Syntax Error
No Data Returned
Performance Issues
FrameworX provides two built-in approaches to prevent SQL Injection when interacting with databases. The choice depends on the use case and complexity of the operation.
Dataset Tables automatically generate INSERT and UPDATE commands using internal ADO parameterized queries. Since the framework builds these operations internally with typed parameters, tag values are never concatenated into the SQL string. SQL Injection protection is automatic and transparent.
This approach is recommended for straightforward insert and update operations that do not require custom database logic.
execute commandWhen the execute keyword is used in a Dataset Query, FrameworX parses the command internally and calls the Stored Procedure (SQL Server) or Function (PostgreSQL) through ADO with typed parameter passing. Values are sent as ADO parameters — never concatenated into the SQL command — eliminating the risk of SQL Injection.
For detailed syntax, examples, and configuration, see DatasetQuery Stored Procedure
Summary
| Scenario | SQL Injection Risk | Recommendation |
|---|---|---|
| Hardcoded query, no tags | No risk — no user input involved | Direct query is safe |
| Query with tags not exposed to the user | No risk — values are controlled internally | Direct query is safe |
| Query with tags exposed to user input | Yes — user can manipulate values | Dataset Tables or execute with Stored Procedures/Functions |
For restricted databases:
→ Modules / Business Operations / Datasets Module → Tutorials / Business Operations / Datasets Module Tutorial → How-to Guides / I Business Operations / Datasets Module How-to Guide → Technical Reference / Business Operations / Datasets Module ReferenceDatasets Module Links
Explanation - to understand concepts
Tutorials - to learn by doing
How-to Guides - to accomplish specific tasks
Reference - technical details