tips tricks and little known features in sap ase

59
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 Verschoor VP, Global DBMS Migration Lead , Platform Solutions Group (c) 2015 Independent SAP Technical User Group Annual Conference, 2015

Upload: sap-technology

Post on 26-Jul-2015

218 views

Category:

Technology


8 download

TRANSCRIPT

Page 1: Tips Tricks and Little known features in SAP ASE

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

Page 2: Tips Tricks and Little known features in SAP ASE

© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 2

Agenda

Lots of miscellaneous features!

Q&A

Page 3: Tips Tricks and Little known features in SAP ASE

© 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

Page 4: Tips Tricks and Little known features in SAP ASE

© 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

Page 5: Tips Tricks and Little known features in SAP ASE

© 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

Page 6: Tips Tricks and Little known features in SAP ASE

© 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')

Page 7: Tips Tricks and Little known features in SAP ASE

© 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

Page 8: Tips Tricks and Little known features in SAP ASE

© 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

Page 9: Tips Tricks and Little known features in SAP ASE

© 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

Page 10: Tips Tricks and Little known features in SAP ASE

© 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

Page 11: Tips Tricks and Little known features in SAP ASE

© 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.

Page 12: Tips Tricks and Little known features in SAP ASE

© 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!

Page 13: Tips Tricks and Little known features in SAP ASE

© 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

Page 14: Tips Tricks and Little known features in SAP ASE

© 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)

Page 15: Tips Tricks and Little known features in SAP ASE

© 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

Page 16: Tips Tricks and Little known features in SAP ASE

© 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

Page 17: Tips Tricks and Little known features in SAP ASE

© 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"

Page 18: Tips Tricks and Little known features in SAP ASE

© 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

Page 19: Tips Tricks and Little known features in SAP ASE

© 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

Page 20: Tips Tricks and Little known features in SAP ASE

© 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

Page 21: Tips Tricks and Little known features in SAP ASE

© 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

Page 22: Tips Tricks and Little known features in SAP ASE

© 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

Page 23: Tips Tricks and Little known features in SAP ASE

SAP Exodus DBMS Migration Tool

Page 24: Tips Tricks and Little known features in SAP ASE

© 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

Page 25: Tips Tricks and Little known features in SAP ASE

© 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)

Page 26: Tips Tricks and Little known features in SAP ASE

© 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

Page 27: Tips Tricks and Little known features in SAP ASE

© 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%.

Page 28: Tips Tricks and Little known features in SAP ASE

© 2015 SAP SE. All rights reserved. ISUG-Tech 2015, Atlanta 28

Exodus Contact Information

Rob Verschoor, D&T Migration Solutions

[email protected]

or

[email protected]

• Also see SCN blogs:

Google for scn + exodus + verschoor

Page 29: Tips Tricks and Little known features in SAP ASE

© 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().

Page 30: Tips Tricks and Little known features in SAP ASE

Session-global variables in

ASE

Page 31: Tips Tricks and Little known features in SAP 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

Page 32: Tips Tricks and Little known features in SAP ASE

© 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

Page 33: Tips Tricks and Little known features in SAP ASE

Sequences in ASE

Page 34: Tips Tricks and Little known features in SAP 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

Page 35: Tips Tricks and Little known features in SAP ASE

© 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!')

Page 36: Tips Tricks and Little known features in SAP ASE

© 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(…)

Page 37: Tips Tricks and Little known features in SAP ASE

© 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)

Page 38: Tips Tricks and Little known features in SAP ASE

© 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

Page 39: Tips Tricks and Little known features in SAP ASE

© 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?

Page 40: Tips Tricks and Little known features in SAP ASE

© 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

Page 41: Tips Tricks and Little known features in SAP ASE

© 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

Page 42: Tips Tricks and Little known features in SAP ASE

© 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

Page 43: Tips Tricks and Little known features in SAP ASE

Converting Scalar SQL

Functions to ASE

Page 44: Tips Tricks and Little known features in SAP 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

Page 45: Tips Tricks and Little known features in SAP ASE

© 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

Page 46: Tips Tricks and Little known features in SAP ASE

© 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

Page 47: Tips Tricks and Little known features in SAP ASE

© 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

Page 48: Tips Tricks and Little known features in SAP ASE

Converting Try-Catch

Exception Handling to ASE

Page 49: Tips Tricks and Little known features in SAP 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.

Page 50: Tips Tricks and Little known features in SAP ASE

© 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

:

Page 51: Tips Tricks and Little known features in SAP ASE

© 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

:

Page 52: Tips Tricks and Little known features in SAP ASE

© 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<<

Page 53: Tips Tricks and Little known features in SAP ASE

© 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

Page 54: Tips Tricks and Little known features in SAP ASE

© 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

Page 55: Tips Tricks and Little known features in SAP ASE

Catching divide-by-zero

Page 56: Tips Tricks and Little known features in SAP ASE

© 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?

Page 57: Tips Tricks and Little known features in SAP ASE

© 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

Page 58: Tips Tricks and Little known features in SAP ASE

Tricks are what makes stuff

work!

Page 59: Tips Tricks and Little known features in SAP ASE

© 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.