SQL Procedural Conditional Statements
NuoDB SQL supports the following conditional SQL statements for use in SQL stored procedures, user defined functions (UDFs), or trigger.
Syntax
IF ( sql_boolean_expression | sql_query_statement )
sql_code_block
[ ELSE sql_code_block ]
END_IF;
WHILE ( sql_boolean_expression | sql_query_statement )
sql_code_block
END_WHILE;
TRY sql_code_block
CATCH(error_variable)
sql_code_block
END_TRY;
[ [ VAR ] var_name var_type [ , var_name var_type ]... = ]
CASE input_expression
WHEN (when_expression) THEN result_expression
[ WHEN (when_expression) THEN result_expression ]...
[ ELSE result_expression ]
END;
Description
An IF
statement evaluates the results from the sql_boolean_expression
or the boolean result returned from the sql_query_statement
and if true, transfers control to the next sql_code_block
or if false, transfers control to the sql_code_block
following the ELSE
keyword.
A WHILE
statement evaluates the results from the sql_boolean_expression
or the boolean result returned from the sql_query_statement
and executes the following sql_code_block
until the time at which the boolean WHILE
condition evaluates to false.
The TRY
statement executes the following sql_code_block
and if an error is thrown, the name of the error condition is assigned to error_variable
for reporting purposes, and execution continues with the sql_code_block
following the CATCH
keyword.
The CASE
statement takes as an input_expression
a valid SQL expression that can be compared to the following series of WHEN
expressions. If the input_expression
is equal to one of the specified WHEN
expressions (when_expression
) then the result_expression
following its THEN
keyword will be executed. If the input_expression
is not equal to any of the specified WHEN
expressions, then if an ELSE
expression is specified, its result_expression
is executed.
The CASE
statement will return the value of the evaluated result_expression
and this can be assigned to one or more variables. See Example 4.
Parameters
sql_boolean_expression
-
A valid SQL expression that results in true or false.
sql_query_statement
-
A string representing a valid SQL query statement that results in a boolean true or false value. Any SQL query that returns a non-empty result set, evaluates as true. See
SELECT
for syntax of a validSELECT
statement. . error_variable
-
A variable to which the error incurred in a
TRY
/CATCH
block is assigned. input_expression
-
In a
CASE
statement, a valid SQL expression that can be compared towhen_expression
and may or may not be assigned one of the specifiedresult_expression
s. when_expression
-
In a
CASE
statement, a valid SQL expression to be compared withinput_expression
. result_expression
-
In a
CASE
statement, a valid SQL expression that can be assigned toinput_expression
, when the correspondingwhen_expression
evaluates equally.
Examples
- Example 1: Using a
WHILE
loop within a stored procedure -
The
FOR SELECT
statement needs to provide an alias, usingAS
, for the playerid column. This is necessary because the variable playerid, which is returned from theFOR SELECT
statement, is being used in theSELECT
statement of theINSERT
statement inside theFOR SELECT
loop. Without this alias name, theSELECT
statement inside theINSERT
statement would treat playerid as a column in one of the tables being selected from. And in this case, since both the scoring table and the players table contains a column named playerid, an ambiguous column error would result.SET DELIMITER @ CREATE PROCEDURE prc_player_teams (in_lastname STRING) /* IN is implied */ RETURNS team_tab (player_name STRING ,year INTEGER ,stint INTEGER ,team_name STRING ,conf_div STRING ,rank INTEGER ,record STRING) AS FOR SELECT p1.playerid AS P1_PLAYER_ID ,p1.firstnhl ,p1.lastnhl FROM hockey.players p1 WHERE UPPER(p1.LASTNAME) LIKE UPPER(in_lastname)||'%'; VAR v_nhlyear INTEGER = firstnhl; WHILE (v_nhlyear < lastnhl) INSERT INTO team_tab SELECT p.firstname||' '||p.lastname ,s.year ,s.stint ,t.name ,conferenceid||' '||divisionid ,t.rank ,wins||'-'||losses||'-'||ties FROM hockey.players p JOIN hockey.scoring s ON s.playerid = p.playerid JOIN hockey.teams t ON t.teamid = s.teamid WHERE p.playerid = P1_PLAYER_ID AND p.playerid = s.playerid AND s.teamid = t.teamid AND s.year = v_nhlyear AND t.year = v_nhlyear ORDER BY p.lastname,s.year,s.stint; v_nhlyear=v_nhlyear +1; END_while; END_FOR; END_PROCEDURE @ SET DELIMITER ; CALL prc_player_teams('Arnason'); PLAYER_NAME YEAR STINT TEAM_NAME CONF_DIV RANK RECORD ------------- ----- ------ --------------------- --------- ----- -------- Chuck Arnason 1971 1 Montreal Canadiens 0 ED 3 46-16-16 Chuck Arnason 1972 1 Montreal Canadiens 0 ED 1 52-10-16 Chuck Arnason 1973 1 Atlanta Flames 0 WD 4 30-34-14 Chuck Arnason 1973 2 Pittsburgh Penguins 0 WD 5 28-41-9 Chuck Arnason 1974 1 Pittsburgh Penguins WA NO 3 37-28-15 Chuck Arnason 1975 1 Pittsburgh Penguins WA NO 3 35-33-12 Chuck Arnason 1975 2 Kansas City Scouts CC SM 5 12-56-12 Chuck Arnason 1976 1 Colorado Rockies CC SM 5 20-46-14 Chuck Arnason 1977 1 Colorado Rockies CC SM 2 19-40-21 Chuck Arnason 1977 2 Cleveland Barons WA AD 4 22-45-13 Chuck Arnason 1978 1 Minnesota North Stars WA AD 4 28-40-12 Chuck Arnason 1978 2 Washington Capitals WA NO 4 24-41-15 Tyler Arnason 2001 1 Chicago Blackhawks WC CE 3 41-27-13 Tyler Arnason 2002 1 Chicago Blackhawks WC CE 3 30-33-13 Tyler Arnason 2003 1 Chicago Blackhawks WC CE 5 20-43-11 Tyler Arnason 2005 1 Chicago Blackhawks WC CE 4 26-43-0 Tyler Arnason 2005 2 Ottawa Senators EC NE 1 52-21-0 Tyler Arnason 2006 1 Colorado Avalanche WC NW 4 44-31-0 Tyler Arnason 2007 1 Colorado Avalanche WC NW 2 44-31-0 Tyler Arnason 2008 1 Colorado Avalanche WC NW 5 32-45-0
- Example 2: Using
TRY/CATCH
to execute a test statement and handle errors -
In the following examples, for the last execution of the stored procedure, the TRY
statement will successfully insert the row into the table, which means theCATCH
statement does not execute. However, since statements executed from inside a stored procedure are executed as a single transaction, by default, theTHROW
statement will cause the inserted row to be rolled back.DROP PROCEDURE IF EXISTS prc_hockey_create; SET DELIMITER @ CREATE PROCEDURE prc_hockey_create (inNum STRING , inName STRING , inPos STRING , inTeam STRING) RETURNS trace (log STRING,num STRING,name STRING) AS TRY INSERT INTO HOCKEY (number,name,position,team) VALUES (inNum, inName, inPos, inTeam); CATCH(error) INSERT INTO trace VALUES (error, inNum,inName); RETURN ; END_TRY; THROW 'record valid for insert'; END_PROCEDURE @ SET DELIMITER ; CALL prc_hockey_create('abc','Tom Jones','Goalie','Bruins'); LOG NUM NAME -------------------------------------------------- ---- --------- unable to convert string "abc" into type "integer" abc Tom Jones `` CALL prc_hockey_create('40','TUUKKA RASK','Goalie','Bruins');`` LOG NUM NAME --------------------------------------------------------------------------- ---- ----------- duplicate value in unique index PLAYER_IDX, key = '40, TUUKKA RASK, Bruins' 40 TUUKKA RASK CALL prc_hockey_create('99','Tom Jones','Goalie','Bruins'); Procedure HOCKEY.PRC_HOCKEY_CREATE, record valid for insert
- Example 3: Using
TRY/CATCH
to control error handling and continue processing -
In this example we have data loaded into a staging table. We want to validate the data and only load rows that are valid into the permanent table.
If a row is not valid, we want to log it to the error logging table with the error.DROP PROCEDURE IF EXISTS prc_insert_validate; DROP TABLE IF EXISTS error_log; DROP TABLE IF EXISTS perm_tbl; DROP TABLE IF EXISTS stage_tbl; CREATE TABLE error_log (error_msg string ,record string); CREATE TABLE perm_tbl (id integer not null primary key generated always as identity , name string , City string , state string CHECK (state = 'MA')); CREATE UNIQUE INDEX idx_unique_perm_tbl_name ON perm_tbl(name); INSERT INTO perm_tbl (name, city, state) VALUES ('Mary Doe','Boston', 'MA'); CREATE TABLE stage_tbl ( name string , City string , state string); INSERT INTO stage_tbl (name, city, state) VALUES ('Tom Jones','Any City', 'USA'),('Bob Smith','Cambridge', 'MA'), ('Mary Doe','Boston', 'MA'),('Thomas Brady','Foxboro', 'MA'); SET DELIMITER @ CREATE PROCEDURE prc_insert_validate () AS VAR v_name string; VAR v_city string; VAR v_state string; FOR SELECT name, city, state FROM stage_tbl; v_name = name; v_city = city; v_state = state; TRY INSERT INTO perm_tbl (name, city, state) VALUES (v_name, v_city, v_state); CATCH(error) INSERT INTO error_log VALUES (error, 'record: '||v_name||' '||v_city||' '||v_state); END_TRY; END_FOR; END_PROCEDURE @ SET DELIMITER ; CALL prc_insert_validate; SELECT * FROM perm_tbl; ID NAME CITY STATE --- ------------ --------- ------ 1 Mary Doe Boston MA 3 Bob Smith Cambridge MA 5 Thomas Brady Foxboro MA SELECT * FROM error_log; ERROR_MSG RECORD -------------------------------------------------------------------------- ------------------------------ violation of constraint "STATE" record: Tom Jones Any City USA duplicate value in unique index IDX_UNIQUE_PERM_TBL_NAME, key = 'Mary Doe' record: Mary Doe Boston MA
- Example 4: Using
CASE
statement within a stored procedure -
SET DELIMITER @ CREATE PROCEDURE get_stats(IN in_stat STRING, IN in_year INTEGER, IN in_teamid STRING, OUT out_stat1 STRING, OUT out_stat2 STRING, OUT out_stat3 STRING) AS out_stat1,out_stat2,out_stat3 = CASE in_stat WHEN 'Conference' THEN (SELECT conferenceid, divisionid, rank FROM hockey.teams WHERE year = in_year AND teamid = in_teamid) WHEN 'Record' THEN (SELECT wins, losses, ties FROM hockey.teams WHERE year = in_year AND teamid = in_teamid) END; END_PROCEDURE @ CREATE PROCEDURE get_team_stats(IN in_stat STRING, IN in_year INTEGER, IN in_teamid STRING) AS VAR out1 STRING, out2 STRING, out3 STRING; EXECUTE get_stats(in_stat,in_year,in_teamid,out1,out2,out3); VAR display_out STRING; display_out= CASE in_stat WHEN 'Conference' THEN 'Conference='||out1||' Division='||out2||' Rank='||out3 WHEN 'Record' THEN 'Wins='||out1||' Loses='||out2||' Ties='||out3 END; THROW display_out; END_PROCEDURE @ SET DELIMITER ; EXECUTE get_team_stats('Conference',2011,'BOS'); Procedure HOCKEY.GET_TEAM_STATS, Conference=EC Division=NE Rank=1 EXECUTE get_team_stats('Record',2011,'BOS'); Procedure HOCKEY.GET_TEAM_STATS, Wins=49 Loses=29 Ties=0