sql scripting with advantage chris franz systems consultant / advantage evangelist may 2011

32
SQL SCRIPTING WITH ADVANTAGE CHRIS FRANZ SYSTEMS CONSULTANT / ADVANTAGE EVANGELIST MAY 2011

Post on 19-Dec-2015

216 views

Category:

Documents


1 download

TRANSCRIPT

SQL SCRIPTING WITH ADVANTAGE

CHRIS FRANZSYSTEMS CONSULTANT / ADVANTAGE EVANGELIST

MAY 2011

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;