The control-of-flow language controls the flow of execution of SQL statements, statement blocks, and stored procedures. PL/SQL and Transact-SQL provide many of the same constructs, although there are some syntax differences.
These are the keywords supported by each RDBMS.
Statement |
Oracle PL/SQL |
Microsoft SQL Server Transact-SQL |
---|---|---|
Declare variables | DECLARE | DECLARE |
Statement block | BEGIN...END; | BEGIN...END |
Conditional processing | IF…THEN, ELSIF…THEN, ELSE ENDIF; |
IF…[BEGIN…END] ELSE <condition> [BEGIN…END] ELSE IF <condition> CASE expression |
Unconditional exit | RETURN | RETURN |
Unconditional exit to the statement following the end of the current program block | EXIT | BREAK |
Restarts a WHILE loop | N/A | CONTINUE |
Wait for a specified interval | N/A (dbms_lock.sleep) | WAITFOR |
Loop control | WHILE LOOP…END LOOP;
|
WHILE <condition> BEGIN… END LABEL…GOTO LABEL |
Program comments | /* … */, -- | /* … */, -- |
Print output | RDBMS_OUTPUT.PUT_ LINE |
|
Raise program error | RAISE_APPLICATION_ ERROR |
RAISERROR |
Execute program | EXECUTE | EXECUTE |
Statement terminator | Semicolon (;) | N/A |
Transact-SQL and PL/SQL variables are created with the DECLARE keyword. Transact-SQL variables are identified with @) and, like PL/SQL variables, are initialized to a null value when they are first created.
Oracle | Microsoft SQL Server |
---|---|
DECLARE VSSN CHAR(9); VFNAME VARCHAR2(12); VLNAME VARCHAR2(20); VBIRTH_DATE DATE; VLOAN_AMOUNT NUMBER(12,2); |
DECLARE @VSSN CHAR(9), @VFNAME VARCHAR2(12), @VLNAME VARCHAR2(20), @VBIRTH_DATE DATETIME, @VLOAN_AMOUNT NUMERIC(12,2) |
Transact-SQL does not support the %TYPE and %ROWTYPE variable data type definitions. A Transact-SQL variable cannot be initialized in the DECLARE command. The Oracle NOT NULL and CONSTANT keywords cannot be used in Microsoft SQL Server data type definitions.
Like Oracle LONG and LONG RAW data types, text and image data types cannot be used for variable declarations. Additionally, the PL/SQL style record and table definitions are not supported.
Oracle and Microsoft SQL Server offer these ways to assign values to local variables.
Oracle | Microsoft SQL Server |
---|---|
Assignment operator (:=) | SET @local_variable = value |
SELECT...INTO syntax for selecting column values from a single row | SELECT @local_variable = expression [FROM…] for assigning a literal value, an expression involving other local variables, or a column value from a single row |
FETCH…INTO syntax | FETCH…INTO syntax |
Here are some syntax examples.
Oracle | Microsoft SQL Server |
---|---|
DECLARE VSSN CHAR(9); VFNAME VARCHAR2(12); VLNAME VARCHAR2(20); BEGIN VSSN := '123448887'; SELECT FNAME, LNAME INTO VFNAME, VLNAME FROM STUDENTS WHERE SSN=VSSN; END; |
DECLARE @VSSN CHAR(9), @VFNAME VARCHAR(12), @VLNAME VARCHAR(20) SET @VSSN = '12355887' SELECT @VFNAME=FNAME, @VLNAME=LNAME FROM STUDENTS WHERE SSN = @VSSN |
Oracle PL/SQL and Microsoft SQL Server Transact-SQL support the use of BEGIN…END terminology to specify statement blocks. Transact-SQL does not require the use of a statement block following the DECLARE statement. The BEGIN…END statement blocks are required in Microsoft SQL Server for IF statements and WHILE loops if more than one statement is executed.
Oracle | Microsoft SQL Server |
---|---|
DECLARE DECLARE VARIABLES ... BEGIN -- THIS IS REQUIRED SYNTAX PROGRAM_STATEMENTS ... IF ...THEN STATEMENT1; STATEMENT2; STATEMENTN; END IF; WHILE ... LOOP STATEMENT1; STATEMENT2; STATEMENTN; END LOOP; END; -- THIS IS REQUIRED SYNTAX |
DECLARE DECLARE VARIABLES ... BEGIN -- THIS IS OPTIONAL SYNTAX PROGRAM_STATEMENTS ... IF ... BEGIN STATEMENT1 STATEMENT2 STATEMENTN END WHILE ... BEGIN STATEMENT1 STATEMENT2 STATEMENTN END END -- THIS IS REQUIRED SYNTAX |
The Microsoft SQL Server Transact-SQL conditional statement includes IF and ELSE rather than the ELSIF statement in Oracle PL/SQL. Multiple IF statements can be nested to achieve the same effect. For extensive conditional tests, the CASE expression may be easier to read.
Oracle | Microsoft SQL Server |
---|---|
DECLARE VDEGREE_PROGRAM CHAR(1); VDEGREE_PROGRAM_NAME VARCHAR2(20); BEGIN VDEGREE_PROGRAM := 'U'; IF VDEGREE_PROGRAM = 'U' THEN VDEGREE_PROGRAM_NAME := 'Undergraduate'; ELSIF VDEGREE_PROGRAM = 'M' THEN VDEGREE_PROGRAM_ NAME := 'Masters'; ELSIF VDEGREE_PROGRAM = 'P' THEN VDEGREE_PROGRAM_ NAME := 'PhD'; ELSE VDEGREE_PROGRAM_ NAME := 'Unknown'; END IF; END; |
DECLARE @VDEGREE_PROGRAM CHAR(1), @VDEGREE_PROGRAM_NAME VARCHAR(20) SELECT @VDEGREE_PROGRAM = 'U' SELECT @VDEGREE_PROGRAM_ NAME = CASE @VDEGREE_PROGRAM WHEN 'U' THEN 'Undergraduate' WHEN 'M' THEN 'Masters' WHEN 'P' THEN 'PhD'. ELSE 'Unknown' END |
Oracle PL/SQL provides the unconditional LOOP and FOR LOOP. Transact-SQL offers the WHILE loop and the GOTO statement for looping purposes.
WHILE Boolean_expression
{sql_statement | statement_block}
[BREAK] [CONTINUE]
The WHILE loop tests a Boolean expression for the repeated execution of one or more statements. The statement(s) are executed repeatedly as long as the specified expression evaluates to TRUE. If multiple statements are to be executed, they must be placed within a BEGIN…END block.
Oracle | Microsoft SQL Server |
---|---|
DECLARE COUNTER NUMBER; BEGIN COUNTER := 0 WHILE (COUNTER <5) LOOP COUNTER := COUNTER + 1; END LOOP; END; |
DECLARE @COUNTER NUMERIC SELECT@COUNTER = 1 WHILE (@COUNTER <5) BEGIN SELECT @COUNTER = @COUNTER +1 END |
Statement execution can be controlled from inside the loop with the BREAK and CONTINUE keywords. The BREAK keyword causes an unconditional exit from the WHILE loop, and the CONTINUE keyword causes the WHILE loop to restart, skipping any statements that follow. The BREAK keyword is equivalent to the Oracle PL/SQL EXIT keyword. Oracle does not have an equivalent to CONTINUE.
Both Oracle and Microsoft SQL Server have GOTO statements, with different syntax. The GOTO statement causes the execution of a Transact-SQL batch to jump to a label. None of the statements between the GOTO statement and the label are executed.
Oracle | Microsoft SQL Server |
---|---|
GOTO label; <<label name here>> |
GOTO label |
The Transact-SQL PRINT statement performs the same operation as the PL/SQL RDBMS_OUTPUT.put_line procedure. It is used for printing user-specified messages.
The message limit for the PRINT statement is 8,000 characters. Variables that are defined using the char or varchar data type can be embedded in the printed statement. If any other data type is used, the CONVERT or CAST function must be used. Local variables, global variables, and text can be printed. Both single and double quotation marks can be used to enclose text.
Both Microsoft SQL Server and Oracle have RETURN statements. RETURN lets your program exit unconditionally from a query or procedure. RETURN is immediate and complete and can be used at any point to exit from a procedure, batch, or statement block. Statements following RETURN are not executed.
Oracle | Microsoft SQL Server |
---|---|
RETURN expression: | RETURN [integer_expression] |
The Transact-SQL RAISERROR statement returns a user-defined error message and sets a system flag to record that an error has occurred. It is similar in function to the PL/SQL raise_application_error exception handler.
The RAISERROR statement allows the client to retrieve an entry from the sysmessages table or build a message dynamically with user-specified severity and state information. When defined, this message is sent back to the client as a server error message.
RAISERROR ({msg_id | msg_str}, severity, state
[, argument1 [, argument2]])
[WITH options]
When converting your PL/SQL programs, it may not be necessary to use the RAISERROR statement. In the following code example, the PL/SQL program uses the raise_application_error exception handler, while the Transact-SQL program uses nothing. The raise_application_error exception handler has been included to prevent the PL/SQL program from possibly returning an ambiguous unhandled exception error message. Instead, it always returns the Oracle error message (SQLERRM) when an unanticipated problem occurs.
When a Transact-SQL program fails, it always returns a detailed error message to the client program. Therefore, unless some specialized error handling is required, the RAISERROR statement is not always needed.
Oracle | Microsoft SQL Server |
---|---|
CREATE OR REPLACE FUNCTION DEPT_ADMIN.DELETE_DEPT (VDEPT IN VARCHAR2) RETURN NUMBER AS BEGIN DELETE FROM DEPT_ADMIN.DEPT WHERE DEPT = VDEPT; RETURN(SQL%ROWCOUNT); EXCEPTION WHEN OTHER THEN RAISE_APPLICATION_ERROR (-20001,SQLERRM); END DELETE_DEPT; / |
CREATE PROCEDURE DEPT_ADMIN.DELETE_DEPT @VDEPT VARCHAR(4) AS DELETE FROM DEPT_DB.DBO.DEPT WHERE DEPT = @VDEPT RETURN @@ROWCOUNT GO |