"runSqlStatements"
JSON DB "runSqlStatements"
action runs SQL statements as a batch operation
The "runSqlStatements"
action runs one or more SQL statements as a batch operation, such as drop, create, alter, call, insert, update, and delete statements.
Notice
JSON DB API transactions do not support SQL stored procedures, stored functions, and triggers. It also does not support "revertTransactionToSavepoint"
when the transaction contains a call to "getRecordsUsingSQL"
or "runSqlStatements"
. Unsupported actions return an error.
The
"runSqlStatements"
action cannot run in an existing transaction. It creates a new transaction.FairCom does not recommend including
SELECT
statements in the"runSqlStatements"
action because the server returns all records selected by each query.It is easy to return too many records, which results in query timeouts or clients receiving too much data.
It is much better to use the
"getRecordsUsingSQL"
action to run SQL queries because it can return a cursor, which is faster and much more efficient at paginating data.If you want to use the
"runSqlStatements"
to run queries, be sure to add the SQL TOP clause to your SQL statement to limit the number of records returned.
The server returns a
"data"
object in the response that contains one object for each SQL statement in the request.The
"errorCode"
property for each individual SQL statement indicates the success or failure of the statement during runtime.You must check the
"errorCode"
property of each individual SQL statement to determine if it succeeded or failed. This is intentional because there are use cases where you expect some SQL statements to fail, such as dropping a table before creating it.Do not assume a zero value in the
"errorCode"
property for the"runSqlStatements"
action means all SQL statements succeeded.The only time the server sets a non-zero value in the
"errorCode"
property for the"runSqlStatements"
action is when it evaluates the request and detects invalid JSON syntax, missing required properties, and invalid property values.
Before the server runs SQL statements, it creates a new transaction, then runs all specified SQL statements in that transaction.
Tip
It can be efficient to run hundreds of statements in one
"runSQLStatements"
action.By default, the server automatically rolls back the transaction at the end. You must set the
"atEnd"
and"onError"
properties to control how the server commits each SQL statement.You may call a stored procedure as long as it does not have out or
"in"
/"out"
parameters and you pass a constant value to each"in"
parameter.A SQL statement may optionally include a semicolon at its end, but it is unnecessary and is ignored.
A SQL statement may contain one or more line feed characters. These are encoded in JSON strings as
\n
.Use
"runSQLStatements"
action to do things that are not available in other JSON DB API actions.Use parameters in the
SELECT
andCALL
statements to prevent SQL injection attacks.Note
A parameter name in the SQL statement must begin with a colon, immediately followed by the name of the parameter. When defining input and output parameters in JSON, parameter names do not include the colon to be more friendly to programming languages.
Use native JSON DB API actions when possible. They run faster than SQL. It is also easier and safer to dynamically generate JSON in your code than to generate SQL code.
Use the
"getRecordsUsingSQL"
action to run queries because it can return a cursor.Use the
"createTable"
action to create a table because it follows best practices and provides more settings.Use the
"alterTable"
action to modify a table because it is easier to use.Use the
"insertRecords"
action to insert large numbers of records because it is more efficient.
Request examples
Minimal request
Note
This example shows automatic rollback on error.
{ "api": "db", "authToken": "replaceWithAuthtokenFromCreateSession", "action": "runSQLStatements", "params": { "sqlStatements": [ "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )", "CREATE UNIQUE INDEX employee_pk ON employee (id)", "INSERT INTO employee \n VALUES (7369, 'John Smith', 'Clerk')" ] } }
{ "api": "db", "authToken": "replaceWithAuthtokenFromCreateSession", "action": "runSQLStatements", "params": { "onError": "stop", "atEnd": "rollback", "sqlStatements": [ "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )", "CREATE UNIQUE INDEX employee_pk ON employee (id)", "INSERT INTO employee \n VALUES (7369, 'John Smith', 'Clerk')" ] }, "debug": "none" }
{ "requestId": "2", "authToken": "replaceWithAuthtokenFromCreateSession", "api": "db", "action": "runSQLStatements", "params": { "transactionId": "NO SUPPORT FOR TRANSACTIONS AT THIS TIME", "databaseName": "ctreeSQL", "ownerName": "admin", "onError": "continue", "atEnd": "commit", "sqlStatements": [ "DROP TABLE employee;", "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )", "CREATE UNIQUE INDEX employee_pk ON employee (id)", "INSERT INTO employee VALUES (7369, 'John Smith', 'Clerk');", "INSERT INTO employee VALUES (1, 'Emma Smith', 'Boss')", "CALL my_stored_proc(:inIntParam1, :outDoubleParam2, :inOutBinaryParam3)", "CALL c2f(:input_celsius, :output_fahrenheit) ", "SELECT TOP 20 SKIP 0 name \nFROM employee \nWHERE name <= :mySqlNamedParam4", "CREATE TABLE employee ( id BIGINT )" ], "inParams": [ { "name": "inIntParam1", "value": 3 }, { "name": "inoutBinaryParam3", "value": "54657374" }, { "name": "mySqlNamedParam4", "value": "J" }, { "name": "input_celsius", "value": 22 } ] }, "responseOptions": { "binaryFormat": "hex", "dataFormat": "objects", "numberFormat": "string", "includeFields": [], "excludeFields": [] }, "apiVersion": "1.0", "debug": "max" }
Note
This example shows automatic rollback on error.
{ "authToken": "authToken", "result": { "reactions": [ { "affectedRows": 0, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "sql": "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )" }, { "affectedRows": 0, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "sql": "CREATE UNIQUE INDEX employee_pk ON employee (id)" }, { "affectedRows": 1, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "sql": "INSERT INTO employee \n VALUES (7369, 'John Smith', 'Clerk')" } ] }, "debugInfo": { "request": { "authToken": "authToken", "api": "db", "action": "runSQLStatements", "params": { "sqlStatements": [ "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )", "CREATE UNIQUE INDEX employee_pk ON employee (id)", "INSERT INTO employee \n VALUES (7369, 'John Smith', 'Clerk')" ] }, "debug": "max" }, "serverSuppliedValues": { "databaseName": "faircom", "ownerName": null }, "errorData": { "errorData": null }, "warnings": [] }, "errorCode": 0, "errorMessage": "" }
Note
This result occurs when the minimal request example is run a second time.
{ "authToken": "authToken", "result": { "data": [ { "affectedRows": 0, "errorCode": -20041, "errorMessage": "Table/View/Synonym employee already exists", "sql": "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )" }, { "affectedRows": 0, "errorCode": -20028, "errorMessage": "Index with the same name employee_pk already exists", "sql": "CREATE UNIQUE INDEX employee_pk ON employee (id)" }, { "affectedRows": 0, "errorCode": -17002, "errorMessage": "CT - Key value already exists in index employee_pk", "output": {}, "sql": "INSERT INTO employee \n VALUES (7369, 'John Smith', 'Clerk')" } ] }, "errorCode": 0, "errorMessage": "" }
{ "authToken": "authToken", "result": { "reactions": [ { "affectedRows": 0, "errorCode": -20041, "errorMessage": "Table/View/Synonym employee already exists", "outParams": [], "rows": {}, "sql": "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )" } ] }, "errorCode": 0, "errorMessage": "" }
{ "authToken": "authToken", "result": { "reactions": [ { "affectedRows": 0, "errorCode": -20005, "errorMessage": "Table/View/Synonym employee not found", "outParams": [], "rows": {}, "sql": "DROP TABLE employee" }, { "affectedRows": 0, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "sql": "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )" }, { "affectedRows": 0, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "sql": "CREATE UNIQUE INDEX employee_pk ON employee (id)" }, { "affectedRows": 1, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "sql": "INSERT INTO employee VALUES (7369, 'John Smith', 'Clerk')" }, { "affectedRows": 1, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "sql": "INSERT INTO employee VALUES (1, 'Emma Smith', 'Boss')" }, { "affectedRows": 0, "errorCode": -20122, "errorMessage": "procedure my_stored_proc not found", "outParams": [], "rows": {}, "sql": "CALL my_stored_proc(:inIntParam1, :outDoubleParam2, :inOutBinaryParam3)" }, { "affectedRows": 0, "errorCode": -20122, "errorMessage": "procedure c2f not found", "outParams": [], "rows": {}, "sql": "CALL c2f(:input_celsius, :output_fahrenheit)" }, { "affectedRows": 0, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": { "binaryFormat": "hex", "data": [ { "name": "Emma Smith" } ], "dataFormat": "objects", "fields": [ { "length": 50, "name": "name", "type": "varchar" } ], "moreRecords": false, "numberFormat": "string", "requestedRecordCount": 1, "returnedRecordCount": 1 }, "sql": "SELECT TOP 20 SKIP 0 name \nFROM employee \nWHERE name <= :mySqlNamedParam4" }, { "affectedRows": 0, "errorCode": -20041, "errorMessage": "Table/View/Synonym employee already exists", "outParams": [], "rows": {}, "sql": "CREATE TABLE employee ( id BIGINT )" } ] }, "requestId": "2", "debugInfo": { "request": { "authToken": "authToken", "api": "db", "action": "runSQLStatements", "params": { "databaseName": "ctreeSQL", "ownerName": "admin", "onError": "continue", "atEnd": "commit", "sqlStatements": [ "DROP TABLE employee;", "CREATE TABLE employee (id BIGINT, name VARCHAR(50), job VARCHAR(50) )", "CREATE UNIQUE INDEX employee_pk ON employee (id)", "INSERT INTO employee VALUES (7369, 'John Smith', 'Clerk');", "INSERT INTO employee VALUES (1, 'Emma Smith', 'Boss')", "CALL my_stored_proc(:inIntParam1, :outDoubleParam2, :inOutBinaryParam3)", "CALL c2f(:input_celsius, :output_fahrenheit) ", "SELECT TOP 20 SKIP 0 name \nFROM employee \nWHERE name <= :mySqlNamedParam4", "CREATE TABLE employee ( id BIGINT )" ], "inParams": [ { "name": "inIntParam1", "value": 3 }, { "name": "inoutBinaryParam3", "value": "54657374" }, { "name": "mySqlNamedParam4", "value": "J" }, { "name": "input_celsius", "value": 22 } ] }, "apiVersion": "1.0", "requestId": "2", "responseOptions": { "binaryFormat": "hex", "dataFormat": "objects", "numberFormat": "string", "includeFields": [], "excludeFields": [] }, "debug": "max" }, "serverSuppliedValues": { "databaseName": "ctreeSQL", "ownerName": null }, "errorData": { "errorData": null }, "warnings": [ { "code": 100, "message": "SQL execution produced errors" } ] }, "errorCode": 0, "errorMessage": "" }
Use the runSqlStatements JSON API action to run sql statements as a batch operation
The "params"
property is an object that contains an action's parameters. Each action defines its own required and optional properties.
Properties summary
"params"
properties summaryProperty | Description | Default | Type | Limits (inclusive) | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
specifies how the action commits or rolls back the statements it runs |
| string |
| ||||||||
specifies the name of a database | Defaults to the | string | 1 to 64 bytes | ||||||||
specifies values for input parameters |
The is the default when no SQL statements have any named parameters. When one or more SQL statements have named parameters, this is required. | array of objects | |||||||||
| specifies the name of an input parameter | Required - No default value | string | ||||||||
| specifies the value of the parameter | Required - No default value |
| ||||||||
specifies when to stop or continue the execution of SQL statements |
| string |
| ||||||||
specifies the unique name of a schema in a database |
| string | 1 to 64 bytes | ||||||||
sqlStatements | specifies SQL statements that the server will execute There is one SQL statement per string | Required - No default value | array of strings |
The "atEnd"
property is an optional string that defines how the action commits or rolls back the statement it runs. It defaults to "rollbackOnError"
.
Possible values:
"commit"
Setting
"atEnd"
to"commit"
causes the"runSqlStatements"
action to always commit the results of all successful SQL statements that you specify."rollbackOnError"
Setting
"atEnd"
to"rollbackOnError"
causes the"runSqlStatements"
action to commit the results of all SQL statements as long as all are completed successfully. If one SQL statement returns an error, the"runSqlStatements"
action rolls back all changes."rollback"
Setting
"atEnd"
to"rollback"
causes the"runSqlStatements"
action to always roll back the results of all SQL statements. It does not matter if some complete successfully and some fail.
There are use cases in which use
"onError"
and"atEnd"
together.When prototyping code.
"onError": "continue ", "atEnd": "rollback"
Use this sample when you want all statements to run and report errors, but you do not want to commit any changes. This is useful in development when you want to try out a number of SQL statements to check their syntax, performance, and proper execution and you do not yet want to commit changes because you are still developing the code. It is convenient since it eliminates the need to drop newly created objects and delete newly inserted records.
When developing code.
"onError": "continue", "atEnd": "rollbackOnError"
Use this sample when you want all statements to run so you can see and troubleshoot all errors and you want to commit all changes, but only when all SQL statements run successfully. This is the default setting because it is good for development and is still safe when these settings are accidentally deployed to production.
When running in production and test environments.
"onError": "stop", "atEnd": "rollbackOnError"
Use this sample when you want to immediately stop running SQL statements and rollback all changes when there is an error, but you want to commit all changes when all the SQL statements run successfully. This is useful in production because you want to commit a set of successfully executed SQL statements, but when a failure occurs, you want the server to immediately stop running the remaining SQL statements and roll back all changes. Immediately stopping execution and rolling back changes prevents server resources from being consumed unnecessarily.
When deploying database changes.
"onError": "continue", "atEnd": "commit"
Use this sample when you want to unconditionally commit all SQL statements even when an error occurs on one or more statements. This is useful for deploying database changes because it is common to ignore errors during a deployment process — for example, the
DROP
table command returns an error when dropping a table that does not exist. This error does not prevent a subsequentCREATE
table from running successfully.
The "databaseName"
property is an optional string that specifies the database that contains the tables. It defaults to the database name supplied at login.
Note
In the API Explorer, "defaultDatabaseName"
is set to "ctreeSQL"
in the "createSession"
action that happens at login.
A zero-length
"databaseName"
is invalid.Its limits are from 0 to 64 bytes.
If the
"databaseName"
property is omitted or set tonull
, the server will use the default database name specified at login.If no default database is specified during
"createSession"
,"defaultDatabaseName"
will be set to the"defaultDatabaseName"
value that is specified in theservices.json
file.
The "inParams"
property is both an optional and required array of objects that specifies the values of input parameters. When optional it defaults to an empty array.
It must include one value for each input parameter in each SQL statement in the
"sqlStatements"
property.It is optional when no SQL statements have named parameters.
Note
A named parameter can be in
SELECT
andCALL
statements.It is required when one or more SQL statements have named parameters.
Example
{ "params": { "inParams": [ { "name": "inIntParam1", "value": 3 }, { "name": "inoutBinaryParam3", "value": "54657374" }, { "name": "mySqlNamedParam4", "value": "Ray" } ] } }
The "onError"
property is an optional string that determines when to stop or continue the execution of all SQL statements. It defaults to "continue"
.
Possible values:
"stop"
Setting
"onError"
to"stop"
causes the"runSqlStatements"
action to stop executing SQL statements when it encounters an error. Stopping"runSqlStatements"
on an error is useful when running subsequent steps that would cause problems or would consume server resources unnecessarily."continue"
Setting
"onError"
to"continue"
causes the"runSqlStatements"
action to continue executing SQL statements when it encounters an error. Continuing"runSqlStatements"
on even when an error occurs is useful when you want to verify the viability of each specified statement, such as ensuring it uses the correct syntax and executes properly.
There are use cases in which use
"onError"
and"atEnd"
together.When prototyping code.
"onError": "continue ", "atEnd": "rollback"
Use this sample when you want all statements to run and report errors, but you do not want to commit any changes. This is useful in development when you want to try out a number of SQL statements to check their syntax, performance, and proper execution and you do not yet want to commit changes because you are still developing the code. It is convenient since it eliminates the need to drop newly created objects and delete newly inserted records.
When developing code.
"onError": "continue", "atEnd": "rollbackOnError"
Use this sample when you want all statements to run so you can see and troubleshoot all errors and you want to commit all changes, but only when all SQL statements run successfully. This is the default setting because it is good for development and is still safe when these settings are accidentally deployed to production.
When running in production and test environments.
"onError": "stop", "atEnd": "rollbackOnError"
Use this sample when you want to immediately stop running SQL statements and rollback all changes when there is an error, but you want to commit all changes when all the SQL statements run successfully. This is useful in production because you want to commit a set of successfully executed SQL statements, but when a failure occurs, you want the server to immediately stop running the remaining SQL statements and roll back all changes. Immediately stopping execution and rolling back changes prevents server resources from being consumed unnecessarily.
When deploying database changes.
"onError": "continue", "atEnd": "commit"
Use this sample when you want to unconditionally commit all SQL statements even when an error occurs on one or more statements. This is useful for deploying database changes because it is common to ignore errors during a deployment process — for example, the
DROP
table command returns an error when dropping a table that does not exist. This error does not prevent a subsequentCREATE
table from running successfully.
The "ownerName"
property is an optional string from 1 to 64 bytes that specifies the account that owns an object.
The
"ownerName"
property is optional and has a dynamic default value.If the
"ownerName"
property is omitted or set tonull
, the server uses the value of the"defaultOwnerName"
property supplied during the "createSession"
action.If the
"defaultOwnerName"
property is not defined, the server uses the"admin"
as the owner name.The owner of an object has administrative rights over that object.
The
"ownerName"
property is a namespace for an object. You can think of it as a container of objects.The
"ownerName"
allows users to use any name for the objects they create — for example, a QA engineer may copy tables into their owner space to run a set of tests.It is common for a user to create their own copies of objects from other accounts for testing, troubleshooting, and fixing data. The copied objects can retain the same name because the
"ownerName"
distinguishes between them.The fully qualified name of an object is the
"databaseName"
,"ownerName"
, and the object's name, such as"tableName"
meaning a FairCom server may contain many tables with the name"mytable"
as long as each one is in a different database or in a different owner space.For example, an organization often creates different databases for different phases of the development lifecycle, such as dev, test, stage, ua, and prod. Each of these databases contains the same set of objects with the same names. Applications leave the
"databaseName"
out of their JSON actions and use the"defaultDatabaseName"
property to specify the target database.Queries and scripts are often written without specifying
"databaseName"
and/or"ownerName"
, allowing queries and scripts to work properly when run in different databases or in different schemas.
Properties summary
"result"
properties summaryProperty | Description | Type | Limits (inclusive) | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
contains objects that the server returns It is an empty array when there are no results available | array of objects | Its contents are determined by the action | |||||||||||
| specifies the number of records that were affected by the SQL statement | integer | |||||||||||
| indicates an error when set to a non-zero integer or success when | integer |
| ||||||||||
| displays a human-readable error message | string | 0 to 256 bytes | ||||||||||
| specifies the results returned by a stored procedure or | object | |||||||||||
| specifies an array or object that the server returns, such as records returned by a query It is an empty array when there are no results available | array | Its contents are determined by the action | ||||||||||
| specifies the format of the data in the | string |
| ||||||||||
| specifies the settings of a field in a table | array | |||||||||||
| specifies the original SQL statement that was executed | string | |||||||||||
contains the data returned by a SQL | array of objects | ||||||||||||
| specifies the number of records that were affected by the SQL statement. | integer | |||||||||||
| specifies the number of milliseconds it took for the server to execute the SQL statement | integer | |||||||||||
| indicates an error when set to a non-zero integer or success when | integer |
| ||||||||||
| displays a human-readable error message | string | 0 to 256 bytes | ||||||||||
| specifies the output values of a stored procedure | array of objects | |||||||||||
| specifies the encoding of a binary data type. It is included when the data type of the output parameters is | string | |||||||||||
| specifies the maximum possible length of the output parameter. It is included when the data type of the output parameter is |
| |||||||||||
| specifies the name of the output parameter | string | |||||||||||
| specifies the scale of the output parameter. It is included when the data type of the output parameter is | integer | |||||||||||
| specifies the JSON DB data type of the output parameter. This is useful when the value is a string containing another data type | string | |||||||||||
| specifies the value of the output parameter |
| |||||||||||
| specifies the rows returned by a stored procedure of a | object | |||||||||||
| Specifies the time at which the query was initiated | ||||||||||||
| indicates the SQL statement that is in the request to help associate each SQL statement in the request with the response. The order of the SQL statement in the request match the order in the response | array of objects |
The "data"
property contains a response message. Its contents are defined by the action. It is an empty array when no results are available.
The "reactions"
property is an array of objects that contain the data returned by a SQL SELECT
statement.
Example
"result": { "reactions": [ { "sql": "", "affectedRows": 0, "errorCode": 0, "errorMessage": "", "outParams": [], "rows": {}, "startTimestamp": "", "elapsedMilliseconds": 0 } ] }