---json
{
"aliases": [
{ "path": ":docs:resource:sql_query" }
],
"page_id": "x5a14zj7vzypxmfu1kr01"
}
---
====== Data Resource - SQL Request======
===== About =====
A ''SQL request'' is a [[request|request]] against a [[docs:system:database:database|SQL database]]. It's the [[docs:resource:runtime|runtime data resource]] form of ''SQL''.
In a ''SQL request'' processing, Tabulify will:
* parse the ''Sql scripts'' (a file or string)
* extract the [[:docs:system:database:sql_statement|SQL statements]]
* execute them one by one
* and returns the result
===== Type =====
''Sql scripts'' can be stored in
* [[#sql files]] - one file, one script
* any [[#other resources]] where one [[:docs:resource:record|record]] is one script
==== SQL Files ====
[[docs:resource:sql_file|SQL files]] will become ''SQL Request'' if they are represented in an [[docs:resource:runtime#data uri|runtime data uri]]
For instance:
(top-5-clients.sql@cd)@sqlite
where:
* ''top-5-clients.sql'' is a [[docs:resource:sql_file|sql file]]
* located in the [[:docs:connection:cd|current directory (cd)]]
* and should be executed against a [[:docs:system:sqlite:sqlite|sqlite database]]
==== Other resources ====
''Sql scripts'' are generally stored in a [[docs:resource:sql_file|SQL File]] but you can get them from any [[docs:resource:resource|resource]].
If the resource has:
* only one column, this column is supposed to store the SQL Scripts
* otherwise we search for the column named ''sql''
Example:
* a [[docs:resource:sql_view|view]] where all scripts are returned in the ''sql'' column
(statements_view@sqlite)@sqlite
* a [[docs:resource:sql_select|select]] where all scripts are returned in the ''sql'' column
((select_statement.sql@cd)@sqlite)@sqlite
* a [[docs:resource:csv|csv file]] where all statements are on one line
(statements.csv@cd)@sqlite
===== List =====
Tabulify supports all SQL Statements:
* [[sql_dml|Data Manipulation Language (DML)]] - ie ''[[sql_select|SELECT]]/UPDATE/INSERT/MERGE'' statement
* [[sql_ddl|Data Definition Language (DDL)]] - ie ''CREATE/ALTER/DROP'' statement
* [[docs:system:database:sql_procedure|SQL Procedures]]- ie ''CALL/DO/DECLARE/BEGIN/END'' statement
===== Manifest =====
Example of [[docs:resource:manifest#kind|kind manifest]]
kind: sql-request
spec:
data-uri: (script.sql@cd)@database
data-def:
parameters:
- value: value1
direction: IN
type: varchar
- value: value2
direction: OUT
type: integer
- ...
strict-execution: true
where:
* ''data-uri'' is an [[docs:resource:runtime|runtime data-uri]]
* ''data-def'' is a [[:docs:resource:data-definition|data definition]] that accepts
* [[..:system:database:sql_parameterized_statement#parameters|parameters]] - A list of parameters if the script contains [[..:system:database:sql_parameterized_statement|SQL Parameterized Statement]]
* ''strict-execution'': if true, the execution will terminate when a SQL statement returns an error. Default to the [[docs:conf:global_env|global tabulify value]].
===== Execution =====
See [[docs:resource:runtime#execution|Runtime Execution]]
===== Limitation: 1 SQL Request, 1 Result Set =====
Tabulify is based on resource chaining (ie one resource, one response). Therefore, a ''SQL Request'' should return only one result set.
It means that in a ''SQL Request'', you:
* cannot have:
* multiple [[:docs:resource:sql_select|Select statements]]
* multiple [[:docs:resource:sql_dml|DML statements]] that are using the ''RETURNING'' clause
* multiple [[:docs:system:database:sql_procedure|Sql procedure]] with ''OUT'' [[:docs:system:database:sql_parameterized_statement|parameters]]
* can have:
* multiple [[:docs:resource:sql_dml|DML statements]] that are **NOT** using the ''RETURNING'' clause
* multiple [[:docs:resource:sql_ddl|DDL statements]]
* multiple DCL statements (GRANT/REVOKE)
* multiple [[:docs:system:database:sql_procedure|Sql procedure]] **without** ''OUT'' [[:docs:system:database:sql_parameterized_statement|parameters]]
If you want to execute a ''SQL Request'' with this limitation, you need to [[:docs:op:split|split]] the statements before running them in a [[:docs:flow:pipeline|pipeline]]
Note that not all database supports returning multiple result set. For instance, [[:docs:system:sqlserver:sqlserver|SQL Server does not support it]].
===== Note =====
==== Execution Warnings ====
When executing a query, the database engine may return warnings.
A warning may come from:
* the database engine
* the user code (For example, the [[https://learn.microsoft.com/en-us/sql/t-sql/language-elements/print-transact-sql|sql server print statement]] create a warning)
Tabulify sends this warnings to the [[wp>Standard_streams|standard error stream]] so that:
* the user will see them in a terminal
* the warnings will not interfere with the normal [[wp>Standard_streams|standard output stream]]
==== Why Request? ====
When creating this [[docs:resource:runtime|runtime]], we needed to give it a name.
We went through the following names in order:
* ''query'' because this is the most common name used in the documentation
* ''script'' because we wanted it to be the counterpart of the [[:docs:resource:script|file system script]]
* ''fetch'' because we wanted to indicate that it was a [[:docs:resource:request|remote call with a result]]
They were not selected:
* ''query'' because in the SQL world, it's an alias for a [[:docs:resource:sql_select|SELECT]] statement as seen in the [[https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#executeQuery-java.lang.String-|executeQuery]] method.
* ''script'' because it has a local meaning and does not reflect the fact that this is a call to a remote service
* ''fetch'' because it's a [[https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API|web word]] and is not well-known in the data world.
Finally, we ended up with ''request'' because:
* it reflects the fact that this is a call to a remote service
* the result given by the java driver is known as a [[https://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html|result set]]