| --- |
| layout: global |
| title: SQL Scripting |
| displayTitle: SQL Scripting |
| license: | |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --- |
| |
| You can employ powerful procedural logic using SQL/PSM standard-based scripting syntax. |
| Any SQL script consists of and starts with a [compound statement](control-flow/compound-stmt.html) block (`BEGIN ... END`). |
| A compound statement starts with a section to declare local variables, cursors, user-defined conditions, and condition handlers, which are used to catch exceptions. |
| This is followed by the compound statement body, which consists of: |
| |
| - Flow control statements include loops over predicate expressions, [FOR](control-flow/for-stmt.html) loops over query results, conditional logic such as [IF](control-flow/if-stmt.html) and [CASE](control-flow/case-stmt.html), and means to break out loops such as [LEAVE](control-flow/leave-stmt.html) and [ITERATE](control-flow/iterate-stmt.html). |
| - DDL statements such as `ALTER`, `CREATE`, `DROP`. |
| - DML statements [INSERT](sql-ref-syntax-dml-insert-table.html). |
| - [Queries](sql-ref-syntax-qry-select.html) that return result sets to the invoker of the script. |
| - [SET](sql-ref-syntax-aux-set-var.html) statements to set local variables as well as session variables. |
| - The [EXECUTE IMMEDIATE](sql-ref-syntax-aux-exec-imm.html) statement. |
| - Cursor processing with [OPEN](control-flow/open-stmt.html), [FETCH](control-flow/fetch-stmt.html), and [CLOSE](control-flow/close-stmt.html) statements. |
| - Nested compound statements, which provide nested scopes for variables, cursors, conditions, and condition handlers. |
| |
| ## Passing data between the invoker and the compound statement |
| |
| There are two ways to pass data to and from a SQL script: |
| |
| - Use session variables to pass scalar values or small sets of arrays or maps from one SQL script to another. |
| - Use parameter markers to pass scalar values or small sets of arrays or map data from a notebook widget, Python, or another language to the SQL Script. |
| |
| ## Variable and cursor scoping |
| |
| Variables declared within a compound statement can be referenced in any expression within a compound statement. |
| Spark resolves identifiers from the innermost scope outward, following the rules described in [Name Resolution](sql-ref-name-resolution.html). |
| You can use the optional compound statement labels to disambiguate duplicate variable names. |
| |
| Cursors declared within a compound statement can be referenced in `OPEN`, `FETCH`, and `CLOSE` statements within that compound statement. |
| Like variables, you can use optional compound statement labels to disambiguate duplicate cursor names in nested scopes. |
| |
| ## Condition handling |
| |
| SQL Scripting supports condition handlers, which are used to intercept and process exceptions to either `EXIT` the compound statement or `CONTINUE` execution. |
| |
| Condition handlers can be defined to handle three distinct classes of conditions: |
| |
| - One or more named conditions that can be a specific Spark-defined error class such as `DIVIDE_BY_ZERO` or a user-declared condition. |
| These handlers handle these specific conditions. |
| |
| - One or more `SQLSTATE`s, that can be raised by Spark. |
| These handlers can handle any condition associated with that `SQLSTATE`. |
| |
| - A generic `SQLEXCEPTION` handler can catch all conditions falling into the `SQLEXCEPTION` (any `SQLSTATE` which is not `XX***` and not `02***`). |
| |
| - A `NOT FOUND` handler catches all conditions with SQLSTATE class `'02xxx'`, which includes the `CURSOR_NO_MORE_ROWS` condition raised when fetching beyond the end of a cursor's result set. |
| |
| The following are used to decide which condition handler applies to an exception. |
| This condition handler is called the **most appropriate handler**: |
| |
| - A condition handler cannot apply to any statement defined in its own body or the body of any condition handler declared in the same compound statement. |
| |
| - The applicable condition handlers defined in the innermost compound statement within which the exception was raised are appropriate. |
| |
| - If more than one appropriate handler is available, the most specific handler is the most appropriate. |
| For example, a handler on a named condition is more specific than one on a named `SQLSTATE`. |
| A generic `EXCEPTION` handler is the least specific. |
| |
| The outcome of a condition handler is as follows: |
| |
| - An `EXIT` handler executes its statement, then exits the compound statement that declared the handler. All cursors opened within that compound statement and nested compound statements are implicitly closed. |
| |
| - A `CONTINUE` handler executes its statement, then continues execution with the statement following the one that raised the condition. |
| |
| The following is a list of supported control flow statements: |
| |
| * [CASE](control-flow/case-stmt.html) |
| * [compound statement](control-flow/compound-stmt.html) |
| * [FOR](control-flow/for-stmt.html) |
| * [IF](control-flow/if-stmt.html) |
| * [ITERATE](control-flow/iterate-stmt.html) |
| * [LEAVE](control-flow/leave-stmt.html) |
| * [LOOP](control-flow/loop-stmt.html) |
| * [REPEAT](control-flow/repeat-stmt.html) |
| * [WHILE](control-flow/while-stmt.html) |
| |
| The following is a list of cursor statements: |
| |
| * [OPEN](control-flow/open-stmt.html) |
| * [FETCH](control-flow/fetch-stmt.html) |
| * [CLOSE](control-flow/close-stmt.html) |