tips tricks and little known features in sap ase
TRANSCRIPT
ISUG-TECH 2014
Conference
Presenter’s Session Title here
Presenter’s name
ISUG-TECH 2015
Conference
Tips, Tricks & Little-Known Features in SAP ASE
Rob VerschoorVP, Global DBMS Migration Lead , Platform Solutions Group
(c) 2015 Independent SAP Technical User GroupAnnual Conference, 2015
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 2
Agenda
Lots of miscellaneous features!
Q&A
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 3
sp_addtype limit
• Let's say you want to use the same datatype across your stored procedures for variables
and parameters, for example VARCHAR(10000)
• but not necessarily use this in table columns
• Solution: define a user-defined datatype: sp_addtype 'mytype', 'varchar(10000)'
• However:
1> sp_addtype 'varchar_max', 'varchar(10000)' -- on 2KB server
2> go
Msg 17308, Level 16, State 1
Server 'SYB15_2K', Procedure 'sp_addtype', Line 640
Illegal length specified -- must be between 1 and 2048.
1> sp_addtype 'varchar_max', 'varchar(10000)' -- on 8KB server
2> go
Msg 17308, Level 16, State 1
Server 'SYB15_8K', Procedure 'sp_addtype', Line 640
Illegal length specified -- must be between 1 and 8192.
• This restriction was meaningless and was removed in 15.7 SP121
• New variable @@maxvarlen contains maximum allowed length of variable
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 4
SELECT…WITH RECOMPILE
• Sometimes, you want to force a query plan always to be recompiled.
• Classic solution: sp_recompile for a table referenced in the query
• Downside: affects plans for all other statements referencing this table
• Classic solution: execute or declare the stored proc WITH RECOMPILE
• Downside: affects plans for all statements in the procedure
• Newer solution: EXECUTE('SELECT * FROM …')
• Downside: code becomes more complex; not possible if exec-imm already used
higher up
• Newest solution (15.7 SP130, 16.0 SP01):
SELECT * FROM … WITH RECOMPILE
• Affects only this particular statement
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 5
SELECT-INTO inside transaction
• A long-standing restriction:
1> begin tran
2> select * into #t from mytable
3> go
Msg 226, Level 16, State 1
Server 'SYB160', Line 2
SELECT INTO command not allowed within multi-statement
transaction.
• Similar issues:
• SELECT-INTO in a trigger
• CREATE/DROP TABLE in a trigger
• Setting the 'ddl in tran' database option does not affect this!
• Solution in 16.0PL05: new config option 'enable select into in tran' , set to 1
• Also, 'ddl in tran' now allows CREATE/DROP table in a trigger when new config opt = 1
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 6
LPAD() & RPAD()
• Padding functions LPAD() and RPAD() added in 15.7 SP130 & 16.0 SP01:
1> select lpad('abc', 6, 'x')
2> go
------
xxxabc
1> select rpad('abc', 4, 'x')
2> go
----
abcx
No longer needed to left-pad a number with zeroes:
select right(replicate('0',8) + convert(varchar,123), 8)
now use: lpad(123,8,'0')
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 7
Nested BIF limit
select isnull(
isnull(sign(
isnull(sign(
isnull(sign(
isnull(sign(
isnull(sign(1),1)),1)),1)),1)),1),1)
Result:
Msg 175, Level 15, State 1
Server 'SYB157', Line 1
Functions may only be nested to level 10.
• This is a hard limit, not configurable
In 15.7 SP 110, the BIF nesting limit was raised from 10 to 32 (still not configurable)
In 16.0 SP02, the BIF nesting limit will be raised from 256
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 8
Order-By enhancements
• Q: How many 'sort columns' can there be in an order by clause?
select … from mytable
order by col1, col2+100, sqrt(col3), charindex('a', col4),…
• Answer: historically, max. 31
• But as of ASE 15.7 SP50 and SP110: 200
• …. and as of ASE 16.0 : 400
• With compatibility mode enabled, the maximum is still 31
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 9
Increased #tables per statement
• Q: How many tables (normal-, work-, proxy-) can there be in a single statement?
• Answer: historically, in 11.9, max. 16; in 12.0, max. 50
• But as of ASE 15.7 SP50 and SP110: 255
• Also: 255 subqueries per statement
• With compatibility mode enabled, the maximum is still 50
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 10
Increased #engines in threaded kernel
• The ASE threaded kernel (introduced in 15.7 GA) uses native threads for ASE
server engines
• Allows more threads to be used than heavyweight processes in with the process
kernel
• However, 'max online engines' was still 128 in 15.7...
• The ASE 145.7 documentation said it could be 1024, but that was not correct
• In 16.0 GA, 'max online engines' can be set as high as 1024
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 11
PREPARE DATABASE
• Since 12.0: QUIESCE DATABASE … HOLD
• Allows taking consistent copies of DB devices without shutting down ASE
• "storage snapshots", "splitting the mirror", "BCV copy"
• Since 12.5: QUIESCE DATABASE…HOLD…FOR EXTERNAL DUMP
• Allows, for a database initialized with consistent copies of DB devices, loading of log
dumps that were subsequently made in the original server (requires booting the target
ASE server with -q)
• Downside: write actions are frozen during the QUIESCE, affecting applications
• Large customer with >100 EMC Symmetrix devices to split: takes >30 seconds
• New in 15.7 SP130/16.0SP01: PREPARE DATABASE…HOLD
• Same as QUIESCE DATABASE…FOR EXTERNAL DUMP, but does not block any writes
• Requires that the storage layer guarantees that DBMS writes will not be lost an kept in
order, e.g. EMC Symmetrix Enginuity.
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 12
Relaxed chained xacts - 16.0
• When ASE runs in chained transaction mode (set chained on), any select statement (and fetch, insert, update, delete), starts a new transaction.
• In 16.0, no new transaction is started when the SELECT statement:
• References only @variables or @@global variables: select @@error, select @my_var
• References only constants: select 'abc', select 100
• NB: select 'abc' + 'def' still starts a new xact (though select 1+2 does not)
• Calls certain built-in functions:
• get[utc]date()
• current_date()
• current_[big]time()
• current_bigdatetime()
• abs()
• [ase]hostname()
• NB: does not apply to all built-in functions: sign() or rand() still start a new xact!
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 13
Pesky 'Transaction count' messages in chained mode
Stored procedures for chained transaction mode:
create proc my_proc as
insert t values (1)
commit
go
sp_procxmode my_proc, 'chained'
go
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 14
Stored procedures for chained transaction mode
1> set chained on
2> go
1> select count(*) from t -- start the transaction
2> exec my_proc -- commits the transaction
3> go
-----------
722038
(return status = 0)
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRAN is
missing. Previous count = 1, Current count = 0.
1>
In 15.7 SP110, these messages are suppressed
in chained transaction mode
Pesky 'Transaction count' messages in chained mode
• Update: this message is still printed when the proc is marked with sp_procxmode… 'anymode' (CR 776856)
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 15
CREATE DATABASE…FOR LOAD
• When doing a CREATE DATABASE … FOR LOAD, the idea is that the database will
be overwritten by loading a database dump
• Yet, CREATE DATABASE… FOR LOAD initializes all allocation pages first.
• … and these are overwritten when the dump is loaded
Conclusion: these writes are pointless
15.7 SP121: allocation pages no longer initialized creation is now
instantaneous
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 16
KILL
• A long-standing rumour: a stronger version of KILL exists
• E.g. syb_terminate
• Rumour is incorrect! It's a myth…
• See my book "Tips, Tricks & Recipes for Sybase ASE", chapter 3
• Introducing… KILL <spid> WITH FORCE (15.7 SP121)
• Does kill sessions which are unable to check their KILLYOURSELF bit
• Sessions are never killed if they hold a spinlock (could lead to data corruption)
• No downside in using WITH FORCE
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 17
PC client downloadable separately
• As of ASE 16.0 GA, the PC client package is not longer bundled with ASE
• Must be downloaded separately; look for "SDK" or "Software Development Kit"
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 18
Being creative with permissions (1)
• One of my best tricks: the 'sa_indirect_role' tool
• See www.sypron.nl/grant_sa
• Basically: allow selected non-priviliged users to execute privileged commands
• E.g. running dbcc commands without granting sybase_ts_role
• Uses a combination of ASE features; check the code!
• This is not a security hole, when used responsibly (as with everything)
• Frequently recommended by Sybase TechSupport to customers
• But formally speaking, not supported by Sybase
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 19
Being creative with permissions (2)
• New feature in 15.7 ESD#2:
create procedure myproc
with execute as owner
as
…
• This executes the stored procedure with the permissions and roles of the user who
created the procedure
• Default: the user who executes the procedure (execute as caller)
• Create as 'sa', with 'sa_role' etc., execute as a non-priv'd user
• This is a less kludgy, and fully supported, way of achiving much of the same effects
• Yet another supported way to get there: using granular permissions (ASE license
option and configurable feature), also in 15.7 ESD#2
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 20
Being creative with permissions (3)
-- allow selected users to shut down the ASE server
create procedure do_shutdown
with execute as owner
as begin
-- only allow specific users, see next slide
declare @whoami varchar(30)
select @whoami = suser_name(suid)
from master.dbo.sysprocesses where spid = @@spid
if @whoami in ('jsmith', 'bwhite')
begin
shutdown
end
else
print 'Sorry my friend!'
end
go
grant execute on do_shutdown to public
go
Control access to this procedure
either by explicitly checking the user
or implicitly through grant
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 21
Being creative with permissions (4)
• Issue: how to check which user is calling the procedure
• With execute as owner, suser_name() now returns the name of the user who created the
procedure
• Instead, pick up sysprocess.suid
create procedure suser_test
with execute as owner
as
begin
select suser_name() 'suser_name',
suser_name(suid) 'suid'
from master.dbo.sysprocesses where spid = @@spid
end
suser_name suid
---------- ---------
sa robv
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 22
Being creative with permissions (5)
• Possible applications:
• Reading from MDA tables without granting mon_role
• dbcc commands
• DBA admin commands
• … etc…
• Be aware of permission-related aspects when using execute-immediate in these
stored procedures
• Check out sp_procxmode <procname>, 'dynamic'
• Documentation describes 'Dynamic Ownership Chain' aspects
SAP Exodus DBMS Migration Tool
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 24
Supported databases
• Exodus currently supports (v.2.6, Q1 2015):
• Source DBMS:
• Oracle (v.9/10/11/12); >80-90% automatic conversion ratio
• Microsoft SQL Server (v.2000-2012); >90-95% automatic conversion ratio
• IBM DB2 UDB (LUW, v.9.x, most PL/SQL extensions not covered); >70-80% automatic conversion
ratio
• Target DBMS: Sybase ASE, Sybase IQ, or SQL Anywhere
• Exodus is Unicode-enabled for migrated SQL code/schema
• Exodus API is in English only
• Under construction and planned: additional source & target DBMSs
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 25
DBMS migration stages
A. Pre-migration complexity/risk assessment decision to proceed
B. Schema migration
Performed by Exodus; migrated schema consistent with migrated SQL
C. Data migration (no Exodus support)
• Use SAP/Sybase ECDA/DirectConnect; SAP/Sybase Replication Server; SAP Data Services (etc.)
D. Server-side SQL migration
• Vendor-specific source SQL converted to the target DBMS SQL dialect (SQLScript, T-SQL, Watcom SQL)
• Stored procedure, functions, packages, etc.
• 90%+ of migration effort goes into SQL migration
• Most migration overruns and failures occur here
E. Client-side (application-generated) SQL migration (Exodus support for ad-hoc SQL query conversion)
• Client-side SQL may or may not be hard to capture or locate in app source code
• Fortunately most application-submitted SQL code is usually quite simple
F. Client application (no Exodus support)
Java/JDBC? Native OCI? Oracle Forms?
G. DBA tools (limited Exodus support)
Catalog queries not converted
H. Testing (functional, performance) (no Exodus support)
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 26
Exodus tool
Exodus run-time components (RTC)
Converted
SQL objects for
target DBMS
(SQL scripts)
Extracted
source DBMS
SQL objects
(SQL scripts)
Converts SQL to native target
DBMS SQL dialect where possible:
-- example: Oracle
SELECT SYSDATE from DUAL;
Converts SQL to run-time components
in target DBMS where needed:
-- example: Oracle
SELECT INITCAP(msg) from MyTable;
-- example: SAP Sybase ASE
SELECT CURRENT_BIGDATETIME()
-- example: SAP Sybase ASE
SELECT
dbo.sp_f_dbmtk_capitalize_word(msg)
from MyTable
Converted to
Converted to
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 27
SAP ASE as target DBMS
SAP ASE does not have a native equivalent of the following PL/SQL features :
Sequences (*)
Try-catch exception handling (as in PL/SQL and MSSQL 2005+) (**)
PL/SQL Packages (and package variables) (**)
%TYPE declarations (*)
RECORD and %ROWTYPE datatypes (*)
Timezone/interval/opaque datatypes (**)
Buffered PL/SQL output (DBMS_OUTPUT package calls) (*)
REF Cursors (**)
Synonyms for tables & views (*)
Data formatting masks, e.g. with TO_CHAR() (*)
Nested declarations of SQL functions/procedures (**)
Parametrized cursor declarations (*)
Nevertheless, Exodus converts these fully (*) or mostly (**) from Oracle to ASE
“mostly” means:> 95%.
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 28
Exodus Contact Information
Rob Verschoor, D&T Migration Solutions
or
• Also see SCN blogs:
Google for scn + exodus + verschoor
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 29
A Few Audience Quiz Questions….
• What ASE datatype would you use to migrate Oracle's BOOLEAN datatype to ASE?
TINYINT, not BIT: BOOLEAN can also contain NULL, but BIT can hold only 0 or 1
• How would you migrate a VARCHAR2 parameter in an Oracle stored procedure?
VARCHAR2 parameters do not have a declared length - so you must pick a length when migrating these
• Can you migrate an Oracle SMALLINT datatype to a SMALLINT in IQ?
Probably not: Oracle SMALLINT has 38-digit precision, like INT[EGER]. IQ SMALLINT supports the range from -32768 to
32767. So depends on actual values stored.
• What is the difference between Oracle and ASE for the BEGIN TRANSACTION statement ?
Oracle does not have a BEGIN TRANSACTION statement (it only supports chained xact mode)
• What happens when an unhandled exception reaches a top-level PL/SQL anonymous block?
An open transaction is rolled back to the implicit savepoint at the start of the anonymous block
• What is the result of this expression: 1/10 ?
In Oracle: 0.1
In MSSQL, DB2, ASE, IQ, SQLA: 0
• What is the visible effect of this PL/SQL statement: DBMS_OUTPUT.PUT_LINE(‘Hello!’);
Nothing, unless set serveroutput on was set, or the generated line is picked up with DBMS_OUTPUT.GET_LINE().
Session-global variables in
ASE
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 31
Session-global variables
• Exodus requires session-global variables:
• Scope = session
• Value is retained across client-server trips
• Watcom SQL has CREATE VARIABLE
• ASE has no such feature…
• …or has it?
• Since ASE 12.5:
• set_appcontext()
• get_appcontext()
• rm_appcontext()
• Not designed as session-global variables, but that's what they are
• VARCHAR(255) only
• Uses memory from the procedure cache
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 32
Session-global variables
• Exodus run-time components provide an API around these application context
functions, for use by the Exodus generated SQL code
• Handle storage of non-VARCHAR data
• Break up VARCHAR values longer than 255
• Used by Exodus for (among other things)
Sequences
Try-catch exception handling (as in PL/SQL and MSSQL 2005+)
PL/SQL Packages (and package variables)
Buffered PL/SQL output (DBMS_OUTPUT package calls)
Migrating the PL/SQL UTL_FILE package
Sequences in ASE
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 34
Sequences in ASE (and IQ)
• ANSI 2003 defines the concept of a 'sequence generator'
• DBMS object to generate sequential numbers
• Same basic concept as identity columns, but sequences are stand-alone objects, not part
of a table
• Sequences are supported in various DBMSs: SQL Anywhere, Oracle, MS SQL
• Not available in ASE & IQ
• However: a full sequence implementation can be done using existing ASE features
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 35
Sequences in ASE (and IQ)
• Sequence creation (SQL Anywhere syntax):
create sequence MySeq
start at 100
increment by 1
• Basic sequence concepts (SQL Anywhere syntax):
• MySeq.nextval - generates next value for this sequence
• MySeq.currval - contains last value generated for this sequence in the current session
• In SQL terms, these are both functions that can be used as expressions
insert into MyTable (pk, col1)
values (MySeq.nextval, 'Hello World!')
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 36
Sequences in ASE
1. Create a table with an identity column (plus other sequence attributes):
create table <name> (
seq bigint identity,
increment_by bigint null,
minvalue bigint null,
maxvalue bigint null,
…
)
2. Insert a row with the attribute values
3. Set the identity counter to the starting value of the sequence
dbcc set_identity_burn_max(…)
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 37
Sequences in ASE
4. Create a SQL function to get the next value using reserve_identity()
create function sp_f_nextval (@seqtab varchar(100))
as
begin
set @val = reserve_identity(@seqtab)
return @val
end
• NB: this does not insert a row, but only bumps up the identity counter
• But we need to do one more thing… implement the .currval function
-- keep this value for any subsequent 'currval' calls…
set @dummy = set_appcontext(<name>, @val)
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 38
Sequences in ASE
5. Create a SQL function to return the last generated value:
create function sp_f_currval (@seqtab varchar(100))
as
begin
set @val = get_appcontext(<name>, @val)
return @val
end
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 39
Sequences in ASE
There's one problem left:
• When a sequence reaches the maximum value, it can cycle back to its starting value
(optionally)
• This can be achieved by running dbcc set_identity_burn_max(…)
However….
• It is not allowed to call DBCC from a SQL Function in ASE
• It is allowed to call DBCC from a stored procedure…
• …but it is not allowed to call a stored procedure from an ASE SQL Function
• How to work around this?
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 40
Sequences in ASE
Solution:
• Create a stored proc that pretends to be an extended stored procs
• …since extended stored procs can be called from ASE SQL Functions
• An extended stored proc starts has a name starting with xp_
• They are supposed to map to external DLLs implementing the proc functions
• But they can also be written in SQL!
create proc xp_reset (@seqtab varchar(100))
as
begin
dbcc set_identity_burn_max(...)
end
Call this procedure from the SQL function generating the next sequence value
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 41
Sequences in IQ
• Sequences exist in SQL Anywhere 12.x
• However, these cannot be used directly with IQ tables (not clearly documented!)
create sequence MySeq -- really an SA object
go
insert into iq_table (MySeq.nextval, 'Hello!')
go
Syntax error raised
insert into sa_table (MySeq.nextval, 'Hello!')
go
OK
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 42
Sequences in IQ
• Solution: wrap the sequence call in a SQL Function:
create function sp_f_nextval (@seqtab varchar(100))
as
begin
execute('set @val =' || @seqtab || '.nextval')
return @val
end
insert into iq_table (sp_f_nextval('MySeq'), 'Hello!')
go
OK
Converting Scalar SQL
Functions to ASE
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 44
Converting Scalar SQL Functions to ASE (1)
• ASE’s scalar SQL user-defined functions (UDF) are limited in the features they support
• No DML (INSERT/UPDATE/DELETE)
• No DDL (CREATE TABLE)
• No transaction control (COMMIT/ROLLBACK)
• No non-deterministic BIFs
• No stored proc calls (except xp_ extended stored procedures)
• NB: table-valued SQL UDFs and table variables coming in ASE “Corona” release (2015)
• These limitations can represent a significant migration challenge if many SQL funtions are
used in the source DBMS
• Exodus exploits some boundary areas to convert SQL functions as much as possible anyway
• Main trick: (re)name stored procedures as “xp_” to allow them to be called from a SQL UDF
• Things that still cannot be done:
• SQL Function output parameters can often be rewritten as a stored procedure, if called only for single
scalar assignment, i.e. not in a SELECT statement (this rewrite is not currently done by Exodus)
• Returning result sets to the client can lead to a TDS machine state error (do NOT try to do this, also not
from a nested procedure called from the UDF)
• Converted PL/SQL exception handling exceptions raised inside a converted SQL function may not be
propagated correctly
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 45
Converting Scalar SQL Functions to ASE (2)
• Example: the following SQL UDF would be invalid in ASE
• Contains INSERT statement
• Contains COMMIT statement
CREATE FUNCTION myfunc (@p INT)
RETURNS INT
AS
BEGIN
INSERT INTO MyTab VALUES (@p)
COMMIT
RETURN(@p)
END
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 46
Converting Scalar SQL Functions to ASE (3)
• Exodus migrates this function as follows:
CREATE FUNCTION myfunc (@p INT)
RETURNS INT
AS
BEGIN
DECLARE @DBMTK_FUNCTION_RESULT INT
EXECUTE xp_myfunc @DBMTK_FUNCTION_RESULT OUTPUT, @p
RETURN(@DBMTK_FUNCTION_RESULT)
END
CREATE PROCEDURE xp_myfunc (@DBMTK_FUNCTION_RESULT INT OUTPUT, @p INT)
AS
BEGIN
INSERT INTO MyTab VALUES (@p)
COMMIT
SET @DBMTK_FUNCTION_RESULT = @p
RETURN
END
1
2
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 47
Converting Scalar SQL Functions to ASE (5)
• Remaining issues:
• There may some spurious warnings returned by ASE, despite the converted
function working correctly
• Currently, any nested stored procedure that is called from a SQL function, must
be named xp_, also on deeper levels
These issues should be alleviated in SP133, by enabling traceflag 11001
• Do not generate result set output in a stored procedure called from an ASE SQL
function: a TDS state error can occur and abort your session
Converting Try-Catch
Exception Handling to ASE
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 49
Converting Try-Catch Exception Handling to ASE (1)
• ASE does not support try-catch exception handling (like Oracle, Watcom, MSSQL, DB2)
BEGIN
…statements…
EXCEPTION
WHEN exception-name THEN ...action...
END
• Yet, Exodus can convert most of Oracle's PL/SQL and MSSQL 2005’s TRY-CATCH exception
handling to an ASE equivalent
• Inserts additional code to detect and propagate exceptions
• The Exodus-generated exception handling code may represent a maintenance challenge
• Exodus user guide provides some guidance
• Very complex exception-handling algorithms may be better migrated manually
• User can always choose not to convert exception handling,
Notes:
• By default, exception handling in ASE SQL functions is not converted
• The body of many SQL functions will be converted to ASE stored procedures anyway, where exception
conversion is enabled by default.
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 50
Converting Try-Catch Exception Handling to ASE (2)
• Automatically converted aspects for Oracle PL/SQL exception handling:
• Oracle exceptions: DUP_VAL_ON_INDEX, NO_DATA_FOUND, TOO_MANY_ROWS,
TIMEOUT_ON_RESOURCE, INVALID_CURSOR, CURSOR_ALREADY_OPEN, ZERO_DIVIDE
• RAISE for user-defined exceptions
• RAISE (without exception name) in an exception handler to re-raise an exception
• RAISE_APPLICATION_ERROR
• Automatic transaction rollback due to unhandled exceptions
• Exception propagation across triggers and nested stored procedure calls
• Not supported for Oracle PL/SQL exception handling:
• Oracle exceptions: ACCESS_INTO_NULL, CASE_NOT_FOUND, COLLECTION_IS_NULL,
INVALID_NUMBER, LOGIN_DENIED, NOT_LOGGED_ON, PROGRAM_ERROR,
ROWTYPE_MISMATCH, SELF_IS_NULL, STORAGE_ERROR, VALUE_ERROR
• Associating of exceptions with an error code (with PRAGMA EXCEPTION_INIT)
• Inside the original exception handling block, RAISE_APPLICATION_ERROR and exceptions occurring
during exception handling, may not be intercepted or propagated
• User-defined exceptions are expected to have unique names across the entire application
• SQLCODE and SQLERRM will often not be exactly identical to Oracle values
:
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 51
Converting Try-Catch Exception Handling to ASE (3)
• Automatically converted aspects for MSSQL 2005+ TRY-CATCH exception handling:
• THROW and RAISERROR in the TRY block
• THROW in the CATCH block to re-raise an exception
• Configurable behavior for BEGIN-END blocks outside TRY-CATCH blocks
• Exception propagation across triggers and nested stored procedure calls
• Not supported for MSSQL 2005+ TRY-CATCH exception handling:
• Exceptions occurring during exception handling in the CATCH block, may not be intercepted or propagated
• Transaction aspects around XACT_STATE() in the catch block; all transactional aspects must be
converted manually
:
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 52
Converting Try-Catch Exception Handling to ASE (4)
Example from PL/SQL application:
CREATE PROCEDURE myproc IS
BEGIN
INSERT INTO Customers VALUES (custID, custName);
[…other statements…]
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE('Error: customer ID already exists!');
ROLLBACK;
END;Converted to stored procedure
myproc_dbmtk_exception_1234
>>error-checking statements inserted<<
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 53
Converting Try-Catch Exception Handling to ASE (4)
Result in ASE (simplified!)
CREATE PROCEDURE myproc AS
BEGIN
INSERT INTO Customers VALUES (@custID, @custName)
EXEC @rs = myproc_dbmtk_exception_1234 @@ERROR
IF @rs = 1 GOTO end_label
[…other statements…]
end_label:
END
CREATE PROCEDURE myproc_dbmtk_exception_1234 (@err INT) AS
BEGIN
IF (@err = 2601)
BEGIN
PRINT 'Error: customer ID already exists!'
ROLLBACK TRANSACTION
RETURN(1)
END
RETURN(0)
END
1
2
3
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 54
Converting Try-Catch Exception Handling to ASE (5)
• More challenging: nested blocks, with and without exception handlers
• Who handles the exception in a block?
• Where to proceed after an exception was handled or when an unhandled exception remains?
• Exceptions in triggers
BEGIN
BEGIN
…statements…
BEGIN
…statements…
END
…statements…
EXCEPTION
WHEN exception-name THEN ...action...
END
EXCEPTION
WHEN exception-name THEN ...action...
END
Catching divide-by-zero
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 56
Catching divide-by-zero
• Philosophical debate: should you avoid dividing by zero or catch it when it happens?
• Oracle, MSSQL, DB2 all throw an exception when dividing by zero
• Exodus needs to convert that to a working ASE equivalent
• In ASE, dividing by zero aborts the batch:
1> select 1/0
2> print 'hello'
3> go
Msg 3607, Level 16, State 4
Server 'ASE16', Line 1
Divide by zero occurred.
This means you cannot intercept a div-by-zero in ASE.
Or can you?
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 57
Catching divide-by-zero
• System X comes to the rescue!
• Enable traceflag 3610 : div-by-zero will not abort the batch!
• Starting with ASE 11.0, by default, div-by-zero aborts the batch
1> dbcc traceon(3610)
2> go
1> select 1/0
2> select @@error
3> print 'hello'
4> go
-----------
NULL
Divide by zero occurred.
(1 row affected)
-----------
3607
hello
Tricks are what makes stuff
work!
© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 59
No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP SE. The information contained herein may be changed without prior notice.
Some software products marketed by SAP SE and its distributors contain proprietary software components of other software vendors.
Microsoft, Windows, Excel, Outlook, and PowerPoint are registered trademarks of Microsoft Corporation.
IBM, DB2, DB2 Universal Database, System i, System i5, System p, System p5, System x, System z, System z10, System z9, z10, z9, iSeries, pSeries, xSeries, zSeries, eServer, z/VM, z/OS, i5/OS, S/390, OS/390, OS/400, AS/400, S/390 Parallel Enterprise Server, PowerVM, Power Architecture, POWER6+, POWER6, POWER5+, POWER5, POWER, OpenPower, PowerPC, BatchPipes, BladeCenter, System Storage, GPFS, HACMP, RETAIN, DB2 Connect, RACF, Redbooks, OS/2, Parallel Sysplex, MVS/ESA, AIX, Intelligent Miner, WebSphere, Netfinity, Tivoli and Informix are trademarks or registered trademarks of IBM Corporation.
Linux is the registered trademark of Linus Torvalds in the U.S. and other countries.
Adobe, the Adobe logo, Acrobat, PostScript, and Reader are either trademarks or registered trademarks of Adobe Systems Incorporated in the United States and/or other countries.
Oracle is a registered trademark of Oracle Corporation.
UNIX, X/Open, OSF/1, and Motif are registered trademarks of the Open Group.
Citrix, ICA, Program Neighborhood, MetaFrame, WinFrame, VideoFrame, and MultiWin are trademarks or registered trademarks of Citrix Systems, Inc.
HTML, XML, XHTML and W3C are trademarks or registered trademarks of W3C®, World Wide Web Consortium, Massachusetts Institute of Technology.
Java is a registered trademark of Sun Microsystems, Inc.
JavaScript is a registered trademark of Sun Microsystems, Inc., used under license for technology invented and implemented by Netscape.
SAP, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign, SAP BusinessObjects Explorer, StreamWork, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP SE in Germany and other countries.
© 2015 SAP SE. All rights reserved
Business Objects and the Business Objects logo, BusinessObjects, Crystal Reports, Crystal Decisions, Web Intelligence, Xcelsius, and other Business Objects products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of Business Objects Software Ltd. Business Objects is an SAP company.
Sybase and Adaptive Server, iAnywhere, Sybase 365, SQL Anywhere, and other Sybase products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of Sybase, Inc. Sybase is an SAP company.
All other product and service names mentioned are the trademarks of their respective companies. Data contained in this document serves informational purposes only. National product specifications may vary.
The information in this document is proprietary to SAP. No part of this document may be reproduced, copied, or transmitted in any form or for any purpose without the express prior written permission of SAP SE.
This document is a preliminary version and not subject to your license agreement or any other agreement with SAP. This document contains only intended strategies, developments, and functionalities of the SAP® product and is not intended to be binding upon SAP to any particular course of business, product strategy, and/or development. Please note that this document is subject to change and may be changed by SAP at any time without notice.
SAP assumes no responsibility for errors or omissions in this document. SAP does not warrant the accuracy or completeness of the information, text, graphics, links, or other items contained within this material. This document is provided without a warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.
SAP shall have no liability for damages of any kind including without limitation direct, special, indirect, or consequential damages that may result from the use of these materials. This limitation shall not apply in cases of intent or gross negligence.
The statutory liability for personal injury and defective products is not affected. SAP has no control over the information that you may access through the use of hot links contained in these materials and does not endorse your use of third-party Web pages nor provide any warranty whatsoever relating to third-party Web pages.