28
Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 By: Breck Carter Introduction SAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since version 12 in 2010... that’s a pretty good track record, skipping over one version number per year for three years. It is possible that version numbers 13 and 14 were passed over for the usual reasons of triskaidekaphobia and tetraphobia (fear of the numbers 13 and 4), and it is also possible that number 15 was skipped because it’s been used by SAP Sybase ASE since, well, forever, and SAP Sybase SQL Anywhere 15 would perpetuate the myth that SQL Anywhere and ASE are somehow related. So, we’ve got SAP Sybase SQL Anywhere 16, what’s cool about it? Well, first of all, for the record, it’s got all the same cool stuff found in version 12, nothing big has been jettisoned, not even SQL Remote (so many folks fret about that, having been burned by other vendors forcing Upgrade Death Marches of dubious value). Performance is improved, but that’s not discussed in this article because (a) the performance enhancements are covered in the documentation, (b) it’s too early to tell exactly what the effects are, and (c) without a Woohoo! case study or two to drive home the point I would just be reading the Help to you. Another big new feature in SQL Anywhere 16 is the Role-Based Security Model, a breathtaking revision of GRANT and REVOKE involving seven new and replaced SQL statements, six new system procedures, six new database and server options, and a whole new way of looking at things: “Whereas before you had authorities, permissions, object-level permissions, and groups, you now have roles, system privileges, object-level privileges, and user-extended roles.” The release-defining Role-Based Security Model isn’t fully covered in this article because, frankly, it’s just too big to fit... but, one component has been plucked from within it: the two- person password change process is found only in SAP Sybase SQL Anywhere 16, nowhere else, not in Oracle or SQL Server or any other relational database. © 2013 SAP AG or an SAP affiliate company. All rights reserved.

Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

Embed Size (px)

Citation preview

Page 1: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16By: Breck Carter

Introduction

SAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since version 12 in 2010... that’s a pretty good track record, skipping over one version number per year for three years.

It is possible that version numbers 13 and 14 were passed over for the usual reasons of triskaidekaphobia and tetraphobia (fear of the numbers 13 and 4), and it is also possible that number 15 was skipped because it’s been used by SAP Sybase ASE since, well, forever, and SAP Sybase SQL Anywhere 15 would perpetuate the myth that SQL Anywhere and ASE are somehow related.

So, we’ve got SAP Sybase SQL Anywhere 16, what’s cool about it?

Well, first of all, for the record, it’s got all the same cool stuff found in version 12, nothing big has been jettisoned, not even SQL Remote (so many folks fret about that, having been burned by other vendors forcing Upgrade Death Marches of dubious value).

Performance is improved, but that’s not discussed in this article because (a) the performance enhancements are covered in the documentation, (b) it’s too early to tell exactly what the effects are, and (c) without a Woohoo! case study or two to drive home the point I would just be reading the Help to you.

Another big new feature in SQL Anywhere 16 is the Role-Based Security Model, a breathtaking revision of GRANT and REVOKE involving seven new and replaced SQL statements, six new system procedures, six new database and server options, and a whole new way of looking at things:

“Whereas before you had authorities, permissions, object-level permissions, and groups, you now have roles, system privileges, object-level privileges, and user-extended roles.”

The release-defining Role-Based Security Model isn’t fully covered in this article because, frankly, it’s just too big to fit... but, one component has been plucked from within it: the two-person password change process is found only in SAP Sybase SQL Anywhere 16, nowhere else, not in Oracle or SQL Server or any other relational database.

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 2: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

2

Now, here’s the Top 10 list of cool new features in SAP Sybase SQL Anywhere 16:

1. ROWsThe new ROW data type is tied with ARRAY for the title of Number One Cool New Feature In SAP Sybase SQL Anywhere 16.

ROW lets you DECLARE structure-like variables in SQL scripts, and pass them as single arguments in procedure CALL statements to represent multiple fields. Here’s an example:

CREATE PROCEDURE p ( pr ROW ( field1 INTEGER, field2 INTEGER, field3 INTEGER ) )BEGIN SELECT pr.field1, pr.field2, pr.field3;END;

BEGIN

DECLARE r ROW ( field1 INTEGER, field2 INTEGER, field3 INTEGER );

SET r.field1 = 1;SET r.field2 = 2;SET r.field3 = 3;

CALL p ( r );

END;

field1 field2 field3 ----------- ----------- ----------- 1 2 3

The ROW() constructor can be used to fill a row all-in-one-go like this:

DECLARE r ROW ( field1 INTEGER, field2 INTEGER, field3 INTEGER );

SET r = ROW ( 1, 2, 3 );

SELECT r.field1, r.field2, r.field3;

field1 field2 field3 ----------- ----------- ----------- 1 2 3

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 3: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

3

ROW variables can be nested inside other ROWs, and so can calls to the ROW() constructor, like this:

BEGIN

DECLARE r ROW ( field1 INTEGER, s ROW ( field2 INTEGER, field3 INTEGER, field4 INTEGER ), field5 INTEGER );

SET r = ROW ( 1, ROW ( 2, 3, 4 ), 5 );

SELECT r.field1, ( r ).s.field2, ( r ).s.field3, ( r ).s.field4, r.field5;

END;

field1 expression expression expression field5 ----------- ----------- ----------- ----------- ----------- 1 2 3 4 5

One thing that’ll take some getting used to is the funky syntax for fields-within-fields: SELECT ( r ).s.field2 works OK, but SELECT r.s.field2 gives SQLCODE -142 Correlation name ’s’ not found.

In one sense, a ROW is like a structure, but in another sense a ROW is like a row, as in a row in a table because you can use SELECT to build a ROW():

BEGIN

DECLARE Dept_row ROW ( DeptID INTEGER, DeptName VARCHAR ( 20 ), DeptHeadID INTEGER );

SET Dept_row = ROW ( SELECT DepartmentID, DepartmentName, DepartmentHeadID FROM Departments WHERE DepartmentID = 100 );

SELECT Dept_row.DeptID, Dept_row.DeptName, Dept_row.DeptHeadID;

END;

DeptID DeptName DeptHeadID ----------- -------------------- -----------

100 R & D 501 © 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 4: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

4

The bad news comes in the form of SQLCODE -1599, which means

“You tried to use an ARRAY or ROW type in an unsupported context. You cannot store these values in tables or read them directly from client interfaces such as ODBC, ESQL, and JDBC. You must extract the individual values you are interested in.”

The good news is that message should probably contain the word “yet”, as in

• “You cannot yet” SELECT an entire ROW in ISQL, • or include a ROW column in a CREATE TABLE statement, • or use CREATE DOMAIN with the ROW data type, • or pass entire ROW values to and from client applications...

where “yet” means soon, or eventually.

If you’re skeptical about whether or not the ROW data type will ever by supported by CREATE TABLE, consider this example; it shows the ROW() constructor being used to create a derived table containing a column “product_row” with the ROW data type:

SELECT ( product.product_row ).id AS id FROM ( SELECT ROW ( Products.id, Products.name ) FROM GROUPO.Products ) AS product ( product_row );

id ----------- 300 301 302 400 401 500 501 600 601 700

The derived table “product” might not be a real CREATE TABLE table, but it works just like a table in the FROM clause, and it’s available in SAP Sybase SQL Anywhere 16.0.0 right now.

Can ROW columns in CREATE TABLE be far behind?

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 5: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

5

2. ARRAYsThe ARRAY data type is the second entry in the Top 10 Cool list, tied for Number One with ROW.

Similar to ROW, the ARRAY keyword is used for both the data type and constructor:

BEGINDECLARE a ARRAY ( 5 ) OF INTEGER;SET a = ARRAY ( 97, 98, 99 );SELECT a [[ 1 ]], a [[ 2 ]], a [[ 3 ]]; END;

a[[ 1]] a[[ 2]] a[[ 3]] ----------- ----------- ----------- 97 98 99

Yes, arrays come with funky syntax too: [[double square brackets]] around index expressions instead of [] or ().

Arrays can have adjustable upper bounds (just code DECLARE ARRAY OF without the ( 5 )), and you can add entries after using the ARRAY() constructor to initialize the array:

BEGINDECLARE a ARRAY OF INTEGER;

SET a = ARRAY ( 1, 2 );

SELECT a [[ 1 ]], a [[ 2 ]];

SET a = ARRAY ( 3, 4, 5, 6 );SET a [[ 5 ]] = 7;SET a [[ 6 ]] = 8;

SELECT a [[ 1 ]], a [[ 2 ]], a [[ 3 ]], a [[ 4 ]], a [[ 5 ]], a [[ 6 ]]; END;

a[[ 1]] a[[ 2]] ----------- ----------- 1 2

a[[ 1]] a[[ 2]] a[[ 3]] a[[ 4]] a[[ 5]] a[[ 6]] ----------- ----------- ----------- ----------- ----------- ----------- 3 4 5 6 7 8

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 6: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

You can pass arrays in procedure calls, and the new CARDINALITY() function helps deal with variable-size arrays:

CREATE PROCEDURE p ( pa ARRAY OF INTEGER )BEGIN DECLARE i INTEGER; SET i = CARDINALITY ( pa ); SELECT pa [[ i ]];END;

BEGINDECLARE a ARRAY OF INTEGER;

SET a = ARRAY ( 1, 2 );CALL p ( a );

SET a = ARRAY ( 1, 2, 3, 4, 5, 6 );CALL p ( a );END;

pa[[ i]] ----------- 2

pa[[ i]] ----------- 6

Arrays can be nested within arrays, but “nested arrays” aren’t necessarily the same as “multi-dimensional arrays” because each nested array can have a different size. In other words, SAP Sybase SQL Anywhere 16 supports single-dimensional arrays which can be nested within other single-dimensional arrays, and that [[funky syntax]] lets you code [[ 1 ]] [[ 2 ]] but not [[ 1, 2 ]]:

BEGINDECLARE a ARRAY OF ARRAY OF INTEGER;

SET a = ARRAY ( ARRAY ( 1, 2 ), ARRAY ( 3, 4, 5 ), ARRAY ( 6, 7, 8, 9 ) );

SELECT CARDINALITY ( a [[ 1 ]] ) AS “Cardinality 1“, CARDINALITY ( a [[ 2 ]] ) AS “2“, CARDINALITY ( a [[ 3 ]] ) AS “3“, a [[ 1 ]] [[ 2 ]], a [[ 2 ]] [[ 3 ]], a [[ 3 ]] [[ 4 ]];END;

Cardinality 1 2 3 a[[ 1]][[ 2]] a[[ 2]][[ 3]] a[[ 3]][[ 4]] ------------- ---------- ---------- ------------- ------------- ---------- 2 3 4 2 5 9

6© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 7: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

In one sense, ARRAY variables behave like arrays in other languages, but in another sense they behave like single-column result sets. Here is an example showing how data from a table can be loaded into two arrays, one of them which is a nested array-within-an-array:

BEGINDECLARE D ARRAY OF INTEGER;DECLARE E ARRAY OF ARRAY OF INTEGER;DECLARE D_idx INTEGER;DECLARE E_idx INTEGER;

DECLARE emp_cursor CURSOR FOR SELECT DepartmentID AS D_scalar, ARRAY_AGG ( EmployeeID ORDER BY EmployeeID ) AS E_vector FROM Employees GROUP BY DepartmentID ORDER BY DepartmentID;

--------------------------------------------------- Fill arrays.

OPEN emp_cursor;SET D_idx = 1;FETCH NEXT emp_cursor INTO D [[ D_idx ]], E [[ D_idx ]];

WHILE SQLCODE = 0 LOOP SET D_idx = D_idx + 1; FETCH NEXT emp_cursor INTO D [[ D_idx ]], E [[ D_idx ]];END LOOP;

CLOSE emp_cursor;

--------------------------------------------------- Display arrays.

SET D_idx = 1;

WHILE D_idx <= CARDINALITY ( D ) LOOP MESSAGE STRING ( ‘D [[ ’, D_idx, ’ ]] = ’, D [[ D_idx ]] ); SET E_idx = 1;

WHILE E_idx <= CARDINALITY ( E [[ D_idx ]] ) LOOP MESSAGE STRING ( ’ E [[ ’, D_idx, ’ ]] [[ ’, E_idx, ’ ]] = ’, E [[ D_idx ]] [[ E_idx ]] ); SET E_idx = E_idx + 1; END LOOP;

SET D_idx = D_idx + 1;END LOOP;END;

7© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 8: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

The DECLARE CURSOR statement uses the new ARRAY_AGG function to gather all the EmployeeID column values for one GROUP BY value of DepartmentID, and return it as the “E_vector” array column in the result set.

The two FETCH statements store each D_scalar value as the next element in the array D; i.e., D is an array of DepartmentID values.

Those FETCH statements also take each E_vector array value and stores it in the next element of the array E; i.e., E [[ D_idx ]] is a nested array containing EmployeeID values. These nested arrays vary in size because each department contains a varying number of employees.

The two WHILE loops display the contents of D and E, like this (with a few entries omitted):

D [[ 1 ]] = 100 E [[ 1 ]] [[ 1 ]] = 102 E [[ 1 ]] [[ 2 ]] = 105 ... E [[ 1 ]] [[ 21 ]] = 1157 E [[ 1 ]] [[ 22 ]] = 1250D [[ 2 ]] = 200 E [[ 2 ]] [[ 1 ]] = 129 E [[ 2 ]] [[ 2 ]] = 195 ... E [[ 2 ]] [[ 18 ]] = 1446 E [[ 2 ]] [[ 19 ]] = 1596D [[ 3 ]] = 300 ...D [[ 4 ]] = 400 ...D [[ 5 ]] = 500 E [[ 5 ]] [[ 1 ]] = 191 E [[ 5 ]] [[ 2 ]] = 703 ... E [[ 5 ]] [[ 8 ]] = 1615 E [[ 5 ]] [[ 9 ]] = 1658

3. SMTP Email EnhancementsOnce upon a time, a really cool feature was added to SAP Sybase SQL Anywhere: the ability to send MAPI and SMTP email messages from inside stored procedures.

Then along came all those bots and worms and trojans and viruses, and not only did Microsoft make it almost impossible to send MAPI messages inside executable programs (like a database server) running on Windows, but most shops stopped running SMTP servers... so calling xp_sendmail() from inside SAP Sybase SQL Anywhere became a chore.

But then, another cool feature was added to SAP Sybase SQL Anywhere: the ability to use a secure third-party SMTP server like gmail.com by providing an SSL (secure sockets layer) certificate along with a user id and password. That meant if you had a gmail account, and you could find a certificate, you could use it to send emails from SQL.

With great security, of course, comes great security difficulties, and the challenge of debugging vague return codes like 105 “A TLS error has occurred”.

8© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 9: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

9

Now SAP Sybase SQL Anywhere 16 has made debugging easier with the new xp_get_mail_error_code() function which turns the generic failure return code -1 into something more specific like 535, and xp_get_mail_error_text() which tells you what really happened: “Username and Password not accepted.”

But wait, it gets better: when you call xp_get_mail_error_text() after gmail rejects your email, Google includes a link to a web page:

Here’s a working example of how to send a message via gmail.com from inside a SAP Sybase SQL Anywhere 16 script:

BEGINDECLARE @return_code INTEGER;

@return_code = CALL xp_startsmtp ( smtp_sender = ‘[email protected]’, smtp_server = ‘smtp.gmail.com’, smtp_port = 587, timeout = 60, smtp_sender_name = ‘Sender Name Goes Here’, smtp_auth_username = ‘[email protected]’, smtp_auth_password = ‘Password Goes Here’, trusted_certificates = ‘C:/temp/Equifax_Secure_Certificate_Authority.cer’ );

MESSAGE STRING ( ‘xp_startsmtp @return_code = “, @return_code ) TO CLIENT;IF @return_code = -1 THEN MESSAGE STRING ( ‘ Error = ‘, xp_get_mail_error_code(), ‘ - ‘,

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 10: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

10

xp_get_mail_error_text() ) TO CLIENT;END IF;

@return_code = CALL xp_sendmail ( recipient = ‘[email protected]’, subject = ‘Subject Goes Here’, “message“ = ‘Message Body Goes Here’ );

MESSAGE STRING ( ‘xp_sendmail @return_code = ‘, @return_code ) TO CLIENT;IF @return_code = -1 THEN MESSAGE STRING ( ‘ Error = ‘, xp_get_mail_error_code(), ‘ - ‘, xp_get_mail_error_text() ) TO CLIENT;END IF;

@return_code = CALL xp_stopsmtp();

MESSAGE STRING ( ‘xp_stopsmtp @return_code = ‘, @return_code ) TO CLIENT;IF @return_code = -1 THEN MESSAGE STRING ( ‘ Error = ‘, xp_get_mail_error_code(), ‘ - ‘, xp_get_mail_error_text() ) TO CLIENT;END IF;

EXCEPTION WHEN OTHERS THEN CALL xp_stopsmtp();

END;

If you run that code as-is, here’s what you will see:

xp_startsmtp @return_code = -1 Error = 535 - 5.7.1 Username and Password not accepted. Learn more at 5.7.1 http://support.google.com/mail/bin/answer.py?answer=14257 kf2sm5240109igc.0 - gsmtp xp_sendmail @return_code = 3xp_stopsmtp @return_code = 0

If you fix the smtp_auth_username and smtp_auth_password values, the code will work:

xp_startsmtp @return_code = 0xp_sendmail @return_code = 0xp_stopsmtp @return_code = 0

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 11: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

11

Another enhancement that directly affects sending email is the new CREATE OR REPLACE CERTIFICATE statement. Once you have gone to the trouble of finding or creating a security certificate, you can now store it inside the database instead of deploying it as a separate file:

CREATE OR REPLACE CERTIFICATE gmail FROM FILE ‘C:/temp/Equifax_Secure_Certificate_Authority.cer’;

The CREATE CERTIFICATE name can now be used inside the CALL xp_startsmtp() like this:

@return_code = CALL xp_startsmtp ( smtp_sender = ‘[email protected]’, smtp_server = ‘smtp.gmail.com’, smtp_port = 587, timeout = 60, smtp_sender_name = ‘Sender Name Goes Here’, smtp_auth_username = ‘[email protected]’, smtp_auth_password = ‘Password Goes Here’, trusted_certificates = ‘cert_name=gmail’ );

Here’s a tip: Don’t forget the FILE keyword in the FROM FILE clause of CREATE CERTIFICATE. It is oh-so-easy to leave out: not only does FROM ‘C:/temp/Equifax_Secure_Certificate_Authority.cer’ look right but it seems to work right because the CREATE CERTIFICATE doesn’t throw an error. What happens next is xp_startsmtp() fails, xp_get_mail_error_code() returns the undocumented error code 10038, xp_get_mail_error_text() returns nothing, and you’re back to the “challenge of debugging” bemoaned above. The problem (I think) is that without the FILE keyword CREATE CERTIFICATE stored the string ‘C:/temp/Equifax_Secure_Certificate_Authority.cer’ as the certificate itself rather than reading the file, and that’s just not gonna work... so, you’ve been warned :)

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 12: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

12

4. ALTER TABLE ALTER OWNERThe SAP Sybase SQL Anywhere question-and-answer forum is home to many “How do I [do some thing]?” questions that have been asked over and over again throughout the years.

Many of them have helpful answers, but others share the same response: “You can’t, not without [first doing some other difficult thing].”

For example, “You can’t change the page size of a database, not without unloading, recreating and reloading the database with the new page size.”

That particular answer still applies, but here’s one that is changing: Until SAP Sybase SQL Anywhere 16 the answer to “How do I change the owner of a table?” has been “You can’t, not without dropping and recreating the table with the new owner.”

Now the answer is “Use the new ALTER TABLE ALTER OWNER statement”:

ALTER TABLE DBA.t ALTER OWNER TO USER1;

What about foreign keys? What about permissions? By default, they’re dropped, and the altered table stands bereft of family relationships... but you can use the PRESERVE PRIVILEGES and PRESERVE FOREIGN KEYS clauses to change that; here’s an example.

CREATE TABLE DBA.parent ( pkey INTEGER NOT NULL PRIMARY KEY, data INTEGER NOT NULL );

CREATE TABLE DBA.child ( pkey INTEGER NOT NULL PRIMARY KEY, fkey INTEGER NOT NULL REFERENCES parent ( pkey ), data INTEGER NOT NULL );

CREATE TABLE DBA.grandchild ( pkey INTEGER NOT NULL PRIMARY KEY, fkey INTEGER NOT NULL REFERENCES child ( pkey ), data INTEGER NOT NULL );

INSERT parent VALUES ( 1, 1 );INSERT child VALUES ( 2, 1, 2 );INSERT grandchild VALUES ( 3, 2, 3 );COMMIT;

GRANT CONNECT TO USER1 IDENTIFIED BY SQL;

ALTER TABLE DBA.child ALTER OWNER TO USER1 PRESERVE PERMISSIONS PRESERVE FOREIGN KEYS;

SELECT * FROM USER1.child;

pkey fkey data ----------- ----------- ----------- 2 1 2

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 13: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

13

This screen shot from Sybase Central shows that while the child table is now owned by USER1, the foreign key relationship with DBA.grandchild remains undisturbed:

5. xp_getenv()

The new xp_getenv() extended stored procedure accepts an environment variable as argument and returns the current value:

SELECT xp_getenv ( ‘APPDATA’ );

xp_getenv(‘APPDATA’)--------------------------------------------------------------0x433a5c55736572735c427265636b5c417070446174615c526f616d696e67

Oops... xp_getenv() returns LONG BINARY, and ISQL displays that in hex instead of character, so if you want to display it as a VARCHAR you have to call CAST():

SELECT CAST ( xp_getenv ( ‘APPDATA’ ) AS VARCHAR );

xp_getenv(‘APPDATA’)------------------------------C:\Users\Breck\AppData\Roaming

Environment variables provide a direct path for passing external settings to SQL stored procedures and other scripts running inside a database server: you SET an environment variable outside the server, and call xp_getenv() inside the server whenever the value is needed.

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 14: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

14

For example, here’s a permanent environment variable being set up via Control Panel – System – Advanced System Settings – Environment Variables... – System Variables – New... – New System Variables window:

...and here’s how easy it is to retrieve that value in a SQL script:

BEGIN DECLARE ClientAuthorizationCode VARCHAR ( 10 ); SET ClientAuthorizationCode = xp_getenv ( ‘ClientAuthorizationCode’ ); SELECT ClientAuthorizationCode;END;

ClientAuthorizationCode ----------------------- X4Z895

Environment variables are simpler than configuration files which require custom code on the client side, or inside the database, to read and parse the configuration files, not to mention the process of creating and maintaining the configuration files which is always more complex than simple SET commands.

When you call xp_getenv ( ‘variable’ ) from inside a SAP Sybase SQL Anywhere 16 database running on Windows 7, it works for

• all the environment variables that appear when you run SET by itself at the command prompt on the database server,

• which is a superset of the variables in the Control Panel – Advanced System Settings – Environment Variables window,

• which also includes custom SET WHATEVER values you have defined before starting the database engine,

• but xp_getenv() doesn’t work for the dynamic environment variables like CD and ERROR-LEVEL; e.g., %CD% returns the current directory inside a batch file but xp_getenv ( ‘CD’ ) returns NULL,

• nor does xp_getenv() work for custom SET variables that fall out of scope before xp_getenv() is called; e.g., the following SELECT returns NULL because the SET WHATEVER command created a variable local to the command processor opened by xp_cmdshell() and that processor disappeared along with the SET WHATEVER when the CALL returned:

CALL xp_cmdshell ( ‘SET WHATEVER=123’ );SELECT xp_getenv ( ‘WHATEVER’ );

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 15: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

15

If you really need the value of %CD%, you can run this command before starting the server

SET VCD=%CD%

and then call xp_getenv() inside the SQL script:

SELECT CAST ( xp_getenv ( ‘VCD’ ) AS VARCHAR );

xp_getenv(‘VCD’)----------------C:\data\xpdemo

Here’s another trick; you can combine sa_split_list() with xp_getenv() to turn the PATH string into a table with one folder per row:

SELECT row_value AS “Path“ FROM sa_split_list ( CAST ( xp_getenv ( ‘PATH’ ) AS VARCHAR ), ‘;’ ) ORDER BY line_num;

Path-----------------------------------------------------------------C:\Program Files\Common Files\Microsoft Shared\Windows Live C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live C:\Windows\system32C:\Windows ...C:\Program Files (x86)\Sybase\Shared\win32C:\Program Files (x86)\Sybase\Shared\ 4.3\win32 C:\Program Files\SQL Anywhere 16\bin64 C:\Program Files\SQL Anywhere 16\bin32

6. BINTOHEX() and HEXTOBIN()If you’ve ever had to code SQL to convert an ordinary character string to and from a “hexadecimal string” in which each character in the original string corresponds to pair of ‘0-F’ characters, you’re may be familiar with the INTTOHEX() and HEXTOINT() functions which convert INTEGER numbers to and from hex strings.

If so, then you are also familiar, or perhaps disgusted, with how few characters INTTOHEX() and HEXTOINT() can handle, as well as how messed up everything gets with the funky conversions between INTEGER and VARCHAR:

SELECT HEXTOINT ( ‘ff’ ) AS a, EXPRTYPE ( ‘SELECT HEXTOINT ( ‘’ff’’ )’, 1 ) AS type_of_a;

a type_of_a----------- --------- 255 integerSELECT INTTOHEX ( 255 ) AS b,

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 16: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

16

EXPRTYPE ( ‘SELECT INTTOHEX ( 255 )’, 1 ) AS type_of_b;

b type_of_b-------- ----------000000ff varchar(8)

SELECT HEXTOINT( ‘30313233343536373839‘ );

Function ‘hextoint’ has invalid parameter ‘1’ (‘30313233343536373839’)SQLCODE=-1090, ODBC 3 State=“08004“

Those challenges don’t apply to SAP Sybase SQL Anywhere 16’s new BINTOHEX() and HEXTOBIN() functions which convert between LONG BINARY and LONG VARCHAR: no more length limitations, and no more conversions between string and INTEGER.

Here’s an example; the string ‘Hello, world!’ is 13 characters long, and BINTOHEX converts it to a hexadecimal string ‘4865...’ that is 26 characters in length:

SELECT BINTOHEX ( ‘Hello, world!’ ) AS a, LENGTH ( a );

a LENGTH(a)-------------------------- ---------48656C6C6F2C20776F726C6421 26

Here’s how it works going the other way; HEXTOBIN converts ‘48656C6C6F2C20776F726C6421’ to a BINARY string, and to prevent ISQL from displaying that as ‘0x4865...’ CAST() is called to display the result as a character string:

SELECT CAST ( HEXTOBIN ( ‘48656C6C6F2C20776F726C6421’ ) AS VARCHAR ) AS b;

b---------------‘Hello, world!’

Mostly, what folks really want are CHARTOHEX() and HEXTOCHAR() functions, and that’s pretty much what BINTOHEX() and HEXTOBIN() give you if you keep these points in mind:BINARY strings are just like VARCHAR strings without all the collation sequences and character sets conversions, and

ISQL really really really wants to display BINARY strings in the 0x4865... format instead of ‘what you want’.

If your application does care about collation sequences and character sets, then you’re probably used to dealing with some complications.

If, on the other hand, a string is just a string to you, be it BINARY or VARCHAR, then these tiny wrapper functions might come in handy:

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 17: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

CREATE FUNCTION CHARTOHEX ( c LONG VARCHAR ) RETURNS LONG VARCHARBEGIN RETURN BINTOHEX ( c );END;

CREATE FUNCTION HEXTOCHAR ( h LONG VARCHAR ) RETURNS LONG VARCHARBEGIN RETURN HEXTOBIN ( h );END;

SELECT CHARTOHEX ( ‘Hello, world!‘ ) AS a, HEXTOCHAR ( ‘48656C6C6F2C20776F726C6421‘ ) AS b;

a b-------------------------- -------------48656C6C6F2C20776F726C6421 Hello, world!

The LONG VARCHAR data types specified in the CREATE FUNCTION statements force implied data conversions on the LONG BINARY values used by BINTOHEX and HEXTOBIN, so the outside world only sees LONG VARCHAR values when calling CHARTOHEX() and HEXTOCHAR().

7. Two-Person Password ChangesThe two-person rule requires that two authorized people must participate in a critical operation in order to achieve a high level of security.

Because the possession of someone else’s password is a security concern, a diligent enterprise might wish to impose the two-person rule when a DBA changes the password for someone else’s user id. With a single DBA in control of this process, that single DBA does “possess someone else’s password” during the short window of time between the password being changed and it being changed again by its rightful owner, thus making it possible for the DBA to masquerade as that user.

If that single DBA then repeats the forced password change after posing as the user, the exploit might not be discovered let alone prevented.

SAP Sybase SQL Anywhere 16 now lets you apply the two-person rule to password changes by requiring two separate administrators to perform the operation. Each administrator changes one part of the password, and then gives that part to the user. The user then provides both parts of the changed password when next connecting to a SAP Sybase SQL Anywhere database. In return, SAP Sybase SQL Anywhere prompts the user for yet another new and different password which then must be used from that point forward.

17© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 18: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

Here’s a demonstration of how it works:

Step 1: Create two minor DBA user ids, the “two-person” login policy and an end-user id.

CREATE USER DBAdminion1 IDENTIFIED BY ‘t83mUXm58‘;GRANT CHANGE PASSWORD TO DBAdminion1;

CREATE USER DBAdminion2 IDENTIFIED BY ‘4dC02gMqw‘;GRANT CHANGE PASSWORD TO DBAdminion2;

CREATE LOGIN POLICY CHANGE_PASSWORD_DUAL_CONTROL change_password_dual_control = ON;

CREATE USER EndUser LOGIN POLICY CHANGE_PASSWORD_DUAL_CONTROL;

The CREATE USER DBAdminion1 and DBAdminion2 statements create two administrative user ids that will be used to perform the two-person password change.

GRANT CHANGE PASSWORD statements are a part of the new “Role-Based Security Model”. Rather than grant full DBA privileges to DBAdminion1 and DBAdminion2, they are only permitted to perform one single task: dual-control password changes on other user ids. These administrators are truly less-than-omnipotent, they can’t create tables, they can‘t even query other people’s tables.

The CREATE LOGIN POLICY statement is another example of the new “Role-Based Security Model”. It works by defining a new “login policy” called CHANGE_PASSWORD_DUAL_CONTROL which consists of one pre-defined “login policy option” called (wait for it!) change_password_dual_control, with its value changed from the default OFF to ON.

The CREATE USER EndUser statement initializes the new user id with the login policy which forces the use of dual-control password changes. At this point, EndUser doesn‘t have any password at all so it can‘t be used to do anything.

Step 2: DBAdminion1 assigns the first part the password for EndUser.

“%SQLANY16%\bin64\dbisql.com”^ -c “ENG=ddd16;DBN=ddd16;UID=DBAdminion1;PWD=t83mUXm58“^ ALTER USER EndUser IDENTIFIED FIRST BY ‘My74mFi7‘;

Step 3: DBAdminion2 assigns the second part the password.

“%SQLANY16%\bin64\dbisql.com“^ -c “ENG=ddd16;DBN=ddd16;UID=DBAdminion2;PWD=4dC02gMqw“^ ALTER USER EndUser IDENTIFIED LAST BY ‘7mf3ePIo‘;

Step 4: EndUser connects to the database with the two parts of the password.

“%SQLANY16%\bin64\dbisql.com“^ -c “ENG=ddd16;DBN=ddd16;UID=EndUser;PWD=My74mFi77mf3ePIo;“

18© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 19: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

Run that, and you‘ll see what EndUser sees:

Click OK to get this:

Then click Connect to get the “Enter a new password” dialog box in which you specify the old “part1 - part2” password plus a new password, and when you press OK it will let you connect:

When you press OK, SAP Sybase SQL Anywhere lets you connect for the first time.

It is important to note that this first connection, plus all subsequent connections, are only possible using the new password chosen by EndUser, and never using a password assigned by anyone else. This is a big deal, unique to SAP Sybase SQL Anywhere 16 among all relational databases.

19© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 20: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

8. Disk Sandboxing And FriendsDisk sandboxing is the ability to restrict SQL statements that do file I/O to the folder where the main database file resides plus subfolders below it.

For secure network databases that’s a cool new feature because it permits the flexibility of reading and writing external files without the risk your code will run amok across all the local and network hard drives.

It’s a cool new feature for embedded databases, too, maybe even more so... Which is worse, getting one phone call from an irate CIO, or 100 calls from irate customers, all screaming about runaway calls to sp_copy_file() and sp_move_directory() and sp_delete_file()?

Yes, the sandbox comes with built-in playmates, sp_copy_file() and the like. They’re all being lumped together as one single cool new feature because without the sandbox, the new functions might be seen as a more of a threat than a feature, and without the new functions disk sandboxing might be seen as just a solution looking for a problem. You don‘t need sandboxing to use the new functions, but you should think about it.

Here’s how disk sandboxing works: First, you use the dbsrv16 -sbx option to enable disk sandboxing when the database is started, or you use SET OPTION PUBLIC.disk_sandbox = ‘On’ to turn it on permanently for a database.

Second... that’s it, there is no Step 2.

Now you just sit back and relax, safe in the knowledge that runaway scripts will be stopped in their tracks by SQLCODE -1671:

CALL xp_write_file ( ‘c:/corporate/index.html‘, ‘im in ur base killin ur d00dz‘ );

20© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 21: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

21

Here’s a script that shows what the seven new sp_*() file I/O functions look like:

BEGIN BEGIN TRY CALL xp_write_file ( ‘c:/data/sandbox/text1.txt‘, ‘Hello, world!‘ ); CALL sp_create_directory ( ‘c:/data/sandbox/temp1‘ ); CALL sp_copy_file ( ‘c:/data/sandbox/text1.txt‘, ‘c:/data/sandbox/temp1/text1.txt‘ ); CALL sp_copy_directory ( ‘c:/data/sandbox/temp1‘, ‘c:/data/sandbox/temp2‘ ); CALL sp_move_directory ( ‘c:/data/sandbox/temp1‘, ‘c:/data/sandbox/temp3‘ ); CALL sp_move_file ( ‘c:/data/sandbox/text1.txt‘, ‘c:/data/sandbox/temp3/text4.txt‘ ); CALL sp_delete_file ( ‘c:/data/sandbox/temp3/text4.txt‘ ); CALL sp_delete_directory ( ‘c:/data/sandbox/temp3‘ ); END TRY BEGIN CATCH MESSAGE STRING ( ‘ERROR_LINE() = ‘, ERROR_LINE() ) TO CLIENT; MESSAGE STRING ( ‘ERROR_MESSAGE() = ‘, ERROR_MESSAGE() ) TO CLIENT; MESSAGE STRING ( ‘ERROR_PROCEDURE() = ‘, ERROR_PROCEDURE() ) TO CLIENT; MESSAGE STRING ( ‘ERROR_SQLCODE() = ‘, ERROR_SQLCODE() ) TO CLIENT; MESSAGE STRING ( ‘ERROR_SQLSTATE() = ‘, ERROR_SQLSTATE() ) TO CLIENT; MESSAGE STRING ( ‘ERROR_STACK_TRACE() = ‘, ERROR_STACK_TRACE() ) TO CLIENT; END CATCH;END;

Like older file I/O functions, the new ones return a numeric return code, but that return code is pretty much useless because unlike the older functions, the new ones either work, or they raise an exception:

ERROR_LINE() = 4ERROR_MESSAGE() = File or directory c:\data\sandbox\textx.txt not foundERROR_PROCEDURE() = ”dbo“.“sp_copy_file“ERROR_SQLCODE() = -1659ERROR_SQLSTATE() = 08WB9ERROR_STACK_TRACE() = : 6“dbo“.“sp_copy_file“ : 4

Yes, BEGIN TRY and BEGIN CATCH and the ERROR_blah_blah things are all new, another cool new feature, coming up next...

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 22: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

22

9. TRY CATCH And FriendsThe new BEGIN TRY BEGIN CATCH feature works exactly like the old BEGIN EXCEPTION WHEN OTHERS THEN, except it’s way less funky-looking, and it comes with a bunch of new ERROR_things() to improve diagnostics.

The phrase “exactly like” might be an exaggeration, but the fact that you can code a old RESIGNAL statement inside a BEGIN CATCH, plus the fact you can call the new ERROR_things() inside an old EXCEPTION handler, indicate otherwise.

Here’s some code to show what happens when a “Division by zero” exception bubbles up to a BEGIN CATCH exception handler at the top of a procedure call stack:

CREATE PROCEDURE p1()BEGIN DECLARE x INTEGER; DECLARE y INTEGER; SET x = 1; MESSAGE STRING ( ‘STACK_TRACE() #1 = ’, STACK_TRACE() );

SET x = x / 0;END;

CREATE PROCEDURE p2()BEGIN CALL p1();END;

CREATE PROCEDURE p3()BEGIN BEGIN TRY CALL p2(); END TRY BEGIN CATCH MESSAGE STRING ( ‘ERROR_SQLCODE() = ‘, ERROR_SQLCODE() ); MESSAGE STRING ( ‘ERROR_SQLSTATE() = ‘, ERROR_SQLSTATE() ); MESSAGE STRING ( ‘ERROR_MESSAGE() = ‘, ERROR_MESSAGE() ); MESSAGE STRING ( ‘ERROR_LINE() = ‘, ERROR_LINE() ); MESSAGE STRING ( ‘ERROR_PROCEDURE() = ‘, ERROR_PROCEDURE() ); MESSAGE STRING ( ‘ERROR_STACK_TRACE() = ‘, ERROR_STACK_TRACE() ); MESSAGE STRING ( ‘TRACEBACK() = ‘, TRACEBACK() ); MESSAGE STRING ( ‘STACK_TRACE() #2 = ‘, STACK_TRACE() ); END CATCH; MESSAGE STRING ( ‘...done‘ );END;

CALL p3();

The keywords BEGIN TRY, END TRY, BEGIN CATCH and END CATCH all go together as a single unit. You put your real code between the BEGIN TRY and END TRY, and your error diagnostics between the BEGIN CATCH and END CATCH, but nothing goes between the END TRY and BEGIN CATCH, not even a semicolon.

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 23: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

23

If you want something done with the error (display it, RESIGNAL it, whatever) it’s up to you to code it in the BEGIN CATCH, otherwise execution will proceed with the statement after the END CATCH as if nothing happened.

The ERROR_things() are all new, and so is STACK_TRACE().

TRACEBACK() isn’t new, but it might as well be new since it’s so much better in SAP Sybase SQL Anywhere 16.

Here’s what they all look like in the output:

STACK_TRACE() #1 = “DBA”.“p1” : 6“DBA”.“p2” : 3“DBA“.“p3” : 4ERROR_SQLCODE() = -628ERROR_SQLSTATE() = 22012ERROR_MESSAGE() = Division by zeroERROR_LINE() = 7ERROR_PROCEDURE() = “DBA”.“p1”ERROR_STACK_TRACE() = “DBA”.“p3” : 4“DBA”.“p2“ : 3“DBA“.“p1“ : 7TRACEBACK() = “DBA“.“p1” : 7 : set x = x/0“DBA“.“p2“ : 3 : call p1()“DBA“.“p3“ : 4 : call p2()STACK_TRACE() #2 = “DBA“.“p3“ : 14...done

Two calls to STACK_TRACE() have been included to show that this function is for active debugging rather than passive error diagnosis. The first call displayed as „STACK_TRACE() #1 =“ shows the current call stack in reverse order: STACK_TRACE() was called from line p1:6, p1 was called from line p2:3, and p2 was called from line p3:4.

The other call “STACK_TRACE() #2 =” is down at the bottom. It doesn‘t show much because there is no stack of calls at this point: STACK_TRACE() was called from line p3:14, and that’s all there is. In other words, STACK_TRACE isn’t much good inside an after-the-fact error handler.

The new ERROR_SQLCODE(), ERROR_SQLSTATE() and ERROR_MESSAGE() functions return the same values as the older SQLCODE and SQLSTATE special variables and ERRORMSG() function.

The new ERROR_LINE() and ERROR_PROCEDURE() functions tell you exactly where the error occurred: line 7 in procedure p1... well, almost exactly... a close inspection shows that ERROR_LINE() is based on the SYSPROCEDURE.proc_defn version of the source code...

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 24: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

24

1 create procedure “DBA“.“p1“()2 begin3 declare “x“ integer;4 declare “y“ integer;5 set “x“ = 1;6 message “STRING“(‘STACK_TRACE() #1 = ’,“STACK_TRACE“()) to console;7 set “x“ = “x“/08 end

...which is what gets saved and executed after SAP Sybase SQL Anywhere mangles your original code... which SAP Sybase SQL Anywhere also saves in the SYSPROCEDURE.source column:

1 create PROCEDURE p1()2 BEGIN3 DECLARE x INTEGER;4 DECLARE y INTEGER;5 SET x = 1;6 MESSAGE STRING ( ‘STACK_TRACE() #1 = ’, STACK_TRACE() );78 SET x = x / 0;9 END

In a perfect world SAP Sybase SQL Anywhere would use the code in SYSPROCEDURE.source, and ERROR_LINE() would return 8, but this is the real world, and in the real world even the venerable Execution Profiler calls it “line 7”:

The new ERROR_STACK_TRACE() function shows the complete inverse of STACK_TRACE(), a line number trace from top to bottom ending at the point of error:

ERROR_STACK_TRACE() = “DBA“.“p3“ : 4“DBA“.“p2“ : 3“DBA“.“p1“ : 7

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 25: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

25

The old TRACEBACK() function has been given a makeover in SAP Sybase SQL Anywhere 16, from this:

TRACEBACK() = set x = x/0call p1()call p2()

which everyone agreed was (cough) less-than-perfect, to this:

TRACEBACK() = “DBA“.“p1“ : 7 : set x = x/0“DBA“.“p2“ : 3 : call p1()“DBA“.“p3“ : 4 : call p2()

which is wonderful! TRACEBACK() gets my vote: more information (woohoo!) than even ERROR_STACK_TRACE(), albeit in a different (who cares?) order.

In this example, the output ends with “...done” to show that the BEGIN CATCH let processing continue; e.g., no RESIGNAL.

10. LOAD TABLE ALLOW ALL ERRORSThe LOAD TABLE statement has a well-deserved reputation for being a high-speed non-transactional method for inserting massive amounts of data in a very short time.

Unlike the INSERT statement, however, LOAD TABLE doesn’t give you the opportunity to skip over duplicate key values and carry on with the next row. LOAD TABLE is very much an all-or-nothing affair, with a single PRIMARY KEY or UNIQUE constraint violation turning it into a “nothing”.

Until now, that is. SAP Sybase SQL Anywhere 16 introduces the new ALLOW ALL ERRORS clause that tells LOAD TABLE to skip over those bad input records, plus the MESSAGE LOG and ROW LOG clauses to keep a record of what got skipped. That makes it better than INSERT because INSERT ON ERROR SKIP doesn’t handle UNIQUE constraint violations, just duplicate primary keys, and it doesn‘t keep track of the error messages or row values.

Here’s how LOAD TABLE ALLOW ALL ERRORS works:

CREATE TABLE t ( pkey INTEGER NOT NULL PRIMARY KEY, ukey INTEGER NOT NULL UNIQUE, row_number INTEGER NOT NULL );

BEGIN

DECLARE @rows LONG VARCHAR;DECLARE @message_log LONG VARCHAR;DECLARE @row_log LONG VARCHAR;

SET @rows = STRING ( ‘1, 1, 1 \x0d\x0a‘, -- OK ‘1, 2, 2 \x0d\x0a‘, -- PRIMARY KEY violation ‘3, 3, 3 \x0d\x0a‘, -- OK ‘4, 3, 4 \x0d\x0a‘ ); -- UNIQUE constraint violation

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 26: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

LOAD TABLE t USING VALUE @rows ALLOW ALL ERRORS MESSAGE LOG VARIABLE @message_log ROW LOG VARIABLE @row_log;

SELECT * FROM t ORDER BY row_number;SELECT @message_log;SELECT @row_log;

END;

The second and fourth input records contain bad data, so they don‘t get inserted:

pkey ukey row_number ----------- ----------- ----------- 1 1 1 3 3 3

The error messages are stored in the MESSAGE LOG VARIABLE, and the bad records themselves are stored in the ROW LOG VARIABLE:

@message_log----------------------------------------------------------------Primary key for table ‘t‘ is not unique: Primary key value (‘1‘)Index ‘t UNIQUE (ukey)‘ for table ‘t‘ would not be unique

@row_log--------1, 2, 2 4, 3, 4

That’s all there is to it... it’s up to you to write code to deal with the bad records, if you care, or just carry on with the good rows.

ConclusionSAP Sybase SQL Anywhere 16 isn’t one of those turn-the-world-upside-down, rewrite-the-query-processor kind of new releases, it’s more evolutionary than revolutionary. At least, that’s what it looks like to the outside world, except maybe for the big new “Performance Enhancements” and “Role-Based Security Model” features that have been (mostly) omitted from this article.

More than any other new feature, the ROW and ARRAY variable data types prove that SAP Sybase SQL Anywhere’s evolution is leading to a bright future, because that future includes ROW and ARRAY column data types.

26© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 27: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

27

Many of the other features, not just the ones described here, are focused on server-side scripts rather than database queries. If it‘s your habit to push application logic down into the server then you’re going to find a lot to like in SAP Sybase SQL Anywhere 16. And if that’s not your habit, it should be:

“...any programmer seriously interested in performance runs transactions using a stored-procedure interface, rather than SQL commands over ODBC/JDBC.” – Michael Stonebraker

About Breck CarterBreck Carter is a consultant specializing in SAP Sybase SQL Anywhere and the creator of the Foxhound database monitor for SAP Sybase SQL Anywhere. He can be reached at [email protected], his blog is at SQLAnywhere.blogspot.com, and Foxhound can be found at risingroad.com.

© 2013 SAP AG or an SAP affiliate company. All rights reserved.

Page 28: Top 10 Cool New Features In SAP® Sybase® SQL Anywhere® 16 · PDF fileSAP Sybase SQL Anywhere 16 is the first new release of SAP Sybase SQL Anywhere since ... number 15 was skipped

Copyright

© Copyright 2013 SAP AG. All rights reserved.

No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG. The information contained herein may be changed without prior notice.

Some software products marketed by SAP AG 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 Business ByDesign, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries.

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 S.A. in the United States and in other countries. Business Objects 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.

These materials are subject to change without notice. These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP Group products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty.