View
216
Download
1
Embed Size (px)
Citation preview
2 – May 2011
AGENDA
• SQL script overview• Syntax• Cache• System Variables• Parameters• Stored Procedures• User Defined Functions (UDFs)
3 – May 2011
SQL SCRIPT OVERVIEW
• Benefits– Stored procedures without third-party compiler– Same stored procedure runs on all operating systems– No additional files deployed– ADS has greater controls over script-based procedures and
triggers• Drawbacks– not as versatile as non-script stored procedures
4 – May 2011
SQL SCRIPT OVERVIEW
• Subset of the ANSI SQL 2003 PSM (Persistent Stored Module)– includes variables, cursors, branches, loops and exception
handling.• Structure– Consists of one or more declare statements or a statement
block.– Script Statement Block
Consists of an assignment or if, while, cursor, try, raise, return, cache or sql statement.
script_statement ::= assignment_statement | if_statement | while_statement |cursor_statement | try_statement | raise_statement | return_statement | cache_statement | sql_statement
5 – May 2011
SYNTAX: DECLARE
• DECLARE statement is used to declare variables and cursors. – variables must be declared– variables are initialized to NULL
• A cursor may be defined with a SELECT statement or an EXECUTE PROCEDURE statement.– the statement is not executed until the cursor is opened
using the OPEN statement
6 – May 2011
DECLARING VARIABLES
• Variable and cursor names are case insensitive• Supports same data types as SQL engine except autoinc.• Also support string data type
DECLARE strLocal String;DECLARE iLocal Integer, jLocal Integer;DECLARE cLocal Char(20), Cursor1 Cursor; DECLARE Cursor2 CURSOR as SELECT * FROM employees;
OPEN Cursor2;WHILE FETCH Cursor2 DO iLocal = Cursor2.empid;END WHILE;
7 – May 2011
ASSIGNMENT
• Assigns a new value to a variableDECLARE strLocal String;DECLARE str2 String;DECLARE acVar3 Char(20), dtVal Date;
SET strLocal = 'abc';SET str2 = strLocal + 'def';acVar3 = str2 + strLocal;dtVal = (SELECT dob FROM employees WHERE empid = 1);
8 – May 2011
CONDITIONAL STATEMENTS
• Syntax– IF condition_expr THEN
statement_block [elseif_clause_list] [ELSE statement_block] END IF | END | ENDIF;DECLARE dVal Double;
dVal = 3 * Rand();IF dVal < 1 THEN SELECT * FROM employees;ELSEIF dVal < 2 THEN dVal = dVal + 3; SELECT * FROM employees WHERE empid > dVal;ELSE UPDATE employees SET empid = empid + dVal; dVal = dVal * dVal;ENDIF;
DECLARE cursor1 CURSOR AS SELECT * FROM employees;
OPEN cursor1;
IF FETCH Cursor1 THEN INSERT INTO ErrorLog ( msg ) VALUES ('employees is not empty');ENDIF;
CLOSE cursor1;
9 – May 2011
WHILE LOOPS
• Syntax–WHILE condition_expr DO
loop_statement_blockEND WHILE | END | ENDWHILE;
• Additional Commands– LEAVE: the execution of the loop_statement_block is
terminated and the execution continues on the next statement after the WHILE statement. – CONTINUE: the current iteration of the loop is terminated
and the next iteration of the loop is started by evaluating the WHILE condition.
10 – May 2011
WHILE EXAMPLE
• Example: WHILE
DECLARE i Integer;DECLARE cursor1 CURSOR AS SELECT * FROM test1;
OPEN cursor1;
WHILE FETCH cursor1 DO IF ( cursor1.val = 0 ) OR ( cursor1.val > 50 ) THEN CONTINUE; // Do not include zero in results i = 1; WHILE i <= 50 DO IF cursor1.val * i > 50 THEN LEAVE; INSERT INTO results VALUES( cursor1.val, i, cursor1.val * i ); i = i + 1; ENDWHILE; ENDWHILE;
11 – May 2011
WORKING WITH TABLES
• OPEN– cursor_statement can be specified in OPEN statement, previous OPEN statement
or declaration– on open, the record pointer is positioned before the first row– opening a cursor with a SELECT statement re-executes the statement– opening a cursor with an EXECUTE PROCEDURE statement will re-execute the
stored procedure and open the output table of the stored procedure record pointer gets positioned before the first valid row.
• CLOSE– Closes a cursor and allows it to be reopened
• FETCH– Scrolls the cursor forward one row. NOTE: does not throw an error after last row
12 – May 2011
EXECUTE IMMEDIATECREATE PROCEDURE AddAutoInc( tblName cichar(20), colName cichar(20))BEGIN DECLARE col cursor, __input CURSOR as SELECT * FROM __input; DECLARE stmt string;
OPEN __input; FETCH __input;
// Check to see if the column already exists OPEN col as SELECT * FROM system.columns WHERE parent = __input.tblName AND name = __input.colName; IF FETCH col THEN // already exists ELSE // column does not exists, add it // Construct the ALTER TABLE statement stmt = 'ALTER TABLE ' + __input.tblName + ' ADD ' + __input.colName + ' autoinc '; EXECUTE IMMEDIATE stmt; END IF;
CLOSE col; CLOSE __input; END;
13 – May 2011
ERROR HANDLING
• Syntax– TRY
statement_block [catch_clauses] [catchall_clause] [finally_clause] END TRY | END | ENDTRY;
• TRY construct for handling exceptions raised intentionally or not intentionally– If no exception in statement block, execution moves to
finally – If exception, execution moves to CATCH or CATCHALL
clause
14 – May 2011
EXCEPTIONS
• Handling Exceptions– if exception, __errcode and __errclass and __errtext are set.– execution moves to catch_clause– CATCH error_class clause is examined for match– execution moves to finally_clause (if exists)– catch_all clause can be used to handle all exceptions.
15 – May 2011
EXCEPTION HANDLING EXAMPLE
TRY CREATE TABLE #Test( id integer, name char( 20 ) );CATCH ADS_SCRIPT_EXCEPTION // Only do something if the error code indicates // table already exists IF __errcode = 2010 THEN DROP TABLE #Test; CREATE TABLE #Test( id integer, name char( 20 ) ); ELSE RAISE; // re-raise the exception END IF;END TRY;
16 – May 2011
RAISE
• Syntax– RAISE [ exception ];exception ::= identifier ( integer_expr,
char_expr )• Behavior– RAISE statement raises an exception and execution jumps to
catch or catch_all clause.– A RAISE statement without the optional exception
specification re-raises an existing exception and it is only valid in the CATCH clause. – Identifier, integer_expr and char_expr values in the
exception specification will be assigned to the __errclass, __errcode, and __errtext
17 – May 2011
RETURN
• RETURN– The RETURN statement terminates the execution of the
current script. • ExampleDECLARE cursor1 AS SELECT * FROM #Inpupt;
TRY OPEN cursor1;CATCHALL RETURN;END TRY;
18 – May 2011
MERGE STATEMENT
• Syntax–MERGE [INTO] <tableref> [USING <tableref>] ON <search-
condition> <WHEN MATCHED THEN <update specification> | <WHEN NOT MATCHED THEN <insert specification>
• Behavior– Attempts to update matched records using the <update
specification> and inserts unmatched records using the <insert specification>– For best performance ensure search condition is fully
optimized
19 – May 2011
MERGE EXAMPLE
MERGE Emp e1 USING Employees e2ON (e1.ID = e2.ID)WHEN MATCHED THEN UPDATE SET e1.SSN = e2.SSN, e1.LastName = e2.LastName, e1.FirstName = e2.FirstNameWHEN NOT MATCHED THEN INSERT (ID, SSN, LastName, FirstName)
VALUES (e2.ID, e2.SSN, e2.LastName, e2.FirstName)
20 – May 2011
CACHING
• Syntax– CACHE PREPARE ON | OFF | DEFAULT;
• Sets Caching for semantic information– improves performance if statements are repeatedly
executed (WHILE loop)– drawbacks
tables opened by cached statements are not closed The cached semantic information about string variables may cause string
concatenation errors if the size of the string variable increases.
strVal = 'abc'; CACHE PREPARE ON; WHILE strVal <>'abcddd' DO StrVal = strVal + 'd'; END WHILE; CACHE PREPARE DEFAULT;
21 – May 2011
CACHE BEHAVIOR
• Behavior– ON – The semantic information of the script statements is always cached. – OFF – The semantic information of the script statements is never cached. After
executing a script statement, the semantic information of the statement is freed immediately.
– DEFAULT – This is the default cache setting of the script engine. The semantic information of the script statements is cached only if the semantic information does not hold any table open and if no string variable is used in the script statement.
• Exceptions– CACHE PREPARE ON – If a cursor is re-opened with a different cursor statement,
the semantic information of the previous open will be discarded.
• Demo
23 – May 2011
SYSTEM VARIABLES
• __errclass String• __errorcode Integer• __errtext String
• Properties– Cannot be assigned directly– Initialized with RAISE statement– Runtime errors initialize _errclass with “ADS_SCRIPT_EXCEPTION”
24 – May 2011
SYSTEM VARIABLES
• Connection (::conn)– Name: current user connection unique name– Collation: default collation for the statements – Transactioncount: nesting level of the transaction
• Statement (::stmt)– UpdateCount: the number of rows affected since the
beginning of the current execution– TrigRecNo: record number of the row that fired the trigger– Collation default collation for the statement
• Example syntax– ::conn.Name– ::stmt.TrigRecNo
25 – May 2011
PARAMETERS
• Usage– using parameters in an SQL script is only supported when
the parameters are used in regular SQL DDL or DML statements.
DECLARE i Integer;i = ( SELECT id FROM #input );IF i = 1 THEN INSERT INTO table1 Values( :val1, :val2 );ELSE UPDATE table1 SET name = :val3 WHERE id = :val4;END;
26 – May 2011
PARAMETERS
• Unsupported usage of a parameter in a scriptDECLARE strName String;
strName = (SELECT name FROM table1 WHERE id=:id );
• Getting parameter value in the variablesDECLARE strName String;
CREATE TABLE #temp ( name memo );TRY
INSERT INTO #temp SELECT name FROM table1 WHERE id = :id;
StrName = (SELECT name FROM #temp);FINALLY
DROP TABLE #temp;END TRY;
27 – May 2011
PARAMETERS
• Support for Unnamed Parameters– INSERT INTO #temp SELECT name FROM table1
WHERE id = ?;• Parameters Are Not Allowed In– Cursor Definitions– Text of EXECUTE IMMEDIATE statements
28 – May 2011
STORED PROCEDURES
• Input parameters are accessed through __input• Output parameters are returned through __output
CREATE PROCEDURE testproc( str char( 20 ), len integer, strResult memo OUTPUT ) BEGIN DECLARE strVal String, len Integer; strVal = ( SELECT trim( str ) FROM __input ); len = ( SELECT len FROM __input ); WHILE length( strVal ) < len DO strVal = strVal + strVal; END WHILE; INSERT INTO __output VALUES ( strVal ); END
29 – May 2011
USER DEFINED FUNCTIONS
• Requirements– Defined within a data dictionary–Must return one variable–Written as an SQL script
• Limitations–Only available when connected to dictionary– Can only return a single value– Cannot define aggrigate functions
30 – May 2011
CREATING A UDF
• GUI Available in ARC• Use of the CREATE FUNCTION SQL Statement• Can be Defined Inside a Package– Allows for logical grouping of functions– Function will be called with dot notation (i.e.
package.function)
31 – May 2011
EXAMPLES
• Simple Function to Concatenate a NameCREATE FUNCTION FullName( Last CHAR(25), First CHAR(25)) RETURNS CHAR(80) BEGIN RETURN Trim(Last) + ', ' + Trim(First); END;
• Supports RecursionCREATE FUNCTION MyMath.Factorial( num integer ) RETURNS IntegerBEGIN IF num = 0 THEN RETURN 1; ELSE RETURN num * MyMath.Factorial( num - 1 ); END IF;END;
32 – May 2011
BITWISE OPERATORS
• Supported Operators– AND ( & )–OR ( | )– XOR ( ^ )– NOT ( ~ )– SHIFT LEFT ( << )– SHIFT RIGHT ( >> )
DECLARE @Test INTEGER;SET @Test = 12;
IF ( @Test & 8 ) = 8 THEN RETURN “Third bit is set”;END IF;