129
Guide to Migrating from SAP SQL Anywhere to SQL Server 2016/2017 SQL Server Technical Article Writers: Arthur Alchangian (DB Best Technologies), Igor Yefimov (DB Best Technologies), Galina Shevchenko (DB Best Technologies), Alexander Pavlov (DB Best Technologies) Technical Reviewer: Kalen Delaney (DB Best Technologies), Bill Ramos (DB Best Technologies) Published: Last updated June 22, 2017 Applies to: SQL Server 2016, SQL Server 2017 Summary: This white paper explores challenges that arise when you migrate from a SAP SQL Anywhere (also known as SQL Anywhere) database of version 9 or later to SQL Server 2016. It describes the implementation differences between the two platforms relating to database objects, SQL dialects, and procedural code. We recommend migration to SQL Server 2016 SP1 or later Express Edition as your target for SQL Anywhere solutions. The Express Edition now supports all the features that are available in SQL Server 2016. This allows you to easily scale up or move your databases to Azure SQL Database as your applications grow. Created by: DB Best Technologies LLC 2763 152 nd Ave NE, Redmond, WA 98052 Tel.: +1-855-855-3600 E-mail: [email protected] Web: www.dbbest.com

Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

  • Upload
    hakhue

  • View
    268

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Guide to Migrating from SAP SQL Anywhere to SQL Server 2016/2017

SQL Server Technical Article

Writers: Arthur Alchangian (DB Best Technologies), Igor Yefimov (DB Best Technologies), Galina Shevchenko (DB Best Technologies), Alexander Pavlov (DB Best Technologies)

Technical Reviewer: Kalen Delaney (DB Best Technologies), Bill Ramos (DB Best Technologies)

Published: Last updated June 22, 2017

Applies to: SQL Server 2016, SQL Server 2017

Summary: This white paper explores challenges that arise when you migrate from a SAP SQL Anywhere (also known as SQL Anywhere) database of version 9 or later to SQL Server 2016. It describes the implementation differences between the two platforms relating to database objects, SQL dialects, and procedural code. We recommend migration to SQL Server 2016 SP1 or later Express Edition as your target for SQL Anywhere solutions. The Express Edition now supports all the features that are available in SQL Server 2016. This allows you to easily scale up or move your databases to Azure SQL Database as your applications grow.

Created by: DB Best Technologies LLC 2763 152nd Ave NE, Redmond, WA 98052 Tel.: +1-855-855-3600 E-mail: [email protected] Web: www.dbbest.com

Page 2: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Copyright This is a preliminary document and may be changed substantially prior to final commercial release of the software described herein.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This White Paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT.

Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.

Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.

Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, email address, logo, person, place or event is intended or should be inferred.

© 2017 Microsoft Corporation. All rights reserved.

Microsoft and SQL Server are registered trademarks of Microsoft Corporation in the United States and other countries.

The names of actual companies and products mentioned herein may be the trademarks of their respective owners.

Page 3: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Contents Introduction ................................................................................................................................ 4

Conversion of Data Types .......................................................................................................... 5

Stored Procedures ..................................................................................................................... 7

CALL Statements ................................................................................................................... 7

Returning Result Sets from a Stored Procedure ..................................................................... 8

Defining Parameters ..............................................................................................................12

Selecting a Returned Value in the Calling Environment .........................................................14

Exception Handling................................................................................................................15

Flow Control Constructs ........................................................................................................19

Cursors ..................................................................................................................................26

User-Defined Functions ............................................................................................................28

CREATE FUNCTION Statement ...........................................................................................28

Statements ................................................................................................................................29

FROM Clause ........................................................................................................................29

FOR JSON clause .................................................................................................................38

Common Table Expressions ..................................................................................................39

Special INSERT Statements ..................................................................................................41

Migrating SQL Anywhere Standard Functions ...........................................................................46

Equivalent Functions .............................................................................................................46

Emulated Functions ...............................................................................................................46

Conclusion .............................................................................................................................. 128

About DB Best Technologies ............................................................................................... 128

Post Migration considerations ................................................................................................. 129

Page 4: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Introduction SAP SQL Anywhere database engine, also known as Sybase ASA, was originally designed to support desktop applications, serve as a lightweight database solution to be embedded in applications, and work for mobile solutions. SQL Server 2016 SP1 Express Edition or later is also designed to run in the same environments with much greater capabilities. Therefore, when you consider migrating your Sybase ASA/SAP SQL Anywhere solutions, first consider using the SQL Server 2016 Express Edition. And here is why:

• Express Edition is designed for web and mobile applications for multiple data types, and is built to store and support structured and unstructured data, with native support for relational data, XML, JSON, spatial data, and time data types.

• SQL Server supports a notion of a local database (SQL Server Express LocalDB), fully

compatible with SQL Server, allowing you to embed a lightweight database into applications, and run it in-process with your applications and not as a service

• SQL Server enables you to easily scale your applications across different editions.

Express Edition already comes with solid functionality: up to 4 cores, 1.4 GB maximum RAM, up to 10 GB per database, in-memory OLTP, advanced security and much more, and you can upgrade your database platform to Standard or Enterprise edition as your applications grow. Code once- deploy anywhere. SQL Server is SQL Server “Anywhere”.

This migration guide outlines problems and solutions for migrating from SAP SQL Anywhere to the Microsoft SQL Server 2016 or later. This guide explains the data type mapping and adds remarks about the related conversion issues, explores the challenges you might encounter when migrating from SAP SQL Anywhere to SQL Server 2016/2017, and offers possible solutions and examines SAP SQL Anywhere system function references, divided into equivalent functions and emulated functions.

Page 5: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Conversion of Data Types This section covers data types mapping between SQL Anywhere and SQL Server 2016. The following table shows SQL Anywhere data types and their equivalents in SQL Server 2016 including differences in data type length and ranges.

SQL Anywhere SQL Server 2016 char[(n)] 32767

varchar[(n)] n<=8000, varchar(max) n>8000

varchar[(n)] 32767 varchar[(n)] n<=8000, varchar(max) n>8000 nchar[(n)] 32767

nvarchar[(n)] n<=4000, nvarchar(max) n>4000

nvarchar[(n)] 32767 nvarchar[(n)] n<=4000, nvarchar(max) n>4000 text long varchar

varchar(max) [text has been deprecated in SQL Server]

long nvarchar nvarchar(max) xml xml bit 0,1 bit 0,1 tinyint 0…255 tinyint 0…255 smallint 2^15 – 1 smallint 2^15 - 1

unsigned smallint 2^16 - 1 integer 2^31 – 1 integer 2^31 – 1 integer 2^31 - 1

unsigned integer 2^32 - 1 bigint 2^63 – 1 bigint 2^63 - 1 bigint 2^63 - 1

unsigned bigint 2^64 – 1 numeric(20,0) decimal[(p[,s])] 127 numeric[(p[,s])] 127

decimal[(p[,s])] p<=38 numeric[(p[,s])] p<=38 float(53) p>38

float[(precision)] double real

float[(precision)] real

money +999,999,999,999,999.9999

money +922,337,203,685,477.5807 numeric(19,4) +999,999,999,999,999.9999

Page 6: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

smallmoney +999,999.9999

smallmoney +214,748.3647 numeric(10,4) +999,999.9999

date (January 1, 0001, through December 31, 9999)

date (January 1, 0001, through December 31, 9999)

datetime smalldatetime (January 1, 0001 00:00:00.000000, through December 31, 9999 23:59:59.999999 )

datetime2 (January 1, 0001 00:00:00.0000000, through December 31, 9999 23:59:59.9999999 )

time time datetimeoffset datetimeoffset

binary[(n)] 32767 binary[(n)] n<=8000, varbinary(max) n>8000 varbinary[(n)] 32767

varbinary[(n)] n<=8000, varbinary(max) n>8000

long binary image

varbinary(max)

varbit 32767 long varbit 32767

There are a few options here: • Use varbinary() and emulate type methods • Create CLR UDT with methods • Create CLR aggregate

Page 7: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Spatial data type Spatial data types are compliant with SQL MM (ISO standard). The following diagram show SQL Server spatial data types:

The instantiable types are indicated in blue.

Stored Procedures This section discusses differences between the SQL procedural language in SQL Anywhere and Microsoft SQL Server. This includes the creation and calling of stored procedures as well as working with local variables, cursors, and control-of-flow statements.

CALL Statements This section covers possible issues which can appear while converting SQL Anywhere CALL statements and offers possible solutions.

Issue: Syntax for Calling Procedures SQL Anywhere uses the CALL statement to invoke a procedure.

SQL Anywhere example:

CREATE PROCEDURE new_dept ( IN id INT, IN name CHAR(35), IN head_id INT ) BEGIN INSERT INTO DBA.department (dept_id, dept_name, dept_head_id) VALUES (id, name, head_id); END CALL new_dept(210, 'Eastern Sales', 902);

Page 8: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

Convert SQL Anywhere CALL statements to Transact-SQL EXECUTE or EXEC statements.

SQL Server example:

CREATE PROCEDURE new_dept ( @id INT, @name CHAR(35), @head_id INT ) AS BEGIN INSERT INTO DBO.department (dept_id, dept_name, dept_head_id) VALUES (@id, @name, @head_id); END; RETURN; GO -- Call the procedure EXEC new_dept 210, 'Eastern Sales', 902;

Returning Result Sets from a Stored Procedure This section contains descriptions of issues that can appear when you convert code that returns result sets from a stored procedure and possible solutions.

Issue: RESULT Keyword In SQL Anywhere, you can use the RESULT keyword to return a result set from a stored procedure and then select data from the result set. To do this, you define the keyword as a return parameter in the stored procedure.

SQL Anywhere examples:

Example 1:

CREATE PROCEDURE "DBA"."ManageContacts"(IN action char(1), IN contact_ID integer) RESULT(ID integer, Surname char(20), GivenName char(20), Street char(30), City char(20), State char(16) ) BEGIN

Page 9: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

CASE action WHEN 'S' THEN SELECT * FROM DBA.Contacts WHERE Contacts.ID=contact_ID WHEN 'D' THEN DELETE FROM DBA.Contacts WHERE Contacts.ID=contact_ID END CASE END SELECT t.Surname, t.GivenName FROM DBA.ManageContacts('S', 1) t

Example 2:

CREATE PROCEDURE "DBA"."ShowContactsByCity"(IN city char(20)) RESULT(ID integer, Surname char(20), GivenName char(20), Street char(30), City char(20), State char(16) ) BEGIN SELECT ID, Surname, GivenName, Street, City, State FROM DBA.Contacts WHERE City=city END SELECT t.Surname, t.GivenName, t.Street, t.City, t.State FROM DBA.ShowContactsByCity('Atlanta') t

Solution:

Replace the RESULT keyword with a temporary table defined in a calling code and insert the returned result set into this temporary table. Then you can execute queries on the table and apply WHERE clauses and other SELECT features to limit the result set.

If there are no Data Manipulation Language (DML) statements in the source stored procedure body, consider using a SQL Server table-valued function as an alternative to the procedure. Note that SQL Server does not allow the use of side-effecting DML operators within a function.

SQL Server examples:

Example 1:

CREATE PROCEDURE DBO.ManageContacts(@action char(1),

Page 10: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

@contact_ID int) BEGIN IF @action = 'S' SELECT * FROM DBO.Contacts WHERE Contacts.ID=@contact_ID; IF @action = 'D' DELETE FROM DBO.Contacts WHERE Contacts.ID=@contact_ID; END; RETURN; GO -- Create a temporary table CREATE TABLE #temp_result( ID int, Surname char(20), GivenName char(20), Street char(30), City char(20), State char(16) ); GO -- Call the procedure to populate the table INSERT INTO #temp_result EXEC dbo.ManageContacts 'S', 1; GO -- Select from the temporary table SELECT Surname, GivenName FROM #temp_result; GO

Example 2:

This example does not contain DML operators that change tables, so it can be emulated using table-valued functions in SQL Server:

CREATE FUNCTION DBO.ShowContactsByCity(@city char(20)) RETURNS @result TABLE ( ID int, Surname char(20), GivenName char(20), Street char(30), City char(20), [State] char(16) ) AS BEGIN

Page 11: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

INSERT @result SELECT ID, Surname, GivenName, Street, City, [State] FROM DBO.Contacts WHERE City=@city; RETURN ; END; -- Call the function: SELECT Surname, GivenName, Street, City, [State] FROM DBO.ShowContactsByCity('Atlanta'); GO

Issue: NO RESULT SET Clause The NO RESULT SET clause declares that no result set is returned by this procedure. This is useful when an external environment needs to know that a procedure does not return a result set.

SQL Anywhere example:

CREATE PROCEDURE ProductType (IN product_ID INT, OUT type CHAR(10)) NO RESULT SET BEGIN DECLARE prod_name CHAR(20); SELECT name INTO prod_name FROM GROUPO.Products WHERE ID = product_ID; CASE prod_name WHEN 'Tee Shirt' THEN SET type = 'Shirt' WHEN 'Sweatshirt' THEN SET type = 'Shirt' WHEN 'Baseball Cap' THEN SET type = 'Hat' WHEN 'Visor' THEN SET type = 'Hat' WHEN 'Shorts' THEN SET type = 'Shorts' ELSE SET type = 'UNKNOWN' END CASE; END; declare @v_type CHAR(10); call ProductType(1, @v_type);

Page 12: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

SQL Server does not have any means inside a procedure definition to indicate whether a result set is returned from the procedure. So, the solution is to remove this clause from the procedure definition and optionally use the WITH RESULT SETS NONE option of the EXECUTE statement when calling the procedure.

SQL Server example:

CREATE PROCEDURE ProductType (@product_ID INT, @type CHAR(10) OUTPUT) AS BEGIN DECLARE @prod_name CHAR(20); SELECT @prod_name = Name FROM GROUPO.Products WHERE ID = @product_ID; SELECT @type = CASE @prod_name WHEN 'Tee Shirt' THEN 'Shirt' WHEN 'Sweatshirt' THEN 'Shirt' WHEN 'Baseball Cap' THEN 'Hat' WHEN 'Visor' THEN 'Hat' WHEN 'Shorts' THEN 'Shorts' ELSE 'UNKNOWN' END; END; RETURN; GO -- Call the procedure DECLARE @v_type CHAR(10); EXECUTE ProductType 1, @v_type WITH RESULT SETS NONE; GO

Defining Parameters This section contains description of issues that can appear when you convert parameters of stored procedures and possible solutions.

Issue: IN, OUT, and INOUT Keywords to Define Parameters The keywords IN, OUT, and INOUT are used in SQL Anywhere syntax.

SQL Anywhere example:

CREATE PROCEDURE AverageSalary( IN dept INTEGER,

Page 13: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

OUT avgsal NUMERIC (20,3) ) BEGIN SELECT AVG( salary ) INTO avgsal FROM employee where department_id = dept; END

Solution:

Ignore the keyword IN, and replace OUT and INOUT keywords with the OUTPUT keyword in SQL Server. OUTPUT parameters combine functions of both input and output parameters in SQL Server syntax.

SQL Server example:

CREATE PROCEDURE AverageSalary( @dept INT, @avgsal NUMERIC (20,3) OUTPUT) AS BEGIN SELECT @avgsal = AVG( salary ) FROM employee where department_id = @dept; END; RETURN; GO

Issue: DEFAULT Parameters The DEFAULT keyword provides a default value for the parameter in SQL Anywhere.

SQL Anywhere example:

CREATE PROCEDURE CustomerProducts( IN cust CHAR(50) DEFAULT NULL ) RESULT ( product_id INTEGER, quantity INTEGER ) BEGIN IF cust IS NULL THEN RETURN; ELSE SELECT product_id, quantity FROM product WHERE customer = cust ORDER BY product_id; END IF; END

Page 14: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

Replace the DEFAULT keyword with “=” sign.

SQL Server example:

CREATE PROCEDURE CustomerProducts( @cust char(50) = NULL) as BEGIN IF @cust IS NULL RETURN; ELSE SELECT product_id, quantity FROM product WHERE customer = @cust ORDER BY product_id; END; RETURN; GO

Selecting a Returned Value in the Calling Environment This section covers issues which can appear while converting code selecting returned values of routines and offers possible solutions.

Issue: Different Syntax for Selecting the Value Returned from a Stored Procedure by a RETURN Statement SQL Server syntax does not support the expression in the following form:

returnvalue = CALL myproc();

SQL Anywhere example:

CREATE VARIABLE v1 CHAR(20); CREATE VARIABLE returnval INTEGER; returnval = CALL SampleProc(v1);

Solution:

Use SQL Server syntax to select the value returned from a stored procedure:

EXEC @returnvalue = myproc;

Page 15: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server example:

DECLARE @v1 CHAR(20); DECLARE @returnval INT; EXEC @returnval = SampleProc @v1;

Exception Handling This section covers conversion of exception handling and contains possible solutions for conversion issues.

Issue: ON EXCEPTION RESUME Clause If the ON EXCEPTION RESUME clause appears in the CREATE PROCEDURE or CREATE FUNCTION statement in SQL Anywhere, the routine either will continue executing after an error or it will exit, depending on the ON_TSQL_ERROR option settings. SQL Server does not have an ON EXCEPTION RESUME clause in the CREATE PROCEDURE statement. Thus, the procedure stops executing after an error; there is no option to skip the statement that caused the error and then resume.

SQL Anywhere example:

CREATE PROCEDURE "DBA"."OuterProc"() ON EXCEPTION RESUME BEGIN DECLARE res CHAR(5); MESSAGE 'Hello from OuterProc.' TO CLIENT; CALL InnerProc(); SET res=SQLSTATE; IF res='52003' THEN MESSAGE 'SQLSTATE set to ', res, ' in OuterProc.' TO CLIENT; END IF END CREATE PROCEDURE "DBA"."InnerProc"() ON EXCEPTION RESUME BEGIN DECLARE column_not_found EXCEPTION FOR SQLSTATE '52003'; MESSAGE 'Hello from InnerProc.' TO CLIENT; SIGNAL column_not_found; MESSAGE 'SQLSTATE set to ', SQLSTATE, ' in InnerProc.' TO CLIENT; END

Page 16: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

CALL OuterProc();

Solution:

This SQL Anywhere behavior can be emulated by the SQL Server TRY…CATCH block. To use this block, place the code that can generate an error into a BEGIN TRY…END TRY block. Then place the code to be executed in case of an error into a BEGIN CATCH…END CATCH block.

To emulate SQL Anywhere behavior completely, put each statement that can generate an error in TRY block and then add an empty CATCH block after each of them.

SQL Server example:

To emulate SQL Anywhere error handling similar to the example above, create a new message in the sys.messages system table in SQL Server. User-defined error messages must have a message_id value that is greater than 50000. Use sp_addmessage system procedure to create a message, for example:

EXEC sp_addmessage '52003', 16, 'column_not_found'; -- Create the outer procedure; You will get a dependency warning about -- the inner procedure not existing CREATE PROCEDURE OuterProc AS BEGIN BEGIN TRY DECLARE @res CHAR(10); PRINT 'Hello from OuterProc.'; EXEC InnerProc; END TRY BEGIN CATCH SELECT @res = ERROR_NUMBER(); IF @res = CAST (52003 as CHAR(10)) PRINT CONCAT('SQLSTATE set to ', @res, ' in OuterProc.'); END CATCH END; GO -- Create the inner procedure CREATE PROCEDURE InnerProc AS BEGIN PRINT 'Hello from InnerProc.'; RAISERROR (52003, 16, 1)

Page 17: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

PRINT CONCAT('SQLSTATE set to ', CAST (ERROR_NUMBER() as VARCHAR (10)), ' in InnerProc.'); END; GO -- Call the outer procedure EXEC OuterProc; GO

Issue: DECLARE EXCEPTION and SIGNAL Statement In SQL Anywhere, the DECLARE statement in the procedure declares a symbolic name for one of the predefined SQLSTATE values associated with error conditions already known to the server. The SIGNAL statement generates an error condition from within the procedure.

SQL Anywhere example:

CREATE PROCEDURE SampleProc() BEGIN DECLARE column_not_found EXCEPTION FOR SQLSTATE '52003'; SIGNAL column_not_found; END

Solution:

Ignore the DECLARE statement. Use the RAISERROR statement instead of SIGNAL to generate an error from within the procedure. A severity level value that is greater than 10 denotes errors; a value that is less than or equal to 10 denotes informational messages, which can be used to emulate SQL Anywhere warnings.

SQL Server example:

CREATE PROCEDURE SampleProc AS BEGIN RAISERROR ('column_not_found', 16, 1); END; RETURN; GO

Issue: Exception Handling In SQL Anywhere, the EXCEPTION statement is used to handle errors.

Page 18: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

CREATE PROCEDURE SampleProc() BEGIN DECLARE column_not_found EXCEPTION FOR SQLSTATE '52003'; IF <condition> THEN SIGNAL column_not_found; END IF; EXCEPTION WHEN column_not_found THEN <statements> WHEN OTHERS THEN <other statements> END END

Solution:

Replace the EXCEPTION block with a TRY…CATCH block in SQL Server.

SQL Server example:

CREATE PROCEDURE SampleProc AS BEGIN BEGIN TRY IF <condition> RAISERROR ('column_not_found', 16, 1); END TRY BEGIN CATCH IF ERROR_MESSAGE() = 'column_not_found' BEGIN <statements>; END; ELSE <other statements>; END CATCH; END; RETURN;

Issue: RESIGNAL Statement The RESIGNAL statement passes the exception on to a higher-level exception handler.

Page 19: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

Suppose that the procedure from the previous example has the following EXCEPTION block:

… EXCEPTION WHEN column_not_found THEN <statements> WHEN OTHERS THEN RESIGNAL; Solution:

Declare a local variable to store the text of the generated exception. Assign this variable the value of the SQL Server ERROR_MESSAGE() function in the beginning of the CATCH block. Repeat the RAISERROR statement that generated the exception, and then pass the variable to it as it is shown in the following example.

SQL Server example:

CREATE PROCEDURE SampleProc AS BEGIN DECLARE @message NVARCHAR (4000) BEGIN TRY IF <condition> RAISERROR ('column_not_found', 16, 1); END TRY; BEGIN CATCH SET @message = ERROR_MESSAGE() ; IF @message = 'column_not_found' BEGIN <statements>; END ELSE RAISERROR (@message, 16, 1); END CATCH; END; RETURN;

Flow Control Constructs This section covers conversion of flow-control constructs from SQL Anywhere to SQL Server. It contains possible issues that can appear during the conversion and offers solutions.

Page 20: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Issue: BEGIN ATOMIC Statement An atomic block guarantees that the statements are transactional; they either all succeed or none of them do. If there is already an open transaction for the session, BEGIN ATOMIC creates a savepoint; otherwise, it will start a transaction.

SQL Anywhere example:

BEGIN ATOMIC UPDATE Employee SET manager_ID = 501 WHERE emp_ID = 467; INSERT dbo.Employee values(467, 3, 'Tom', 'Robbins', getdate()); END

INSERT statement in the above example violates primary key constraint, so the entire block will be rolled back.

Solution:

Use the Transact-SQL statements BEGIN TRAN[SACTION] and COMMIT TRAN[SACTION] inside TRY…CATCH block to denote that the statements must be executed entirely.

SQL Server example:

DECLARE @TranName VARCHAR(20); SELECT @TranName = 'MyTransaction'; BEGIN TRY -- Check if there is already an open transaction IF @@trancount = 0 BEGIN TRANSACTION @TranName ELSE SAVE TRANSACTION @TranName UPDATE Employee SET manager_ID = 501 WHERE emp_ID = 467; INSERT dbo.Employee values(467, 3, 'Tom', 'Robbins', getdate()); COMMIT TRANSACTION @TranName; END TRY; BEGIN CATCH ROLLBACK TRANSACTION @TranName; END CATCH;

Page 21: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Note:

Starting with SQL Server 2014, natively compiled stored procedures support atomic blocks (BEGIN ATOMIC WITH…) which is executed (atomically) within the transaction. Either all statements in the block succeed or the entire block will be rolled back to the savepoint that was created at the start of the block.

Issue: IF Statement SQL Anywhere and SQL Server have different syntax for the IF statement.

SQL Anywhere example:

if (1>2) then select 'A'; select 'B'; elseif (2>3) then select 'C'; select 'D'; elseif (3>4) then select 'E'; select 'F'; else select 'G'; select 'H'; end if;

Solution:

The SQL Anywhere IF statement can be easily emulated in SQL Server.

SQL Server example:

IF (1>2) BEGIN SELECT 'A'; SELECT 'B'; END ELSE IF (2>3) BEGIN SELECT 'C'; SELECT 'D'; END; ELSE IF (3>4) BEGIN SELECT 'E'; SELECT 'F'; END; ELSE BEGIN SELECT 'G'; SELECT 'H'; END;

Issue: CASE Statement SQL Anywhere and SQL Server have different syntax for the CASE construct. In SQL Server, CASE is an expression, not a statement, and can be used to determine the value to return, as opposed to the action to be performed.

SQL Anywhere example:

case int_value when 1 then select 'A'; select 'AA'; when 2 then select 'B';

Page 22: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

when 1 then select 'A1'; select 'A2'; -- ignored when 3 then select 'C'; else select NULL; end case;

Solution:

CASE statements can be emulated by using SQL Server IF statements.

SQL Server example:

IF @INT_VALUE = 1 BEGIN SELECT 'A'; SELECT 'AA'; END; ELSE IF @INT_VALUE = 2 BEGIN SELECT 'B'; END; ELSE IF @INT_VALUE = 1 BEGIN SELECT 'A1'; SELECT 'A2'; END; ELSE IF @INT_VALUE = 3 BEGIN SELECT 'C'; END; ELSE BEGIN SELECT NULL; END; Alternatively, if each CASE option selects a single value, you could use a CASE expression in SQL Server.

SQL Server CASE example:

These two constructs are equivalent. Each option returns only a single value.

IF @INT_VALUE = 1 BEGIN SELECT 'A'; END; ELSE IF @INT_VALUE = 2 BEGIN SELECT 'B'; END; ELSE IF @INT_VALUE = 1 BEGIN SELECT 'A1'END; ELSE IF @INT_VALUE = 3 BEGIN SELECT 'C'; END; ELSE BEGIN SELECT NULL; END; -- Can be rewritten as follows SELECT CASE @int_value WHEN 1 THEN 'A' WHEN 2 THEN 'B' WHEN 1 THEN 'A1' WHEN 3 THEN 'C' ELSE 'NULL' END;

Issue: LOOP Statements SQL Server does not have the LOOP keyword.

Page 23: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

... SET i = 1; WHILE i <= 10 LOOP INSERT INTO Counters( number ) VALUES ( i ); SET i = i + 1; END LOOP; ...

Solution:

If a LOOP statement in SQL Anywhere code is a WHILE LOOP, remove the LOOP keyword and enclose the statements inside the WHILE in a BEGIN…END block.

SQL Server example:

... SET @i = 1 WHILE @i <= 10 BEGIN INSERT INTO Counters( number ) VALUES ( @i ); SET @i = @i + 1; END ; ...

Issue: LEAVE Statement and Labeled Loop SQL Server does not have equivalent statements. The first SQL Anywhere example shows a LEAVE statement, and the second example shows nested loops.

SQL Anywhere examples:

Example 1:

SET i = 1; lbl: LOOP INSERT INTO Counters( number ) VALUES ( i ); IF i >= 10 THEN LEAVE lbl; END IF; SET i = i + 1;

Page 24: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

END LOOP lbl

Example 2:

outer_loop: LOOP SET i = 1; inner_loop: LOOP ... SET i = i + 1; IF i >= 10 THEN LEAVE outer_loop END IF END LOOP inner_loop END LOOP outer_loop

Solution:

If a LOOP statement in SQL Anywhere code is a labeled loop that contains a LEAVE statement, use a Transact-SQL WHILE … BREAK statement to achieve similar results. If there are nested loops and a LEAVE statement inside a nested loop, use a Transact-SQL GOTO statement.

SQL Server examples:

Example 1:

SET @i = 1; WHILE 1=1 BEGIN INSERT INTO Counters( number ) VALUES ( @i ); IF @i >= 10 BREAK; SET @i = @i + 1; END;

Example 2:

DECLARE @i INT WHILE 1=1 BEGIN SET @i = 1; WHILE 1=1 BEGIN ...

Page 25: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SET @i = @i + 1; IF @i >= 10 BEGIN GOTO _mark; END END END _mark:

Issue: FOR Cursor Loop SQL Server does not have a comparable statement, however a workaround is possible.

SQL Anywhere example:

FOR cur_loop AS cur CURSOR FOR SELECT emp_lastname FROM employee DO CALL find_name( emp_lastname ); END FOR;

Solution:

The FOR cursor loop can be replaced by a set of Transact-SQL statements including declaring and opening a cursor and fetching the cursor row values into local variables in a WHILE loop.

SQL Server example:

DECLARE cur CURSOR FOR SELECT emp_lastname FROM employee; DECLARE @emp_lastname VARCHAR(50); OPEN cur; FETCH NEXT FROM cur INTO @emp_lastname; WHILE @@FETCH_STATUS = 0 BEGIN EXEC find_name @emp_lastname; FETCH NEXT FROM cur INTO @emp_lastname; END;

Page 26: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Cursors This section contains description of issues that can appear when you convert SQL Anywhere cursors and possible solutions.

Issue: WITH HOLD Clause The SQL Server OPEN statement for opening a cursor does not have a WITH HOLD clause, however a workaround is possible.

SQL Anywhere example:

OPEN cursor_name WITH HOLD Solution:

In SQL Anywhere, all cursors are automatically closed at the end of the current transaction (COMMIT or ROLLBACK). The optional WITH HOLD clause keeps the cursor open for subsequent transactions. To emulate this SQL Anywhere behavior you can use cursor variables or global cursors. In SQL Server, a global cursor remains open until it is explicitly closed.

Issue: ISOLATION LEVEL Clause SQL Server OPEN statement for opening a cursor does not have an ISOLATION LEVEL clause.

SQL Anywhere example:

OPEN cursor_name ISOLATION LEVEL 2

Solution:

The transaction locking behavior of a specific cursor in SQL Server is determined by combining the locking behaviors of the cursor concurrency setting, any locking hints specified in the cursor SELECT, and transaction isolation level options.

Issue: "No Data" Cursor State SQL Anywhere requires a handler for an exception with SQLSTATE value 02000 to detect a "No Data" cursor state.

Page 27: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

CREATE PROCEDURE EmployeeName() BEGIN DECLARE no_data EXCEPTION FOR SQLSTATE '02000'; DECLARE last_name CHAR(50); DECLARE cur CURSOR FOR SELECT emp_lastname FROM employee; OPEN ThisCompany; EmployeeLoop: LOOP FETCH NEXT cur INTO last_name; IF SQLSTATE = no_data THEN LEAVE EmployeeLoop; END IF; CALL find_name( emp_lastname ); END LOOP EmployeeLoop; CLOSE ThisCompany; END

Solution:

Instead of checking the SQLSTATE value, check the @@FETCH_STATUS system variable value for your SQL Server connection. If it is equal to 0, continue fetching the cursor rows in a WHILE loop.

SQL Server example:

CREATE PROCEDURE EmployeeName AS BEGIN DECLARE @last_name VARCHAR(50); DECLARE cur CURSOR FOR SELECT emp_lastname FROM employee; OPEN cur; FETCH NEXT FROM cur INTO @last_name;

Page 28: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

WHILE @@FETCH_STATUS = 0 BEGIN EXEC find_name @last_name; FETCH NEXT FROM cur INTO @last_name; END; CLOSE emp; DEALLOCATE emp; END;

User-Defined Functions This section discusses differences between the syntax of user-defined functions in SQL Anywhere and Microsoft SQL Server.

CREATE FUNCTION Statement This section covers issues and solutions for conversion of the CREATE FUNCTION statement.

Issue: [NOT] DETERMINISTIC Clause The SQL Server CREATE FUNCTION statement does not allow a [NOT] DETERMINISTIC clause. SQL Server automatically detects if the function is deterministic or not.

Solution:

Skip this clause. SQL Server automatically analyzes the body of Transact-SQL functions and evaluates whether the function is deterministic. The alternative is to replace the function with a stored procedure.

Page 29: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Statements This section discusses differences between various constructs used in SQL DML statements in SQL Anywhere and Microsoft SQL Server.

FROM Clause This section covers issues and solutions for conversion of FROM clauses.

Issue: FORCE INDEX (index-name) SQL Server does not have a FORCE INDEX option in the FROM clause, however a workaround is possible.

SQL Anywhere example:

SELECT OrderDate, SalesRepresentative FROM SalesOrders FORCE INDEX (IX_SalesRepresentative_EmployeeID)

Solution:

Replace this clause with the WITH (INDEX ( index_name [ ,...n ] )) table hint in SQL Server.

SQL Server example:

SELECT OrderDate, SalesRepresentative FROM SalesOrders WITH (INDEX (IX_SalesRepresentative_EmployeeID));

Issue: WITH (column-name data-type, ... ) in Selecting from a function The WITH clause provides a way of specifying column name aliases for the function result set. The WITH clause is not used with functions in SQL Server.

SQL Anywhere example:

SELECT sp.CompanyName FROM DBA.ShowCustomers() WITH (ID integer,CompanyName char(30)) sp

Solution:

Page 30: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Insert the results returned from the stored procedure into a temporary table. Then perform select operations on the temporary table. Ignore the WITH clause.

SQL Server example:

create table #temp( ID int, CompanyName char(30) ) INSERT INTO #temp EXEC dbo.ShowCustomers SELECT CompanyName FROM #temp

Issue: Lateral Derived Table SQL Anywhere provides a lateral derived table if you want to use an outer reference in the FROM clause. SQL Server does not have the LATERAL keyword and does not support the concept of lateral derived tables, however a workaround is possible.

SQL Anywhere example:

SELECT v.Product_id, v.BeginDate, CONVERT(date, CASE WHEN l.LastDate IS NULL THEN NULL ELSE DateAdd(dd, -1, l.LastDate) END) AS EndDate, v.Value FROM ProductValue v, LATERAL ( SELECT Min(BeginDate) as LastDate FROM ProductValue WHERE Product_id = v.Product_id AND BeginDate > v.BeginDate ) as l;

Solution:

Rewrite the query with a lateral derived table by means of SQL Server outer joins. The outer and inner tables are joined and the condition specified in the WHERE clause is converted to an ON clause.

SQL Server example:

Page 31: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT v.Product_id, v.BeginDate, CONVERT(date, CASE WHEN Min(l.BeginDate) IS NULL THEN NULL ELSE DateAdd(dd, -1, Min(l.BeginDate)) END) AS EndDate, v.Value FROM ProductValue v LEFT OUTER JOIN ProductValue l ON l.Product_id = v.Product_id AND l.BeginDate > v.BeginDate GROUP BY v.Product_id, v.BeginDate, v.Value;

Issue: FASTFIRSTROW Table Hint The FASTFIRSTROW table hint tells the optimizer to find a plan that will minimize the time to return the first row of results, even if the time to return ALL the results is longer.

SQL Anywhere example:

SELECT Year, Quarter, Code, Amount from FinancialData WITH (FASTFIRSTROW);

Solution:

The SQL Anywhere FASTFIRSTROW hint is equivalent to OPTION (FAST 1) in SQL Server. Replace FASTFIRSTROW table hint with the OPTION (FAST 1) query hint.

SQL Server example:

SELECT Year, Quarter, Code, Amount FROM FinancialData OPTION (FAST 1);

Issue: FIRST Keyword The FIRST keyword is used in SQL Anywhere to limit the number of rows included in the result set of a query.

SQL Anywhere example:

SELECT FIRST * FROM employee ORDER BY emp_lname

Solution:

Page 32: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

The keyword TOP with a value equal to 1 can be used in SQL Server instead of FIRST.

SQL Server example:

SELECT TOP 1 * FROM employee ORDER BY emp_lname;

Issue: START AT Keyword The START AT keyword used with TOP provides an offset during results selection in SQL Anywhere.

SQL Anywhere example:

SELECT TOP 2 START AT 5 * FROM employee ORDER BY emp_lname DESC

Solution:

In SQL Server you have to use OFFSET/FETCH clause.

SQL Server example:

SELECT * FROM employee ORDER BY emp_lname DESC OFFSET 4 ROWS FETCH NEXT 2 ROWS ONLY;

Issue: EXCEPT ALL and INTERSECT ALL Operators In SQL Anywhere, both EXCEPT and INTERSECT take the ALL modifier, which prevents the elimination of duplicate rows from the result set. SQL Server EXCEPT and INTERSECT operators return distinct values and do not take an ALL modifier.

SQL Anywhere examples:

Example 1:

SELECT col1, col2 FROM T1

Page 33: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

INTERSECT ALL SELECT col1, col2 FROM T2

Example 2:

SELECT col1, col2 FROM T1 EXCEPT ALL SELECT col1, col2 FROM T2 Solution:

In SQL Server, emulate INTERSECT ALL and EXCEPT ALL by using an additional numeric column (refered to in this example as Tmp$Num) with INTERSECT and EXCEPT as shown:

select <select_columns_or_alias> from ( select <first_select_columns_with_alias>, row_number() over(partition by <first_select_columns_without_alias> order by (select 1)) as Tmp$Num from ... { intersect | except } select <second_select_columns_with_alias>, row_number() over(partition by <second_select_columns_without_alias> order by (select 1)) as Tmp$Num from ... ) <sub query table name>

All duplicate rows are numbered in both SELECT statements in the new column Tmp$Num. This set no longer contains duplicates, and INTERSECT or EXCEPT can be used on the result sets now. Then the result is selected without the Tmp$Num column.

SQL Server examples:

Example 1:

SELECT col1, col2 FROM ( SELECT col1, col2, ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY (SELECT 1)) AS Tmp$Num FROM T1 INTERSECT SELECT col1, col2, ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY (SELECT 1)) AS Tmp$Num FROM T2 ) r3

Example 2:

Page 34: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT col1, col2 FROM ( SELECT col1, col2, ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY (SELECT 1)) AS Tmp$Num FROM T1 EXCEPT SELECT col1, col2, ROW_NUMBER() OVER(PARTITION BY col1, col2 ORDER BY (SELECT 1)) AS Tmp$Num FROM T2 ) r3

Issue: EXCEPT DISTINCT, INTERSECT DISTINCT, and UNION DISTINCT Operators SQL Anywhere allows EXCEPT DISTINCT and INTERSECT DISTINCT to eliminate duplicate rows before the intersection or exception between the result sets is computed.

SQL Anywhere examples:

Example 1:

SELECT col1, col2 FROM T1 INTERSECT DISTINCT SELECT col1, col2 FROM T2

Example 2:

SELECT col1, col2 FROM T1 EXCEPT DISTINCT SELECT col1, col2 FROM T2

Example 3:

SELECT col1, col2 FROM T1 UNION DISTINCT SELECT col1, col2 FROM T2

Solution:

The SQL Anywhere EXCEPT DISTINCT operator is identical to EXCEPT and INTERSECT. DISTINCT is identical to INTERSECT. UNION DISTINCT is identical to UNION. Use EXCEPT, INTERSECT, and UNION without the DISTINCT keyword in SQL Server.

Page 35: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server examples:

Example 1:

SELECT col1, col2 FROM T1 INTERSECT SELECT col1, col2 FROM T2;

Example 2:

SELECT col1, col2 FROM T1 EXCEPT SELECT col1, col2 FROM T2;

Example 3:

SELECT col1, col2 FROM T1 UNION SELECT col1, col2 FROM T2;

Issue: Non-ANSI Joins SQL Anywhere supports non-ANSI outer join syntax (*= or =*).

SQL Anywhere example:

SELECT first_name, last_name, order_date, quantity FROM customers, sales_orders WHERE customers.id *= sales_orders.customer_id ORDER BY order_date

Solution:

Rewrite the joins to ANSI format. If the specified condition is (*=), consider using a LEFT OUTER JOIN. If the condition is (=*), consider using a RIGHT OUTER JOIN.

SQL Server example:

Page 36: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT first_name, last_name, order_date, quantity FROM customers LEFT OUTER JOIN sales_orders ON customers.id = sales_orders.customer_id ORDER BY order_date

Issue: NATURAL Joins If a natural join is specified, SQL Anywhere generates a join condition based on columns with the same name.

SQL Anywhere example:

SELECT first_name, last_name, dept_name FROM employees NATURAL JOIN departments

Solution:

Convert NATURAL to INNER, and add an ON clause specifying equality conditions for all columns of the two tables that have the same name. In this example, we assume that emp_id is the only column between the two tables with the same name.

SQL Server example:

SELECT first_name, last_name, dept_name FROM employees INNER JOIN departments ON employees.emp_id = departments.emp_id;

Issue: Natural Joins with an ON Clause If both a NATURAL JOIN and a join condition are specified in an ON clause in SQL Anywhere, the result is the conjunction of the two join conditions.

SQL Anywhere example:

SELECT first_name, last_name, dept_name FROM employees NATURAL JOIN departments ON employee.manager_id = department.dept_head_id

Solution:

Add an equality condition to the ON clause for all columns of two tables that have the same name.

Page 37: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server example:

SELECT first_name, last_name, dept_name FROM employees INNER JOIN departments ON employees.manager_id = departments.dept_head_id AND employees.emp_id = departments.emp_id;

Issue: KEY Joins If a key join is specified, SQL Anywhere generates a join condition based on the foreign key relationships in the database. A key join is the default if only the keyword JOIN is used.

SQL Anywhere example:

SELECT * FROM product KEY JOIN sales_order_items SELECT employee.emp_lname, ky_dept_id.dept_name FROM (employee KEY JOIN department as ky_dept_id) KEY JOIN sales_order

Solution:

Convert KEY to INNER and add an ON clause with equality conditions for the columns that define a foreign key relationship between the two tables.

SQL Server example:

SELECT * FROM product INNER JOIN sales_order_items ON sales_order_items.prod_id = product.id; SELECT employee.emp_lname, department.dept_name FROM (employee INNER JOIN department ON employee.dept_id = department.dept_id ) INNER JOIN sales_order ON employee.emp_id = sales_order.sales_rep

Issue: Key Joins with an ON phrase If both a KEY JOIN and a join condition are specified in an ON phrase in SQL Anywhere, the result is the conjunction of the two join conditions.

Page 38: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT * FROM A KEY JOIN B ON A.x = B.y

Solution:

Add an equality condition to the ON ckause for the columns that define a foreign key relationship between the two tables.

SQL Server example:

SELECT * FROM A JOIN B ON A.x = B.y AND A.w = B.z;

FOR JSON clause This section contains description of issues that can appear when you convert SQL Anywhere FOR JSON clause to retrieve query results as JSON.

Issue: Using FOR JSON RAW in a query When FOR JSON RAW is specified in a query, each row is returned as a flattened JSON representation. SQL Server FOR JSON clause does not have RAW mode.

SQL Anywhere example:

SELECT p.Name, p.Description, p.Color, so.Quantity AS ItemsSold FROM Products p JOIN SalesOrders so ON p.ID = so.ProductID FOR JSON RAW; Solution:

In SQL Server, use the PATH mode of the FOR JSON clause without output formatting options.

SQL Server example:

SELECT p.Name, p.Description, p.Color, so.Quantity AS ItemsSold FROM Products p JOIN SalesOrders so ON p.ID = so.ProductID

Page 39: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

FOR JSON PATH;

Issue: Using FOR JSON EXPLICIT in a query When FOR JSON EXPLICIT is used in a query it allows you to specify columns as simple values, objects, and nested hierarchical objects to produce different arrays. SQL Server FOR JSON clause does not have an EXPLICIT mode.

SQL Anywhere example:

SELECT 1 AS TAG, NULL AS PARENT, p.Name AS [!1!Name], p.Description AS [!1!Description], p.Color AS [!1!Color], so.Quantity AS [!1!ItemsSold] FROM Products p JOIN SalesOrders so ON p.ID = so.ProductID FOR JSON EXPLICIT;

Solution:

In SQL Server, use the PATH mode of the FOR JSON clause with specifying JSON path in column aliases of the query which allows creating wrapper objects, nesting properties and maintains full control over the output of the FOR JSON clause.

SQL Server example:

SELECT p.Name as 'Name', p.Description as 'Description', p.Color as 'Color', so.Quantity as 'ItemsSold' FROM Products p JOIN SalesOrders so ON p.ID = so.ProductID FOR JSON PATH;

Common Table Expressions This section covers issues and solutions for conversion of SQL Anywhere common table expressions, including recursive ones.

Page 40: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Issue: Common Table Expressions in an INSERT Statement Common table expressions are permitted within a top-level SELECT statement in an INSERT statement in SQL Anywhere. SQL Server requires that the definition of the common table expression be the first thing in the statement.

SQL Anywhere example:

INSERT INTO employees (last_name, first_name, city) WITH contacts_cte(surname, givenname, city) AS ( SELECT surname, givenname, city FROM contacts) SELECT surname, givenname, city FROM contacts_cte WHERE city != 'Atlanta'

Solution:

Place the INSERT clause after the definition of the common table expression.

SQL Server example:

WITH contacts_cte(surname, givenname, city) AS ( SELECT surname, givenname, city FROM contacts) INSERT INTO employees (last_name, first_name, city) SELECT surname, givenname, city FROM contacts_cte WHERE city != 'Atlanta';

Issue: RECURSIVE Keyword in Common Table Expressions SQL Anywhere syntax requires that you specify the keyword RECURSIVE when writing recursive queries by means of common table expressions. In SQL Server, common table expressions do not require this specification and recursion is specified by how the common table expression is used.

SQL Anywhere example:

WITH RECURSIVE manager ( emp_id, mangr_id, emp_fname, emp_lname, mgmt_level ) AS ( ( SELECT emp_id, mangr_id, emp_fname, emp_lname, 0

Page 41: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

FROM employee AS e WHERE mangr_id = emp_id ) UNION ALL ( SELECT e.emp_id, e.mangr_id, e.emp_fname, e.emp_lname, m.mgmt_level + 1 FROM employee AS e JOIN manager AS m ON e.mangr_id = m.emp_id AND e.mangr_id <> e.emp_id AND m.mgmt_level < 20 ) ) SELECT * FROM manager ORDER BY mgmt_level, emp_lname, emp_fname

Solution:

Ignore the keyword RECURSIVE and use a CTE query as follows.

SQL Server example:

WITH manager ( emp_id, mangr_id, emp_fname, emp_lname, mgmt_level ) AS ( ( SELECT emp_id, mangr_id, emp_fname, emp_lname, 0 FROM employee AS e WHERE mangr_id = emp_id ) UNION ALL ( SELECT e.emp_id, e.mangr_id, e.emp_fname, e.emp_lname, m.mgmt_level + 1 FROM employee AS e JOIN manager AS m ON e.mangr_id = m.emp_id AND e.mangr_id <> e.emp_id AND m.mgmt_level < 20 ) ) SELECT * FROM manager ORDER BY mgmt_level, emp_lname, emp_fname;

Special INSERT Statements This section covers issues and solutions for conversion of SQL Anywhere INSERT statements with some special options.

Issue: WITH AUTO NAME Clause in the INSERT Statement WITH AUTO NAME enables you to specify the column names in the SELECT statement only, rather than having to do it in both the INSERT and the SELECT statements. WITH AUTO NAME is used to simplify the syntax.

Page 42: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

INSERT INTO T1 WITH AUTO NAME SELECT col1, col2 FROM T2

Solution:

Ignore this clause or specify the columns explicitly.

SQL Server example:

INSERT INTO T1 SELECT col1, col2 FROM T2 or INSERT INTO T1 (col1, col2) SELECT col1, col2 FROM T2;

Issue: Inserting Documents and Images The xp_read_file system function is used in SQL Anywhere to insert file contents into a table with a column of LONG BINARY data type.

SQL Anywhere example:

INSERT INTO pictures (filename, picture) VALUES ('portrait.gif', xp_read_file( 'portrait.gif' ) )

Solution:

Use the SQL Server BULK rowset provider for OPENROWSET to read data from a file. Use OPENROWSET with a simple SELECT statement.

SQL Server example:

INSERT INTO pictures([filename], picture) SELECT 'portrait.gif' as [filename], * FROM OPENROWSET(BULK N'C:\portrait.gif', SINGLE_BLOB) AS picture;

Page 43: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Issue: ON EXISTING clause of the INSERT Statement The ON EXISTING clause of the INSERT statement updates existing rows in a table, based on primary key lookup, with new values. If the corresponding row does not already exist in the table, it inserts the new row as usual. For rows that already exist in the table, one of three options can be specified. You can choose to silently ignore the input row (SKIP), update the values in the input row with the values in the VALUES list (UPDATE), or generate an error message for duplicate key values (ERROR). If ON EXISTING is not specified, this is equivalent to specifying ON EXISTING ERROR.

SQL Anywhere examples:

Example 1:

INSERT products ON EXISTING ERROR VALUES(701, 'Tee Shirt', 'Small', 'White', 30, 9.00)

Example 2:

INSERT products ON EXISTING SKIP VALUES(701, 'Tee Shirt', 'Small', 'White', 30, 9.00)

Example 3:

INSERT products ON EXISTING UPDATE VALUES(701, 'Tee Shirt', 'Small', 'White', 30, 9.00)

Solution:

If ON EXISTING ERROR is specified, ignore this clause.

If ON EXISTING SKIP is specified, define the primary key column or columns for the table and check to see whether there is already a key with the inserted value. Add the following check before the INSERT statement:

if not exists (select * from <table_name> where <pk_column1> = pk_value1 and <pk_column2> = pk_value2 . . . and <pk_columnN> = pk_valueN)

Page 44: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

If ON EXISTING UPDATE is specified, define the primary key column or columns for the table, and if the inserted primary key value already exists, rewrite the INSERT statement into UPDATE one; otherwise use the INSERT statement or rewrite it as MERGE statement:

if not exists (select * from <table_name> where <pk_column1> = pk_value1 and <pk_column2> = pk_value2 . . . and <pk_columnN> = pk_valueN) insert <table_name> values(value1, value2, . . . , valueN) else update <table_name> set col1 = value1, col2 = value2, . . . , colN = valueN where <pk_column1> = pk_value1 and <pk_column2> = pk_value2 . . . and <pk_columnN> = pk_valueN

SQL Server examples:

Example 1:

INSERT products VALUES(701, 'Tee Shirt', 'Small', 'White', 30, 9.00);

Example 2:

IF NOT EXISTS (SELECT * FROM products WHERE id = 701) INSERT products VALUES(701, 'Tee Shirt', 'Small', 'White', 30, 9.00);

Example 3:

IF NOT EXISTS (SELECT * FROM products WHERE id = 701) INSERT products VALUES(701, 'Tee Shirt', 'Small', 'White', 30, 9.00) ELSE UPDATE products SET name = 'Tee Shirt', size = 'Small', color = 'White', quantity = 30, unit_price = 9.00 WHERE id = 701

or:

Page 45: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

MERGE products AS target USING (SELECT 701, 'Tee Shirt', 'Small', 'Red', 30, 9.00) AS source (id,name,size,color,quantity,unit_price) ON (target.id = source.id) WHEN MATCHED THEN UPDATE SET name = 'Tee Shirt', size = 'Small', color = 'Red', quantity = 30, unitprice = 9.00 WHEN NOT MATCHED THEN INSERT (id,name,size,color,quantity,unit_price) VALUES (source.id, source.name,source.size, source.color, source.quantity,source.unit_price);

Page 46: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Migrating SQL Anywhere Standard Functions This section describes how to map SQL Anywhere standard functions to equivalent SQL Server functions, and it provides solutions for emulating SQL Anywhere functions.

Equivalent Functions The following SQL Anywhere system functions are usable ”as is”, in SQL Server code:

ABS, ACOS, ASCII, ASIN, ATAN, ATN2, AVG, CAST, CEILING, CHAR, CHARINDEX, COALESCE, CONVERT, COS, COT, COUNT, CUME_DIST, DATALENGTH, DATEADD, DATEDIFF, DATENAME, DATEPART, DAY, DB_ID, DB_NAME, DEGREES, DENSE_RANK, DIFFERENCE, EXP, ERROR_LINE, ERROR_MESSAGE, ERROR_PROCEDURE, FIRST_VALUE, FLOOR, GETDATE, GROUPING, ISDATE, ISNULL, ISNUMERIC, LAST_VALUE, LEFT, LOG, LOG10, LOWER, LTRIM, MAX, MIN, MONTH, NCHAR, NEWID, NULLIF, PERCENT_RANK, PATINDEX, PI, POWER, RADIANS, RAND, RANK, REPLACE, REPLICATE, REVERSE, RIGHT, ROUND, ROW_NUMBER, RTRIM, SIGN, SIN, SOUNDEX, SPACE, SQRT, STR, STUFF, SUBSTRING, SUM, SUSER_ID, SUSER_NAME, SWITCHOFFSET, SYSDATETIMEOFFSET, TAN, TEXTPTR, TODATETIMEOFFSET, UNICODE, UPPER, USER_ID, USER_NAME, YEAR

Emulated Functions The following SQL Anywhere system functions can be emulated by using various SQL Server functions or Transact-SQL constructions.

ARGN( integer-expression, expression [ , ...] ) Returns a selected argument from a list of arguments.

SQL Anywhere example:

SELECT ARGN(4, 'a', 'b', 'c', 'd', 'e', 'f')

Solution:

In SQL Server, use a CASE expression.

SQL Server example:

SELECT CASE 4 WHEN 1 THEN 'a' WHEN 2 THEN 'b' WHEN 3 THEN 'c'

Page 47: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

WHEN 4 THEN 'd' WHEN 5 THEN 'e' WHEN 6 THEN 'f' END; In SQL Server 2016 the CHOOSE function can be used: SELECT CHOOSE(4, 'a', 'b', 'c', 'd', 'e', 'f');

ARRAY(expression [, expression ... ] | single-column-query-expression)

Returns one of a list of elements, all of which are of the same specified data type.

SQL Anywhere example: BEGIN DECLARE @dow ARRAY( 7 ) OF CHAR(3) = ARRAY( 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ); SELECT @dow[[2]]; END

Solution:

In SQL Server use a table variable.

SQL Server example:

DECLARE @dow TABLE (ID int, dow char(3)) INSERT INTO @dow VALUES (1, 'Sun'), (2, 'Mon'), (3, 'Tue'), (4, 'Wed'), (5, 'Thu'), (6, 'Fri'), (7, 'Sat') SELECT dow FROM @dow WHERE ID = 2 Note. The conversion of this function requires an individual approach in each case.

ARRAY_AGG( expression[ ORDER BY order-by-expression [ ASC | DESC ], ... ] ) Creates an unbounded, single-dimensional array from the specified expression for each group where the array element type is identical to the specified expression.

SQL Anywhere example: BEGIN CREATE VARIABLE color_list ARRAY OF LONG VARCHAR; SELECT ARRAY_AGG(DISTINCT Color) INTO color_list FROM Products; SELECT color_list[[4]];

Page 48: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

END

Solution:

In SQL Server, use a table variable.

SQL Server example:

DECLARE @color_list TABLE (ID int, Color varchar(max)) INSERT INTO @color_list SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)), Color FROM (SELECT DISTINCT Color FROM Products) q ORDER BY Color SELECT Color FROM @color_list WHERE ID = 4;

Note. The conversion of this function requires an individual approach in each case.

ARRAY_MAX_CARDINALITY( array-expression ) Returns the maximum number of elements in the array.

SQL Anywhere example: BEGIN CREATE VARIABLE color_list ARRAY(10) OF LONG VARCHAR; SELECT ARRAY_AGG(DISTINCT Color) INTO color_list FROM Products; SELECT ARRAY_MAX_CARDINALITY(color_list); END

Solution:

In SQL Server, use the function COUNT with a table variable.

SQL Server example:

DECLARE @color_list TABLE (ID int, Color varchar(max)) INSERT INTO @color_list SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)), Color FROM (SELECT DISTINCT Color FROM Products) q ORDER BY Color SELECT COUNT(*) FROM @color_list;

Page 49: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Note. The conversion of this function requires an individual approach in each case.

ATAN2(numeric-expression-1, numeric-expression-2) Returns the arc-tangent, in radians, of the ratio of two numbers.

SQL Anywhere example:

SELECT ATAN2(0.52, 0.60)

Solution:

In SQL Server, use the ATN2 function.

SQL Server example:

SELECT ATN2(0.52, 0.60);

BASE64_DECODE ( string-expression ) Decodes data using the MIME base64 format and returns the string as a LONG VARCHAR.

SQL Anywhere example:

SELECT BASE64_ENCODE('VGVzdCBTdHJpbmc=')

Solution:

In SQL Server, there is no similar built-in function. You may need to create a user-defined function, similar to the following :

CREATE FUNCTION dbo.fnMIME64Decode(@Mime VARCHAR(8000)) RETURNS VARCHAR(6000) AS BEGIN DECLARE @Characters VARCHAR(64), @Index SMALLINT, @m1 TINYINT, @m2 TINYINT, @m3 SMALLINT, @m4 SMALLINT, @p1 TINYINT, @p2 TINYINT, @p3 SMALLINT, @PlainText VARCHAR(6000), @Paddings TINYINT SELECT @Characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',

Page 50: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

@Index = DATALENGTH(@Mime) - 3, @Paddings = DATALENGTH(@Mime) - DATALENGTH(REPLACE(@Mime, '=', '')), @PlainText = '' WHILE @Index > 0 SELECT @m1 = CHARINDEX(CAST(SUBSTRING(@Mime, @Index, 1) AS BINARY(1)), CAST(@Characters AS BINARY(64))) - 1, @m2 = CHARINDEX(CAST(SUBSTRING(@Mime, @Index + 1, 1) AS BINARY(1)), CAST(@Characters AS BINARY(64))) - 1, @m3 = CHARINDEX(CAST(SUBSTRING(@Mime, @Index + 2, 1) AS BINARY(1)), CAST(@Characters AS BINARY(64))) - 1, @m4 = CHARINDEX(CAST(SUBSTRING(@Mime, @Index + 3, 1) AS BINARY(1)), CAST(@Characters AS BINARY(64))) - 1, @p1 = (@m1 & 63) * 4 + (@m2 & 48) / 16, @p2 = (@m2 & 15) * 16 + (@m3 & 60) / 4, @p3 = (@m3 & 3) * 64 + (@m4 & 63), @PlainText = CHAR(@p1) + CHAR(@p2) + CHAR(@p3) + @PlainText, @Index = @Index - 4 RETURN LEFT(@PlainText, DATALENGTH(@PlainText) - @Paddings) END;

BASE64_ENCODE( string-expression ) Encodes data using the MIME base64 format and returns it as a 7-bit ASCII string.

SQL Anywhere example:

SELECT BASE64_ENCODE('Test String')

Solution:

In SQL Server, there is no similar built-in function. You may need to create a user-defined function, similar to the following:

CREATE FUNCTION dbo.fnMIME64Encode(@PlainText VARCHAR(6000)) RETURNS VARCHAR(8000) AS BEGIN DECLARE @Characters VARCHAR(64), @Index SMALLINT, @m1 TINYINT, @m2 TINYINT, @m3 TINYINT, @m4 TINYINT, @Mime VARCHAR(8000), @FinalBlock TINYINT SELECT @Characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',

Page 51: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

@FinalBlock = DATALENGTH(@PlainText) % 3, @PlainText = @PlainText + REPLICATE(CHAR(0), (3 - DATALENGTH(@PlainText) % 3) % 3), @Index = DATALENGTH(@PlainText) - 2, @Mime = '' WHILE @Index > 0 BEGIN SELECT @m1 = (ASCII(SUBSTRING(@PlainText, @Index, 1)) & 252) / 4, @m2 = (ASCII(SUBSTRING(@PlainText, @Index, 1)) & 3) * 16 + (ASCII(SUBSTRING(@PlainText, @Index + 1, 1)) & 240) / 16, @m3 = (ASCII(SUBSTRING(@PlainText, @Index + 1, 1)) & 15) * 4 + (ASCII(SUBSTRING(@PlainText, @Index + 2, 1)) & 192) / 64, @m4 = ASCII(SUBSTRING(@PlainText, @Index + 2, 1)) & 63 SELECT @Mime = CASE WHEN @FinalBlock = 1 THEN SUBSTRING(@Characters, @m1 + 1, 1) + SUBSTRING(@Characters, @m2 + 1, 1) + '=' + '=' WHEN @FinalBlock = 2 THEN SUBSTRING(@Characters, @m1 + 1, 1) + SUBSTRING(@Characters, @m2 + 1, 1) + SUBSTRING(@Characters, @m3 + 1, 1) + '=' ELSE SUBSTRING(@Characters, @m1 + 1, 1) + SUBSTRING(@Characters, @m2 + 1, 1) + SUBSTRING(@Characters, @m3 + 1, 1) + SUBSTRING(@Characters, @m4 + 1, 1) END + @Mime, @Index = @Index - 3, @FinalBlock = 0 END RETURN @Mime END;

BINTOHEX( binary-expression ) Returns the hexadecimal equivalent of a binary string.

SQL Anywhere example:

SELECT BINTOHEX(0xAB1)

Solution:

In SQL Server, use the master.dbo.fn_varbintohexstr function in combination with the SUBSTRING and the UPPER functions:

SQL Server example:

Page 52: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT SUBSTRING(UPPER(master.dbo.fn_varbintohexstr(0xAB1)), 3, 8000);

BIT_AND( bit-expression ) Returns the bit-wise AND of the specified expression for each group of rows.

SQL Anywhere example:

SELECT BIT_AND(a) FROM (SELECT 170 a UNION SELECT 75) q

Solution:

In SQL Server, use the & operator:

SQL Server example:

DECLARE @i int = 255; SELECT @i = @i & a FROM (SELECT 170 a UNION SELECT 75) q;

BIT_LENGTH(bit-expression ) Returns the number of bits stored in the array.

SQL Anywhere example:

SELECT BIT_LENGTH('011010111')

Solution:

In SQL Server, use the LEN function.

SQL Server example:

SELECT LEN('011010111');

Page 53: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

BIT_OR( bit-expression ) Returns the bit-wise OR of the specified expression for each group of rows.

SQL Anywhere example:

SELECT BIT_OR(a) FROM (SELECT 170 a UNION SELECT 75) q

Solution:

In SQL Server, use the | operator:

SQL Server example:

DECLARE @i int = 0; SELECT @i = @i | a FROM (SELECT 170 a UNION SELECT 75) q;

BIT_SUBSTR(bit-expression[, start [, length ]] ) Returns a sub-array of a bit array.

SQL Anywhere example:

SELECT BIT_SUBSTR('01011011101111011111', 2, 5) , BIT_SUBSTR('01011011101111011111', 2) , BIT_SUBSTR('01011011101111011111', -6)

Solution:

In SQL Server, use the SUBSTRING and the REVERSE functions.

SQL Server example:

Page 54: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT SUBSTRING('01011011101111011111', 2, 5) , SUBSTRING('01011011101111011111', 2, 8000) , REVERSE(SUBSTRING(REVERSE('01011011101111011111'), 1, 6)); Note. When [length] is negative, then the REVERSE function is used to get symbols from the end.

BIT_XOR( bit-expression ) Returns the bit-wise XOR of the specified expression for each group of rows.

SQL Anywhere example:

SELECT BIT_XOR(a) FROM (SELECT 170 a UNION SELECT 75) q

Solution:

In SQL Server, use the ^ operator:

SQL Server example:

DECLARE @i int = 0; SELECT @i = @i ^ a FROM (SELECT 170 a UNION SELECT 75) q;

BYTE_INSERTSTR( insert-position, source-string, insert-string ) Inserts a string into another string at the byte position specified.

SQL Anywhere example:

SELECT BYTE_INSERTSTR(5, 0xfedcba9876543210, 0x823456)

Solution:

Page 55: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, use the master.dbo.fn_varbintohexstr in combination with the SUBSTRING and the CONVERT functions:

SQL Server example:

SELECT CONVERT(varbinary(max), left(master.dbo.fn_varbintohexstr(0xfedcba9876543210), 2 + 5 * 2) + SUBSTRING(master.dbo.fn_varbintohexstr(0x823456), 3, 8000) + SUBSTRING(master.dbo.fn_varbintohexstr(0xfedcba9876543210), 3 + 5 * 2, 8000), 1);

BYTE_LENGTH( string-expression ) Returns the number of bytes in a string.

SQL Anywhere example:

SELECT BYTE_LENGTH('text ')

Solution:

In SQL Server, use the DATALENGTH function.

SQL Server example:

SELECT DATALENGTH('text ');

BYTE_LOCATE ( source-string, search-string [, start-position ] ) Returns the position of one BYTE string within another.

SQL Anywhere example:

SELECT BYTE_LOCATE('test message', 't', 3),BYTE_LOCATE('test message', 't', -9)

Solution:

In SQL Server, use the CHARINDEX function.

Page 56: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server example:

When [start-position] is greater than or equal to 0 then the function CHARINDEX can be used as is:

SELECT CHARINDEX('t', 'test message', 3); When [start-position] is less than 0 BYTE_LOCATE returns the last matching string offset, rather than the first. A negative offset indicates how much of the end of the string to exclude from the search. The number of bytes excluded is calculated as ( -1 * [integer-expression]) – 1. In this case, we must consider the string without this number of bytes, and locate last matching. DECLARE @str varchar(100) = 'test message', @integer_expression int = -9; SELECT CASE WHEN leftsymb <= 0 THEN 0 ELSE leftsymb - CHARINDEX('t', REVERSE(left(@str, leftsymb))) + 1 END FROM (SELECT (len(@str + '.') - 1) - (-1 * @integer_expression - 1) leftsymb) q;

BYTE_REPLACE ( source-string, search-string, replace-string ) Replaces a string with another string, and returns the new results.

SQL Anywhere example:

SELECT BYTE_REPLACE('abc.def.abc.ghi', 'abc', 'xx')

Solution:

In SQL Server, use the REPLACE and the CONVERT functions.

SQL Server example:

SELECT CONVERT(varbinary(max), REPLACE('abc.def.abc.ghi', 'abc', 'xx'));

BYTE_STUFF ( source-string, start-position, length, insert-string ) Deletes multiple bytes from one string and replaces them with different bytes.

SQL Anywhere example:

SELECT BYTE_STUFF(0xfedcba9876543210, 6, 0, 0x123456)

Page 57: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, use the STUFF function in combination with the master.dbo.fn_varbintohexstr, CONVERT and SUBSTRING functions.

SQL Server example:

SELECT CONVERT(varbinary(max), STUFF(master.dbo.fn_varbintohexstr(0xfedcba9876543210), 2 + 5 * 2 + 1, 0, SUBSTRING(master.dbo.fn_varbintohexstr(0x123456), 3, 8000)), 1);

BYTE_SUBSTR( source-string, start-position [, length ] ) Returns a substring of a string. The substring is calculated using bytes, not characters.

SQL Anywhere example:

SELECT BYTE_SUBSTR('Test Message', 1, 4)

Solution:

In SQL Server, use the SUBSTRING function with byte data and single-byte characters. To emulate the behavior of this function with multibyte characters, write a user-defined function.

SQL Server example:

SELECT CAST(SUBSTRING('Test Message', 1, 4) as varbinary(max));

CARDINALITY (array-expression) Returns the highest number of any array element that has been assigned a value, including NULL.

SQL Anywhere example:

SELECT CARDINALITY( ARRAY( 3,4 ) || ARRAY( 5,6 ) || ARRAY( 7,8 ))

Solution:

Page 58: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, use the result of the COUNT function multiplied by the number of columns in the table variable.

SQL Server example:

SELECT COUNT(*) * 2 /*Number of columns*/ FROM (SELECT 3 a, 4 b UNION ALL SELECT 5, 6 UNION ALL SELECT 7, 8) q

CHAR_LENGTH (string-expression) Returns the number of characters in a string.

SQL Anywhere example:

SELECT CHAR_LENGTH('Chemical ')

Solution:

In SQL Server, use the LEN function, considering that this function doesn’t count trailing spaces.

SQL Server example:

SELECT LEN('Chemical ' + '.') - 1;

COMPARE ( string-expression-1,string-expression-2[, { collation-id | collation-name[(collation-tailoring-string) ] } ] ) Allows you to compare two character strings based on alternate collation rules. Returns:

An INTEGER, based on the collation rules that you choose:

Value Meaning 1 string-expression-1 is greater than string-expression-2 0 string-expression-1 is equal to string-expression-2 -1 string-expression-1 is less than string-expression-2

SQL Anywhere example:

Page 59: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT COMPARE('abc','ABC','UCA(case=LowerFirst)'), COMPARE('abc','ABC','UCA(case=Ignore)'), COMPARE('abc','ABC','UCA(case=UpperFirst)')

Solution:

In SQL Server, use the following CASE construction with COLLATE.

SQL Server example:

SELECT CASE WHEN 'abc' COLLATE Latin1_General_CS_AS < 'ABC' THEN -1 WHEN 'abc' COLLATE Latin1_General_CS_AS > 'ABC' THEN 1 ELSE 0 END , CASE WHEN 'abc' COLLATE Latin1_General_CI_AI < 'ABC' THEN -1 WHEN 'abc' COLLATE Latin1_General_CI_AI > 'ABC' THEN 1 ELSE 0 END , CASE WHEN 'abc' COLLATE Latin1_General_BIN < 'ABC' THEN -1 WHEN 'abc' COLLATE Latin1_General_BIN > 'ABC' THEN 1 ELSE 0 END;

COMPRESS ( string-expression [ , compression-algorithm-alias ] ) Compresses the string and returns a value of type LONG BINARY using a variety of compression algorithms like zip and gzip.

SQL Anywhere example:

SELECT COMPRESS('Hello world', 'zip')

Solution:

In SQL Server, there is no equivalent function, however you can workaround is available by exporting the data to a file and compress it using the filesystem.

CONFLICT ( column-name ) Indicates if a column is a source of conflict for an UPDATE being performed against a consolidated database in a SQL Remote environment.

Page 60: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

CREATE TRIGGER ResolveUpdateAdmin RESOLVE UPDATE ON Admin REFERENCING OLD AS OldConsolidated NEW AS NewRemote REMOTE as OldRemote FOR EACH ROW BEGIN message 'OLD'; message OldConsolidated.PKey || ',' || OldConsolidated.TextCol; message 'NEW'; message NewRemote.PKey || ',' || NewRemote.TextCol; message 'REMOTE'; if CONFLICT( PKey ) then message OldRemote.PKey; end if; if CONFLICT( TextCol ) then message OldRemote.TextCol; end if; END;

Solution:

In SQL Server, there is no equivalent function, however a workaround an be created by understanding the intent of the code.

CONNECTION_EXTENDED_PROPERTY ( { property-id | property-name }[, property-specific-argument [, connection-id ] ]) Returns the value of the given property. Allows an optional property-specific string parameter to be specified.

SQL Anywhere example:

SELECT CONNECTION_EXTENDED_PROPERTY('charset', 'Java')

Solution:

In SQL Server, use the CONNECTIONPROPERTY command.

SQL Server example:

SELECT ConnectionProperty('net_transport') AS 'Net transport', ConnectionProperty('protocol_type') AS 'Protocol type'

Page 61: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

CONNECTION_ PROPERTY ( { property-id | property-name }[ , connection-id ] ) Returns the value of a given connection property as a string.

SQL Anywhere example:

SELECT CONNECTION_PROPERTY('PrepStmt') Solution:

In SQL Server, use the CONNECTIONPROPERTY command.

SQL Server example:

SELECT ConnectionProperty('net_transport') AS 'Net transport', ConnectionProperty('protocol_type') AS 'Protocol type'

CORR ( dependent-expression, independent-expression) Returns the correlation coefficient of a set of number pairs.

SQL Anywhere example:

SELECT CORR(X, Y) FROM (SELECT 3 X, 8 Y UNION ALL SELECT -15, 4 UNION ALL SELECT -1, -34 UNION ALL SELECT 0, 10 UNION ALL SELECT 0, 0) q

Solution:

In SQL Server, use an approach similar to the following example..

SQL Server example:

; WITH Q AS

Page 62: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

(SELECT 3. X, 8. Y UNION ALL SELECT -15, 4 UNION ALL SELECT -1, -34 UNION ALL SELECT 0, 10 UNION ALL SELECT 0, 0) SELECT SUM((Y-Y_) * (X-X_)) / SQRT(SUM(SQUARE(X-X_)) * SUM(SQUARE(Y-Y_))) FROM Q CROSS APPLY (SELECT AVG(X) as X_, AVG(Y) as Y_ from Q) t;

COUNT_SET_BITS ( bit-expression ) Returns a count of the number of bits set to 1 (TRUE) in the array.

SQL Anywhere example:

SELECT COUNT_SET_BITS('00110011')

Solution:

In SQL Server, use the LEN and the REPLACE functions.

SQL Server example:

SELECT LEN('00110011') - LEN(REPLACE('00110011', '1', ''));

COVAR_POP ( dependent-expression, independent-expression) Returns the population covariance of a set of number pairs.

SQL Anywhere example:

SELECT COVAR_POP(X, Y) FROM (SELECT 3 X, 8 Y UNION ALL SELECT -15, 4 UNION ALL SELECT -1, -34 UNION ALL SELECT 0, 10

Page 63: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

UNION ALL SELECT 0, 0) q

Solution:

In SQL Server, use an approach similar to the example shown below.

SQL Server example:

; WITH Q AS (SELECT 3. X, 8. Y UNION ALL SELECT -15, 4 UNION ALL SELECT -1, -34 UNION ALL SELECT 0, 10 UNION ALL SELECT 0, 0) SELECT SUM((X - xAVG) * (Y - yAVG)) / MAX(n) FROM Q CROSS APPLY (SELECT AVG(X) xAVG, AVG(Y) yAVG, COUNT(*) n FROM Q) t;

COVAR_SAMP ( dependent-expression, independent-expression) Returns the population covariance of a set of number pairs.

SQL Anywhere example:

SELECT COVAR_SAMP(X, Y) FROM (SELECT 3 X, 8 Y UNION ALL SELECT -15, 4 UNION ALL SELECT -1, -34 UNION ALL SELECT 0, 10 UNION ALL SELECT 0, 0) q

Solution:

Page 64: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, there is no equivalent function. You can simulate the capability by applying the function to the set of (expr1, expr2) pairs after eliminating all pairs for which either expr1 or expr2 is null. Then make the following computation:

(SUM(expr1 * expr2) - SUM(expr1) * SUM(expr2) / n) / (n-1)

where n is the number of (expr1, expr2) pairs where neither expr1 nor expr2 is null.

The function returns a value of type NUMBER. If the function is applied to an empty set, then it returns null.

CSCONVERT( string-expression,target-charset-string [, source-charset-string [, options]] ) Converts strings between character sets.

SQL Anywhere example:

SELECT CSCONVERT('mytext', 'cp936', 'cp950')

Solution:

In SQL Server, use the COLLATE function.

SELECT CAST('mytext' as varchar(max)) COLLATE … /*Name of collation*/

DATE (expression) Converts the expression into a date, and removes any hours, minutes, or seconds.

SQL Anywhere example:

SELECT DATE('2017-03-28 21:12:59')

Solution:

In SQL Server, use the CAST function.

SQL Server example:

SELECT CAST('2017-03-28 21:12:59' as date);

Page 65: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

DATEFORMAT ( datetime-expression, string-expression ) Returns a string representing a date expression in the specified format.

SQL Anywhere example:

SELECT DATEFORMAT('2017-03-29', 'Mmm dd, yyyy')

Solution:

In SQL Server, use the FORMAT function.

SQL Server example:

SELECT FORMAT(convert(date, '2017-03-29'), 'MMM dd, yyyy');

DATETIME (expression) Converts an expression into a timestamp.

SQL Anywhere example:

SELECT DATETIME('2017-03-28 21:12:59')

Note: In SQL Server, the timestamp data type has nothing to do with date or time, it is an internal counter. Any time the SQL Anywhere documentation refers to timestamp, you should mentally translate that to datetime or datetime2.

Solution:

In SQL Server, use the CAST function.

SQL Server example:

SELECT CAST('2017-03-28 21:12:59' as datetime)

DAYNAME( date-expression ) Returns the name of the day of the week from a date.

Page 66: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT DAYNAME('2017-03-28’)

Solution:

In SQL Server, use the DATENAME function with dw date part.

SQL Server example:

SELECT DATENAME(dw, '2017-03-28');

DAYS Manipulates a TIMESTAMP or returns the number of days between two TIMESTAMP values. ( timestamp-expression ) Return number of days between 0000-02-29 and a TIMESTAMP value. ( timestamp-expression, timestamp-expression ) Return number of days between two TIMESTAMP values. ( timestamp-expression, integer-expression ) Add time to a TIMESTAMP.

SQL Anywhere example:

SELECT DAYS('2017-07-13') SELECT DAYS('2017-07-13 06:07:12', '1997-07-12 10:07:12') SELECT DAYS(CAST('2017-07-13' AS DATE), 366) Note; the datetime data type in SQL Server only supports dates after January 1st, 1753 due to the calendar shift that happened in 1752. If you need to represent an earlier date in a date data type, you need to use datetime2.

Solution:

In SQL Server, use the DATEDIFF function to find the difference between two datetime values and the DATEADD function to find a datetime value before or after a starting datetime.

SQL Server example:

SELECT DATEDIFF(d, CONVERT(datetime2, '0001-01-01'), CONVERT(datetime2, '2017-07-13')) + 307; SELECT DATEDIFF(d, CONVERT(datetime2, '2017-07-13 06:07:12'), CONVERT(datetime2, '1997-07-12 10:07:12')); SELECT DATEADD(d, 366, CAST('2017-07-13' as date));

Page 67: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

DB_EXTENDED_PROPERTY( { property-id | property-name }[, property-specific-argument[, database-id | database-name ] ]) Returns the value of the given property. Allows an optional property-specific string parameter to be specified.

SQL Anywhere example:

SELECT DB_EXTENDED_PROPERTY('File') SELECT DB_EXTENDED_PROPERTY('NcharCollation',' CaseSensitivity')

Solution:

In SQL Server, use the DATABASEPROPERTYEX function to retrieve options or properties for a database. Database properties between SQL Anywhere and SQL Server have difference names, so you will need to map the properties based on the needs of your application.

SQL Server example:

SELECT DATABASEPROPERTYEX('AdventureWorks2014', 'IsAutoShrink');

DB_PROPERTY( { property-id | property-name }[, database-id | database-name ] ) Returns the value of the specified database property.

SQL Anywhere example:

SELECT DB_PROPERTY( 'PageSize' ) Solution:

In SQL Server, use the DATABASEPROPERTYEX function to retrieve options or properties for a database. Database properties between SQL Anywhere and SQL Server have difference names, so you will need to map the properties based on the needs of your application.

SQL Server example:

SELECT DATABASEPROPERTYEX('AdventureWorks', 'IsAutoShrink');

DECOMPRESS( string-expression [, compression-algorithm-alias] ) Decompresses the string and returns a LONG BINARY value.

SQL Anywhere example:

Page 68: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT CAST(DECOMPRESS(Attachment, 'gzip') AS LONG VARCHAR) FROM TableA

Solution:

In SQL Server, there is no equivalent function. You can use the operating system to simulate the functionality.

DECRYPT( string-expression, key [, algorithm-format [, initialization-vector ] ] ) Decrypts the string using the supplied key and returns a LONG BINARY value.

SQL Anywhere example:

SELECT username, password, CAST(DECRYPT(secret,'TheEncryptionKey','AES(FORMAT=RAW;PADDING=PKCS5)', 'ThisIsTheIV') AS LONG VARCHAR) AS revealed FROM SensitiveData

Solution:

In SQL Server, there are several types of decrypt functions including: DECRYPTBYASYMKEY, DECRYPTBYCERT, DECRYPTBYKEY, DECRYPTBYKEYAUTOASYMKEY, DECRYPTBYKEYAUTOCERT, DECRYPTBYPASSPHRASE.

SQL Server example:

-- Get the pass phrase from the user. DECLARE @PassphraseEnteredByUser nvarchar(128); SET @PassphraseEnteredByUser = 'A little learning is a dangerous thing!'; -- Decrypt the encrypted record. SELECT CardNumber, CardNumber_EncryptedbyPassphrase AS 'Encrypted card number', CONVERT(nvarchar, DecryptByPassphrase(@PassphraseEnteredByUser, CardNumber_EncryptedbyPassphrase, 1 , CONVERT(varbinary, CreditCardID))) AS 'Decrypted card number' FROM Sales.CreditCard WHERE CreditCardID = '3681'; GO

DOW( date-expression ) Returns a number from 1 to 7 representing the day of the week of a date, where Sunday=1, Monday=2, and so on. The DOW function is not affected by the value specified for the

Page 69: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

first_day_of_week database option. For example, even if first_day_of_week is set to Monday, the DOW function returns 2 for Monday.

SQL Anywhere example:

SELECT DOW('2017-03-28')

Solution:

In SQL Server, use the following CASE construction.

SQL Server example:

SELECT CASE WHEN (datepart(dw, '2017-03-28') + @@datefirst > 7) THEN datepart(dw, '2017-03-28') + @@datefirst - 7 ELSE datepart(dw, '2017-03-28') + @@datefirst END; Starting with SQL Server 2012, use the IIF function:

SELECT IIF(datepart(dw, '2017-03-28') + @@datefirst > 7, datepart(dw, '2017-03-28') + @@datefirst - 7, datepart(dw, '2017-03-28') + @@datefirst);

ENCRYPT( string-expression, key[, algorithm-format [, initialization-vector ] ] ) Encrypts the specified value using the supplied encryption key and returns a LONG BINARY value.

SQL Anywhere example:

UPDATE SensitiveData SET secret = ENCRYPT(password, 'TheEncryptionKey', 'AES(FORMAT=RAW;PADDING=PKCS5)', 'ThisIsTheIV')

Solution:

In SQL Server, there are several types of encrypt functions including: ENCRYPTBYASYMKEY, ENCRYPTBYCERT, ENCRYPTBYKEY, ENCRYPTBYKEYAUTOASYMKEY, ENCRYPTBYKEYAUTOCERT, ENCRYPTBYPASSPHRASE.

SQL Server example:

-- Create a column in which to store the encrypted data.

Page 70: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

ALTER TABLE Sales.CreditCard ADD CardNumber_EncryptedbyPassphrase varbinary(256); GO -- First get the passphrase from the user. DECLARE @PassphraseEnteredByUser nvarchar(128); SET @PassphraseEnteredByUser = 'A little learning is a dangerous thing!'; -- Update the record for the user's credit card. -- In this case, the record is number 3681. UPDATE Sales.CreditCard SET CardNumber_EncryptedbyPassphrase = EncryptByPassPhrase(@PassphraseEnteredByUser , CardNumber, 1, CONVERT( varbinary, CreditCardID)) WHERE CreditCardID = '3681'; GO

ERROR_SQLCODE( ) Returns the SQLCODE of the error that invoked the error handler.

SQL Anywhere example:

BEGIN DECLARE divTest INT; SET divTest = 1 / 0; SELECT 'No error'; EXCEPTION WHEN OTHERS THEN SELECT 'Exception: SQLCODE = ' || ERROR_SQLCODE(); END;

Solution:

In SQL Server, use the ERROR_NUMBER function.

SQL Server example:

BEGIN TRY DECLARE @divTest int SET @divTest = 1 / 0 SELECT 'No error' END TRY BEGIN CATCH SELECT CONCAT('Exception: SQLCODE = ', ERROR_NUMBER()) END CATCH;

Page 71: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

ERROR_SQLSTATE ( ) Returns the SQLSTATE of the error that invoked the error handler.

SQL Anywhere example:

BEGIN DECLARE divTest INT; SET divTest = 1 / 0; SELECT 'No error'; EXCEPTION WHEN OTHERS THEN SELECT 'Exception: SQLSTATE = ' || ERROR_SQLSTATE(); END;

Solution:

In SQL Server, use the ERROR_STATE function.

SQL Server example:

BEGIN TRY DECLARE @divTest int SET @divTest = 1 / 0 SELECT 'No error' END TRY BEGIN CATCH SELECT CONCAT('Exception: SQLSTATE = ', ERROR_STATE()) END CATCH;

ERROR_STACK_TRACE( ) Returns a calling sequence stack trace for the error that invoked the error handler.

SQL Anywhere example:

BEGIN DECLARE divTest INT; SET divTest = 1 / 0; SELECT 'No error'; EXCEPTION WHEN OTHERS THEN SELECT 'Exception: STACK_TRACE = ' || ERROR_STACK_TRACE() ; END;

Page 72: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, use Extended Events with the package0.callstack event handler to retrieve errors.

ERRORMSG( [ sqlstate | sqlcode ] ) Provides the error message for the current error, or for a specified SQLSTATE or SQLCODE value.

SQL Anywhere example:

SELECT ERRORMSG (-813)

Solution:

In SQL Server, there is no equivalent function. To emulate this function, use the following query: SELECT text FROM sys.messages sm , sys.syslanguages sl WHERE message_id = ERROR CODE AND sm.language_id = sl.msglangid AND sl.langid = @@langid;

ESTIMATE( column-name [, value [, relation-string ] ] ) Returns selectivity estimates as a percentage calculated by the query optimizer, based on specified parameters.

SQL Anywhere example:

SELECT FIRST ESTIMATE(EmployeeID, 200, '>') FROM GROUPO.Employees ORDER BY 1

Solution:

In SQL Server, there is no equivalent function. However, information is available in the XML estimated showplan for the actual query.

ESTIMATE_SOURCE( column-name[, value [, relation-string ] ] ) Provides the source for selectivity estimates used by the query optimizer.

Page 73: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT FIRST ESTIMATE_SOURCE(EmployeeID, 200, '>') FROM GROUPO.Employees ORDER BY 1

Solution:

In SQL Server, there is no equivalent function. However, information is available in the XML estimated showplan for the actual query.

EVENT_CONDITION( condition-name ) Specifies when an event handler is triggered.

SQL Anywhere example:

CREATE EVENT LogNotifier TYPE LogDiskSpace WHERE event_condition('LogFreePercent') < 50 HANDLER BEGIN MESSAGE 'LogNotifier message' END;

Solution:

In SQL Server, this information can be setup with Extended Events.

EVENT_CONDITION_NAME( integer ) Lists the possible parameters for EVENT_CONDITION.

SQL Anywhere example:

SELECT EVENT_CONDITION_NAME(3)

Solution:

In SQL Server, this information can be setup with Extended Events.

Page 74: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

EVENT_PARAMETER( context-name ) Provides context information for event handlers.

SQL Anywhere example:

CREATE EVENT ev_PassedParameter HANDLER BEGIN MESSAGE 'ev_PassedParameter - was triggered at ' || event_parameter('time'); END; TRIGGER EVENT ev_PassedParameter("Time"=string(current timestamp));

Solution:

In SQL Server, this information can be setup with Extended Events.

EXPERIENCE_ESTIMATE( column-name[, value [, relation-string ] ] ) Returns selectivity estimates as a percentage calculated by the query optimizer, based on specified parameters.

SQL Anywhere example:

SELECT DISTINCT EXPERIENCE_ESTIMATE(EmployeeID, 200, '>') FROM GROUPO.Employees;

Solution:

In SQL Server, there is no equivalent function. However, information is available in the XML estimated showplan for the actual query.

EXPLANATION( string-expression [ , cursor-type ][, update-status ] ) Returns the optimization strategy of a SQL statement as a plain text string.

SQL Anywhere example:

SELECT EXPLANATION('SELECT * FROM GROUPO.Departments WHERE DepartmentID > 100','insensitive', 'read-only');

Page 75: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, there is no equivalent function. However, information is available in the estimated showplan for the actual query.

EXPRTYPE( string-expression, integer-expression ) Returns a string that identifies the data type of an expression.

SQL Anywhere example:

SELECT EXPRTYPE('SELECT LineID FROM SalesOrderItems', 1);

Solution:

In SQL Server, there is no analogue. As a variant, you can use the following query: SELECT system_type_name FROM sys.dm_exec_describe_first_result_set ('SELECT LineID FROM SalesOrderItems', NULL, 0)

EXTENDED_PROPERTY( { property-id | property-name }[, property-specific-argument]) Returns the value of the given database server property. Allows an optional property-specific string parameter to be specified.

SQL Anywhere example:

SELECT EXTENDED_PROPERTY('HasSecuredFeature', 'cmdshell'); SELECT EXTENDED_PROPERTY('HasSecuredFeature', 'backup,restore');

Solution:

In SQL Server, use the SERVERPROPERTY function.

EXTRACT( date-part FROM timestamp-expression ) Returns a date part from a TIMESTAMP expression.

SQL Anywhere example:

SELECT EXTRACT(SECOND FROM '2015-07-01 12:34:56.789000'); SELECT EXTRACT(HOUR FROM '2015-07-01 05:34:56.789000');

Page 76: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, use the DATEPART function.

SQL Server example:

SELECT DATEPART(ss, '2015-07-01 12:34:56.789000') SELECT DATEPART(hh, '2015-07-01 05:34:56.789000')

GET_BIT( bit-expression, position ) Returns the value (1 or 0) of a specified bit in a bit array.

SQL Anywhere example:

SELECT GET_BIT('00110011', 4); SELECT GET_BIT('00110011', 5);

Solution:

In SQL Server, use the SUBSTRING function.

SQL Server example:

SELECT CAST(SUBSTRING('00110011', 4, 1) as bit) SELECT CAST(SUBSTRING('00110011', 5, 1) as bit)

GET_IDENTITY( table_name [, number_to_allocate ] ) Allocates values to an AUTOINCREMENT column. This is an alternative to using AUTOINCREMENT to generate numbers.

SQL Anywhere example: SELECT GET_IDENTITY('GROUPO.Customers', 10);

Solution:

In SQL Server, use a sequence to reserve a set of numbers for use as a key value. Note, you don’t need to use an Identity column for this to work.

Page 77: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

USE AdventureWorks2012 GO CREATE SEQUENCE Sales.IDLabel AS int START WITH 1 INCREMENT BY 1 ; GO SELECT NEXT VALUE FOR Sales.IDLabel OVER (ORDER BY CustomerID) AS CHoldID FROM Sales.Customer WHERE AccountNumber Like ('AW0000001%');

GRAPHICAL_PLAN(string-expression[, statistics-level[, cursor-type [, update-status ] ] ]) Returns the plan optimization strategy of a SQL statement in XML format, as a string.

SQL Anywhere example:

SELECT GRAPHICAL_PLAN( 'SELECT * FROM GROUPO.Departments WHERE DepartmentID > 100' ); OUTPUT TO 'plan.saplan' FORMAT TEXT QUOTE '' HEXADECIMAL ASIS;

Solution:

In SQL Server, there is no direct analogue but SHOWPLAN_XML option can be utilized as an alternative solution.

SET SHOWPLAN_XML ON GO SELECT * FROM Departments WHERE DepartmentID > 100 GO SET SHOWPLAN_XML OFF GO

GREATER (expression-1, expression-2) Returns the greater of two parameter values.

SQL Anywhere example:

SELECT GREATER(10, 5)

Solution:

In SQL Server, use the CASE function.

Page 78: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server example:

SELECT CASE WHEN 10 > 5 THEN 10 ELSE 5 END In SQL Server 2016 we can use the IIF function as well:

SELECT IIF(10 > 5, 10, 5)

Note. It is necessary to consider that if at least one expression is NULL the result is NULL too.

HASH( expression[, algorithm ] ) Returns the specified value in hashed form.

SQL Anywhere example:

SELECT HASH('mypass', 'SHA256')

Solution:

In SQL Server, use the HASHBYTE function.

SQL Server example:

SELECT HASHBYTES('SHA2_256', 'mypass')

HEXTOBIN( hexadecimal-string ) Returns the LONG BINARY equivalent of a hexadecimal string.

SQL Anywhere example:

SELECT HEXTOBIN('0ABF0A')

Solution:

In SQL Server, use the CONVERT function. SQL Server example:

Page 79: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT CONVERT(varbinary(max), '0x' + '0ABF0A', 1)

HEXTOINT( hexadecimal-string ) Returns the decimal integer equivalent of a hexadecimal string.

SQL Anywhere example:

SELECT HEXTOINT('0xFFFFFFFF') , HEXTOINT('0xffffffff80000001')

Solution:

In SQL Server, use the CONVERT function. SQL Server example: SELECT CONVERT(int, CONVERT(varbinary(max), '0xFFFFFFFF', 1)) , CONVERT(int, CONVERT(varbinary(max), '0xffffffff80000001', 1))

HOUR (datetime-expression) Returns the hour component of a datetime value.

SQL Anywhere example:

SELECT HOUR('2017-03-28 21:12:59')

Solution:

In SQL Server, emulate this function by using the DATEPART function with hh date part.

SQL Server example:

SELECT DATEPART(hh, '2017-03-28 21:12:59')

HOURS Manipulates a TIMESTAMP or returns the number of hours between two TIMESTAMP values. ( timestamp-expression ) Return number of hours between midnight 0000-02-29 and a TIMESTAMP value.

Page 80: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

( timestamp-expression, timestamp-expression ) Return number of hours between two TIMESTAMP values. ( time-or-timestamp-expression, integer-expression ) Add hours to a TIMESTAMP.

SQL Anywhere example:

SELECT DAYS('2017-07-13 06:07:12') SELECT DAYS('2017-07-13 06:07:12', '1997-07-12 10:07:12') SELECT DAYS(CAST('2017-07-13' AS DATE), 366)

Solution:

In SQL Server, use the DATEDIFF and the DATEADD functions.

SQL Server example:

SELECT DATEDIFF(hh, CONVERT(datetime2, '0001-01-01'), CONVERT(datetime2, '2017-07-13 06:07:12')) + 7368 SELECT DATEDIFF(hh, CONVERT(datetime2, '2017-07-13 06:07:12'), CONVERT(datetime2, '1997-07-12 10:07:12')) SELECT DATEADD(hh, 366, CAST('2017-07-13' as datetime2(0)))

HTML_DECODE( string ) Decodes special character entities that appear in HTML literal strings.

SQL Anywhere example:

SELECT HTML_DECODE('&lt;p&gt;The piano was made ' || 'by &lsquo;Steinway &amp; Sons&rsquo;.&lt;/p&gt;') , HTML_DECODE('&lt;p&gt;It cost &euro;85.000,000.&lt;/p&gt;')

Solution:

In SQL Server, use the CASE and use the XML data type for decoding strings.

SQL Server example:

SELECT CAST('<root>' + '&lt;root&gt;Test&amp;123' + '</root>' AS XML).value(N'(root)[1]', N'varchar(max)');

Page 81: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Or with XML:

HTML_ENCODE( string ) Encodes special characters within strings to be inserted into HTML documents.

SQL Anywhere example:

SELECT HTML_ENCODE('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">')

Solution:

In SQL Server, use the REPLACE function.

SQL Server example:

SELECT (SELECT '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">' FOR XML PATH(''));

HTTP_BODY( ) Returns the body of the HTTP request in binary form. For example, in a POST request, this is the raw POST data.

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the BODY from the string.

HTTP_HEADER( header-field-name [, instance ] ) Returns the value of an HTTP request header.

SQL Anywhere example:

BEGIN declare header_name long varchar; declare header_value long varchar; set header_name = NULL; header_loop: LOOP SET header_name = NEXT_HTTP_HEADER( header_name ); IF header_name IS NULL THEN LEAVE header_loop END IF; SET header_value = HTTP_HEADER( header_name ); MESSAGE 'HEADER: ', header_name, '=',

Page 82: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

header_value TO CONSOLE; END LOOP; END;

Solution:

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the HEADER from the string.

HTTP_RESPONSE_HEADER( header-field-name [, instance ] ) Returns the value of an HTTP response header.

SQL Anywhere example:

BEGIN declare header_name long varchar; declare header_value long varchar; set header_name = NULL; header_loop: LOOP SET header_name = NEXT_HTTP_RESPONSE_HEADER( header_name ); IF header_name IS NULL THEN LEAVE header_loop END IF; SET header_value = HTTP_RESPONSE_HEADER( header_name ); MESSAGE 'RESPONSE HEADER: ', header_name, '=', header_value TO CONSOLE; END LOOP;

Solution:

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the RESPONSE HEADER from the string.

HTTP_VARIABLE( var-name [ , instance [ , attribute ] ] ) Returns the value of an HTTP variable.

SQL Anywhere example:

-- http://sample.com/demo/ShowDetail?product_id=300&customer_id=101 BEGIN

Page 83: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

DECLARE v_customer_id LONG VARCHAR; DECLARE v_product_id LONG VARCHAR; SET v_customer_id = HTTP_VARIABLE('customer_id'); SET v_product_id = HTTP_VARIABLE('product_id'); CALL ShowSalesOrderDetail(v_customer_id, v_product_id); END;

Solution:

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the HTTP VARIABLES from the string.

IDENTITY (expression) Generates integer values, starting at 1, for each successive row in a query.

SQL Anywhere example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT IDENTITY(10), d FROM test

Solution:

In SQL Server, use the ROW_NUMBER function.

SQL Server example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)), d FROM test

Page 84: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

You can also use the SEQUENCE object in SQL Server that was introduced in the 2012 release.

IFNULL(expression-1, expression-2[ ,expression-3]) If the first expression is the NULL value, then the value of the second expression is returned. If the first expression is not NULL, the value of the third expression is returned. If the first expression is not NULL and there is no third expression, NULL is returned.

SQL Anywhere example:

SELECT IFNULL(null, 1, 2), IFNULL(5, 1)

Solution:

In SQL Server, the ISNULL function only takes one two arguments. If you want to use the third argument for the replacement value when the value is not null, you will need use the IIF function.

SQL Server example:

SELECT IIF(NULL IS NULL, 1, 2) , ISNULL(5, 1)

INDEX_ESTIMATE( column-name [ , value [ , relation-string ] ] ) Returns selectivity estimates from the index as a percentage calculated by the query optimizer, based on specified parameters.

SQL Anywhere example:

SELECT INDEX_ESTIMATE( EmployeeID, 200, '>' ) FROM GROUPO.Employees;

Solution:

In SQL Server, use can use XML SHOWPLAN to extract the information for the query.

INSERTSTR( integer-expression, string-expression-1, string-expression-2 ) Inserts a string into another string at a specified position.

Page 85: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT INSERTSTR(4, 'ABC><EFG', 'D'), INSERTSTR(0, 'ABC><EFG', 'D')

Solution:

In SQL Server, use the SUBSTRING and concatenate (+) functions.

SQL Server example:

SELECT SUBSTRING('ABC><EFG', 1, 4) + 'D' + SUBSTRING('ABC><EFG', 4 + 1, LEN('ABC><EFG' + '.') - 1) Note. When integer-expression is less or equal to 0 then string-expression-2 always inserts before string-expression-1:

SELECT 'D' + 'ABC><EFG'

INTTOHEX( integer-expression ) Returns a string containing the hexadecimal equivalent of an integer.

SQL Anywhere example:

SELECT INTTOHEX(15618)

Solution:

In SQL Server, use the CONVERT function.

SQL Server example: SELECT CONVERT(varchar(max), CONVERT(varbinary(max), 15618), 1)

ISENCRYPTED( string, key[, algorithm ] ) Determines if a string is encrypted using the ENCRYPT function and the specified key.

SQL Anywhere example:

SELECT ISENCRYPTED(ENCRYPT('test_string', 'key'), 'key')

Page 86: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, there is no analogue. Your application will need to know which string values are encrypted.

LCASE( string-expression ) Converts all characters in a string to lowercase.

SQL Anywhere example:

SELECT LCASE('ChoCOlatE')

Solution:

In SQL Server, use the LOWER function.

SQL Server example:

SELECT LOWER('ChoCOlatE')

LENGTH ( string-expression ) Returns the number of characters in a string.

SQL Anywhere example:

SELECT LENGTH('ChoCOlatE ')

Solution:

In SQL Server, use the LEN function, considering that this function doesn’t count trailing spaces.

SQL Server example:

SELECT LEN('ChoCOlatE ' + '.') – 1

Page 87: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

LESSER ( expression-1, expression-2 ) Returns the lesser of two parameter values.

SQL Anywhere example:

SELECT LESSER(10, 5)

Solution:

In SQL Server, use the CASE function.

SQL Server example:

SELECT IIF(10 < 5, 10, 5)

Note. It is necessary to consider that if at least one expression is NULL result is NULL too.

LIST( [ALL | DISTINCT ] string-expression [, delimiter-string ] [ ORDER BY order-by-expression [ ASC | DESC ], ... ] ) Returns a delimited list of values for every row in a group.

SQL Anywhere example:

SELECT LIST(EmployeeID ORDER BY Surname, ':') AS "Sorted IDs" FROM GROUPO.Employees GROUP BY DepartmentID;

Solution:

In SQL Server, use the FOR XML PATH.

SQL Server example:

SELECT STUFF(CAST((SELECT CONCAT(';', EmployeeID) FROM Employees WHERE DepartmentID = e.DepartmentID ORDER BY Surname FOR XML PATH(''), TYPE) as varchar(max)), 1, 1, '') [Sorted IDs] FROM Employees e

Page 88: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

GROUP BY DepartmentID

LOCATE ( string-expression-1, string-expression-2 [, integer-expression ] ) Returns the position of one string within another.

SQL Anywhere example:

SELECT LOCATE('test message', 't', 3),LOCATE('test message', 't', -9)

Solution:

In SQL Server, use the CHARINDEX function.

SQL Server example:

When [integer-expression] is more or equal to 0 then the function CHARINDEX can be used as is:

SELECT CHARINDEX('t', 'test message', 3) When [integer-expression] is less than 0 LOCATE returns the last matching string offset, rather than the first. A negative offset indicates how much of the end of the string to exclude from the search. The number of bytes excluded is calculated as ( -1 * [integer-expression]) – 1. In this case, we must consider string without this number of bytes, and locate the last matching. DECLARE @str varchar(100) = 'test message', @integer_expression int = -9 SELECT CASE WHEN leftsymb <= 0 THEN 0 ELSE leftsymb - CHARINDEX('t', REVERSE(left(@str, leftsymb))) + 1 END FROM (SELECT (len(@str + '.') - 1) - (-1 * @integer_expression - 1) leftsymb) q

MEDIAN( [ ALL | DISTINCT ] numeric-expression ) Computes the median of a numeric expression for a set of rows.

SQL Anywhere example:

SELECT MEDIAN(Salary) FROM GROUPO.Employees

Page 89: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, use the PERCENTILE_CONT function.

SQL Server example:

SELECT DISTINCT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY EmployeeID) OVER (PARTITION BY 1) AS MedianCont FROM Employees

MICROSECOND( timestamp-expression ) Returns the microsecond component of a TIMESTAMP expression.

SQL Anywhere example:

SELECT MICROSECOND('12:34:56.789012')

Solution:

In SQL Server, use the DATEPART function with mcs date part.

SQL Server example:

SELECT DATEPART(mcs, '12:34:56.789012')

MILLISECOND( timestamp-expression ) Returns the millisecond component of a TIMESTAMP expression.

SQL Anywhere example:

SELECT MILLISECOND( '12:34:56.78901' );

Solution:

In SQL Server, use the DATEPART function with ms date part.

SQL Server example:

Page 90: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT DATEPART(ms, '12:34:56.78901')

MINUTE ( datetime-expression ) Returns the minute component of a datetime.

SQL Anywhere example:

SELECT MINUTE('2017-03-28 21:12:59')

Solution:

In SQL Server, use the DATEPART function with mi date part.

SQL Server example:

SELECT DATEPART(mi, '2017-03-28 21:12:59')

MINUTES Manipulates a TIMESTAMP or returns the number of minute boundaries between two TIMESTAMP values. ( timestamp-expression ) Return the number of minutes between midnight 0000-02-29 and a TIMESTAMP value. ( timestamp-expression, timestamp-expression ) Return the number of minutes between two TIMESTAMP values. ( timestamp-or-time-expression, integer-expression ) Add minutes to a TIMESTAMP value.

SQL Anywhere example:

SELECT MINUTES('2017-07-13 06:07:12') SELECT MINUTES('1999-07-13 06:07:12', '2017-07-13 10:07:12') SELECT MINUTES(CAST('2017-05-12 21:05:07' AS TIMESTAMP), 5)

Solution:

In SQL Server, use the DATEDIFF and the DATEADD functions.

SQL Server example:

Page 91: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT DATEDIFF(mi, CONVERT(datetime2, '0001-01-01'), CONVERT(datetime2, '2017-07-13 06:07:12')) + 442080 SELECT DATEDIFF(mi, CONVERT(datetime2, '1999-07-13 06:07:12'), CONVERT(datetime2, '2017-07-13 10:07:12')) SELECT DATEADD(mi, 5, CAST('2017-05-12 21:05:07' as datetime2(0)))

MOD ( dividend, divisor ) Returns the remainder when one whole number is divided by another.

SQL Anywhere example:

SELECT MOD(135.789, 4)

Solution:

In SQL Server, use the % operator.

SQL Server example:

SELECT 135.789 % 4

MONTHNAME ( date-expression ) Returns the name of the month from a date.

SQL Anywhere example:

SELECT MONTHNAME('2017-03-28')

Solution:

In SQL Server, use the DATENAME function with month date part.

SQL Server example:

SELECT DATENAME(month, '2017-03-28')

Page 92: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

MONTHS Manipulates a TIMESTAMP or returns the number of month boundaries between two TIMESTAMP values. ( timestamp-expression ) Return the number of months between 0000-02 and a TIMESTAMP value. ( timestamp-expression, timestamp-expression ) Return the number of months between two TIMESTAMP values. ( timestamp-expression, integer-expression ) Add months to a TIMESTAMP value.

SQL Anywhere example:

SELECT MONTHS('2017-07-13 06:07:12') SELECT MONTHS('2017-07-13 06:07:12', '1999-09-13 10:07:12') SELECT MONTHS(CAST('2017-05-12 21:05:07' AS DATETIME), 5)

Solution:

In SQL Server, use the DATEDIFF and the DATEADD functions.

SQL Server example:

SELECT DATEDIFF(m, CONVERT(datetime2, '0001-01-01'), CONVERT(datetime2, '2017-07-13 06:07:12')) + 11 SELECT DATEDIFF(m, CONVERT(datetime2, '2017-07-13 06:07:12'), CONVERT(datetime2, '1999-09-13 10:07:12')) SELECT DATEADD(m, 5, CAST('2017-05-12 21:05:07' as datetime2(0)))

NEXT_CONNECTION ( connection-id [, database-id ] ) Returns an identifying number for the next connection. NEXT_CONNECTION is useful for disconnecting all the connections created before a specific time. However, because NEXT_CONNECTION returns the connection IDs in reverse order, connections made after the function is started are not returned. To ensure that all connections are disconnected, prevent new connections from being created before you run NEXT_CONNECTION.

SQL Anywhere example:

SELECT NEXT_CONNECTION(10) SELECT NEXT_CONNECTION(connection-id, NULL)

Solution:

Page 93: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, if the application needs to manage connections, use the sys.dm_exec_sessions to see all active user connections.

NEXT_DATABASE( database-id ) Returns an identifying number for a database.

SQL Anywhere example:

SELECT NEXT_DATABASE(0)

Solution:

In SQL Server, use a query over sys.databases to iterate through the databases on the server.

NEXT_HTTP_HEADER( header-name ) Returns the next HTTP header name.

SQL Anywhere example:

BEGIN declare header_name long varchar; declare header_value long varchar; set header_name = NULL; header_loop: LOOP SET header_name = NEXT_HTTP_HEADER( header_name ); IF header_name IS NULL THEN LEAVE header_loop END IF; SET header_value = HTTP_HEADER( header_name ); MESSAGE 'HEADER: ', header_name, '=', header_value TO CONSOLE; END LOOP; END;

Solution:

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the HEADER from the string.

Page 94: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

NEXT_HTTP_RESPONSE_HEADER( header-name ) Returns the next HTTP response header name.

SQL Anywhere example:

BEGIN declare header_name long varchar; declare header_value long varchar; set header_name = NULL; header_loop: LOOP SET header_name = NEXT_HTTP_RESPONSE_HEADER( header_name ); IF header_name IS NULL THEN LEAVE header_loop END IF; SET header_value = HTTP_RESPONSE_HEADER( header_name ); MESSAGE 'RESPONSE HEADER: ', header_name, '=', header_value TO CONSOLE; END LOOP;

Solution:

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the RESPONSE HEADER from the string.

NEXT_HTTP_VARIABLE( var-name) Returns an identifying number for the next connection.

SQL Anywhere example:

BEGIN DECLARE variable_name LONG VARCHAR; DECLARE variable_value LONG VARCHAR; SET variable_name = NULL; SET variable_name = NEXT_HTTP_VARIABLE( variable_name ); SET variable_value = HTTP_VARIABLE( variable_name ); END;

Solution:

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the HTTP VARIABLE from the string.

Page 95: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

NEXT_SOAP_HEADER( header-key ) Returns an identifying number for the next connection.

SQL Anywhere example:

BEGIN DECLARE hd_key LONG VARCHAR; DECLARE hd_entry LONG VARCHAR; header_loop: LOOP SET hd_key = NEXT_SOAP_HEADER( hd_key ); IF hd_key IS NULL THEN -- no more header entries LEAVE header_loop; END IF; IF hd_key = 'Authentication' THEN SET hd_entry = SOAP_HEADER( hd_key ); END IF; END LOOP header_loop; END;

Solution:

This function is useful within the PHP external environment and has no analogue in SQL Server. It is possible to use the XML data type and string functions to separate the SOAP HEADER from the string.

NOW( * ) Returns the current year, month, day, hour, minute, second, and fraction of a second.

SQL Anywhere example:

SELECT NOW(*)

Solution:

In SQL Server, use the GETDATE function.

SQL Server example:

SELECT GETDATE()

Page 96: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

NUMBER(*) Generates numbers starting at 1 for each successive row in the results of the query.

SQL Anywhere example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT NUMBER(*), d FROM test

Solution:

In SQL Server, use the ROW_NUMBER function.

SQL Server example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)), d FROM test

PLAN( string-expression, [ cursor-type [ update-status ] ] ) Returns the long plan optimization strategy of a SQL statement, as a string.

SQL Anywhere example:

SELECT PLAN( 'SELECT * FROM GROUPO.Departments WHERE DepartmentID > 100', 'insensitive', 'read-only' );

Solution:

Page 97: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, use the XML SHOWPLAN to extract the information so a specific query.

PROPERTY( { property-id | property-name } [, second-parameter ] ) Returns the value of the specified database server property as a string.

SQL Anywhere example:

SELECT PROPERTY('Name')

Solution:

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case.

PROPERTY_DESCRIPTION( { property-id | property-name } ) Returns a description of a property.

SQL Anywhere example:

SELECT PROPERTY_DESCRIPTION('IndAdd')

Solution:

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case.

PROPERTY_IS_TRACKABLE( property-ID ) Returns whether or not you can maintain historical data for the specified database server property by storing its tracked values.

SQL Anywhere example:

SELECT PropName FROM sa_eng_properties( ) WHERE PROPERTY_IS_TRACKABLE( PropNum ) = 1

Solution:

Page 98: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case.

PROPERTY_NAME( property-id [, property-scope ] ) Returns the name of the property with the supplied property ID for the specified connection level.

SQL Anywhere example:

SELECT PROPERTY_NAME(102, 'server')

Solution:

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case.

PROPERTY_NUMBER( property-name ) Returns the property number of the property with the supplied property-name.

SQL Anywhere example:

SELECT PROPERTY_NUMBER('PAGESIZE')

Solution:

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case.

QUARTER ( datetime-expression ) Returns a number indicating the quarter of the year from the supplied date expression.

SQL Anywhere example:

SELECT QUARTER('2017-03-28 21:12:59')

Solution:

Page 99: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, use the DATEPART function with q date part.

SQL Server example:

SELECT DATEPART(q, '2017-03-28 21:12:59')

READ_CLIENT_FILE( client-filename-expression ) Reads data from the specified file on the client computer.

SQL Anywhere example:

SELECT READ_CLIENT_FILE(ClientFilePath) INTO @Variable

Solution:

In SQL Server, use the OPENROWSET function.

DECLARE @FileContents VARCHAR(MAX) SELECT @FileContents=BulkColumn FROM OPENROWSET(BULK'PathToYourFile.sql',SINGLE_BLOB) x;

READ_SERVER_FILE( filename ) [, start [ , length] ] Reads data from the specified file on the server and returns the full or partial contents of the file as a LONG BINARY value.

SQL Anywhere example:

SELECT READ_SERVER_FILE('d:\\fff.sql', 20, 17)

Solution:

In SQL Server, use the OPENROWSET function and then perform a SUBSTRING on the result.

SQL Server example:

DECLARE @FileContents VARCHAR(MAX); SELECT @FileContents=BulkColumn FROM OPENROWSET(BULK'PathToYourFile.sql',SINGLE_BLOB) x;

Page 100: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT SUBSTRING(@FileContents, 20, 17)

REGEXP_SUBSTR( expression, regular-expression [, start-offset [ , occurrence-number [, escape-expression ] ] ] ) Extracts substrings from strings using regular expressions.

SQL Anywhere example:

SELECT REGEXP_SUBSTR(Street, '^\S+') as street_num, REGEXP_SUBSTR(Street, '(?<=^\S+\s+).*$') AS street_name FROM GROUPO.Employees

Solution:

In SQL Server, you can use a CLR function to process regular expressions.

SQL Server solution:

// default using statements above using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; using System.Text.RegularExpressions; namespace CLR_Functions { public class myFunctions { [SqlFunction] public static SqlInt16 RegexContain(SqlString text, SqlString pattern) { SqlInt16 returnVal = 0; try { string myText = text.ToString(); string myPattern = pattern.ToString(); MatchCollection mc = Regex.Matches(myText, myPattern); if (mc.Count > 0) { returnVal = 1; } } catch {

Page 101: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

returnVal = 0; } return returnVal; } } }

Then, create a function that registers the CLR function.

CREATE FUNCTION RegexContain(@text NVARCHAR(50), @pattern NVARCHAR(50)) RETURNS smallint AS EXTERNAL NAME CLR_Functions.[CLR_Functions.myFunctions].RegexContain

Then call the function as follows:

SELECT RegexContain(Street, '^\S+') as street_num, RegexContain(Street, '(?<=^\S+\s+).*$') AS street_name FROM GROUPO.Employees

REGR_AVGX( dependent-expression , independent-expression) Computes the average of the independent variable of the regression line.

SQL Anywhere example:

SELECT REGR_AVGX(Salary, (2008 - YEAR(BirthDate))) FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_AVGY( dependent-expression , independent-expression) Computes the average of the dependent variable of the regression line.

SQL Anywhere example:

SELECT REGR_AVGY(Salary, (YEAR(NOW()) - YEAR(BirthDate))) FROM GROUPO.Employees

Page 102: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_COUNT( dependent-expression , independent-expression) Returns an integer that represents the number of non-NULL number pairs used to fit the regression line.

SQL Anywhere example:

SELECT REGR_COUNT(Salary, (YEAR(NOW()) - YEAR(BirthDate))) FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_INTERCEPT( dependent-expression , independent-expression) Computes the y-intercept of the linear regression line that best fits the dependent and independent variables.

SQL Anywhere example:

SELECT REGR_INTERCEPT(Salary, (YEAR(NOW()) - YEAR(BirthDate))) FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_R2( dependent-expression , independent-expression) Computes the coefficient of determination (also referred to as R-squared or the goodness of fit statistic) for the regression line.

SQL Anywhere example:

SELECT REGR_R2(Salary, (YEAR(NOW()) - YEAR(BirthDate)))

Page 103: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_SLOPE( dependent-expression , independent-expression) Computes the slope of the linear regression line fitted to non-NULL pairs.

SQL Anywhere example:

SELECT REGR_SLOPE(Salary, (YEAR(NOW()) - YEAR(BirthDate))) FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_SXX( dependent-expression , independent-expression) Returns the sum of squares of the independent expressions used in a linear regression model. The REGR_SXX function can be used to evaluate the statistical validity of a regression model.

SQL Anywhere example:

SELECT REGR_SXX(Salary, (YEAR(NOW()) - YEAR(BirthDate))) FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_SXY( dependent-expression , independent-expression) Returns the sum of products of the dependent and independent variables. The REGR_SXY function can be used to evaluate the statistical validity of a regression model.

SQL Anywhere example:

Page 104: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT REGR_SXY(Salary, (YEAR(NOW()) - YEAR(BirthDate))) FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REGR_SYY( dependent-expression , independent-expression) Returns values that can evaluate the statistical validity of a regression model.

SQL Anywhere example:

SELECT REGR_SYY(Salary, (YEAR(NOW()) - YEAR(BirthDate))) FROM GROUPO.Employees

Solution:

In SQL Server, linear regression algorithms are available as part of the SQL Server R Services.

REMAINDER ( dividend, divisor ) Returns the remainder when one whole number is divided by another.

SQL Anywhere example:

SELECT REMAINDER(5.677, 3.5)

Solution:

In SQL Server, use the % operator.

SQL Server example:

SELECT 5.677 % 3.5

REPEAT (expression1, expression2,…) Concatenates a string a specified number of times.

Page 105: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT REPEAT('value', 3)

Solution:

In SQL Server, use the REPLICATE function.

SQL Server example:

SELECT REPLICATE('value', 3)

REWRITE( select-statement [, 'ANSI' ] ) Returns a rewritten SELECT, UPDATE, or DELETE statement. The rewritten query from the REWRITE function is not intended to be executable. It is a tool for analyzing performance issues by showing what gets passed to the optimizer after the rewrite phase.

SQL Anywhere example:

SELECT REWRITE( 'SELECT s.ID, s.OrderDate FROM GROUPO.SalesOrders s WHERE EXISTS ( SELECT * FROM GROUPO.Employees e WHERE e.EmployeeID = s.SalesRepresentative)' ) FROM SYS.DUMMY; SET TEMPORARY OPTION tsql_outer_joins = 'On'; SELECT REWRITE( 'SELECT DISTINCT s.ID, s.OrderDate, e.GivenName, e.EmployeeID FROM GROUPO.SalesOrders s, GROUPO.Employees e WHERE e.EmployeeID *= s.SalesRepresentative', 'ANSI' ) FROM SYS.DUMMY;

Solution:

In SQL Server, there is no analogue.

ROW( expression [, expression ... ] | single-row-query-expression) Returns a sequence of ( field name data type, ... ) pairs named fields.

SQL Anywhere example:

Page 106: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT ROW(ID, NAME, DESCRIPTION).NAME AS pInfo FROM GROUPO.Products; SELECT CAST(ROW(303, 'Tee Shirt', 'My tee shirt') AS ROW(ProductID INTEGER, ProductName CHAR(25), ProductDescription CHAR(35) ) ).ProductName AS pInfo FROM SYS.DUMMY;

Solution:

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case.

SQL Server example: SELECT NAME AS pInfo FROM Products; SELECT ProductName FROM (SELECT CAST(303 as int) ProductID , CAST('Tee Shirt' as char(25)) ProductName , CAST('My tee shirt' as char(35)) ProductDescription ) q;

ROWID( correlation-name ) Returns an UNSIGNED BIGINT value that uniquely identifies a row within a table.

SQL Anywhere example:

SELECT ROWID( Employees ) FROM GROUPO.Employees WHERE Employees.EmployeeID = 105

Solution:

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case. As variant column with uniqueidentifier type can be added to the table.

SECOND ( datetime-expression ) Returns the second of the given datetime value.

Page 107: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT SECOND('2017-03-28 21:12:59')

Solution:

In SQL Server, use the DATEPART function with ss date part.

SQL Server example: SELECT DATEPART(ss, '2017-03-28 21:12:59')

SECONDS function [Date and time] Manipulates a TIMESTAMP or returns the number of second boundaries between two TIMESTAMP values. ( timestamp-expression ) Return the number of seconds between midnight 0000-02-29 and a TIMESTAMP value. ( timestamp-expression, timestamp-expression ) Return the number of seconds between two TIMESTAMP values. ( timestamp-expression, integer-expression ) Add seconds to a TIMESTAMP value.

SQL Anywhere example:

SELECT SECONDS('2017-07-13 06:07:12') SELECT SECONDS('2017-07-13 06:07:12', '1999-07-13 10:07:12') SELECT SECONDS(CAST('2017-05-12 21:05:07' AS TIMESTAMP), 5)

Solution:

In SQL Server, use the DATEDIFF and the DATEADD functions.

SQL Server example:

SELECT CAST(DATEDIFF(s, CONVERT(datetime2, '0001-01-01'), CONVERT(datetime2, '0068-07-13 06:07:12')) as bigint) + 26524800 SELECT DATEDIFF(s, CONVERT(datetime2, '2017-07-13 06:07:12'), CONVERT(datetime2, '1999-07-13 10:07:12')) SELECT DATEADD(s, 65, CAST('2017-05-12 21:05:07' as datetime))

Page 108: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SECURE_SIGN_MESSAGE( message, key[, hash-algorithm ]) Digitally signs a message.

SQL Anywhere example:

CREATE VARIABLE @signature LONG BINARY; SELECT SECURE_SIGN_MESSAGE(document, private-key) INTO @signature;

Solution:

In SQL Server, you can use the SIGNBYASYMKEY or SIGNBYCERT function.

SECURE_VERIFY_MESSAGE( string-expression, signature, key[, hash-algorithm ]) Digitally verifies a message.

SQL Anywhere example:

CREATE VARIABLE @verified INTEGER; SELECT SECURE_VERIFY_MESSAGE( document, signature, senders-public-key ) INTO @verified;

Solution:

In SQL Server, you can use the VERIFYSIGNEDBYCERT or VERIFYSIGNEDBYASYMKEY to verify the signature.

SQL Server example:

The following example returns 1 if the selected data has not been changed since it was signed with asymmetric key WillisKey74. The example returns 0 if the data has been tampered with.

SELECT Data, VerifySignedByAsymKey( AsymKey_Id( 'WillisKey74' ), SignedData, DataSignature ) as IsSignatureValid FROM [AdventureWorks2012].[SignedData04] WHERE Description = N'data encrypted by asymmetric key ''WillisKey74'''; GO RETURN;

SET_BIT( [ bit-expression, ]bit-position [, value ] ) Sets the value of a specific bit in a bit array.

Page 109: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT SET_BIT('00110011', 4 , 0) SELECT SET_BIT('00110011', 5 , 1) SELECT SET_BIT(6)

Solution:

In SQL Server, use the STUFF and the REPLICATE functions.

SQL Server example:

SELECT STUFF('00110011', 4, 1, '0') SELECT STUFF('00110011', 5, 1, '1') SELECT REPLICATE('0', 6 - 1) + '1'

SET_BITS( expression ) Creates a bit array where specific bits, corresponding to values from a set of rows, are set to 1 (TRUE).

SQL Anywhere example:

The following statements return a bit array with the 2nd, 5th, and 10th bits set to 1 (or 0100100001):

CREATE TABLE t(r INTEGER); INSERT INTO t values(2); INSERT INTO t values(5); INSERT INTO t values(10); SELECT SET_BITS(r) FROM t;

Solution:

In SQL Server, there is no analogue and would need to be emulated using T-SQL statements.

SQL Server example:

; WITH q AS (SELECT REPLICATE('0', MAX(r)) r, MAX(r) m FROM t) SELECT RIGHT(CONCAT(q.r, q1.s), q.m) FROM (SELECT SUM(CONVERT(int, LEFT(CONCAT(REPLICATE('0', t.r - 1) + '1', q.r), q.m))) s FROM q, t) q1, q

Page 110: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SIMILAR( string-expression-1, string-expression-2 ) Returns a number indicating the similarity between two strings.

SQL Anywhere example:

SELECT SIMILAR('toast', 'coast')

Solution:

In SQL Server, the full-text search and semantic search feature provides similar functionality with the CONTAINSTABLE function.

SOAP_HEADER( header-key [, index, header-attribute ] ) Returns a SOAP header entry, or an attribute value for a header entry of the SOAP request.

SQL Anywhere example:

BEGIN DECLARE hd_key LONG VARCHAR; DECLARE hd_entry LONG VARCHAR; header_loop: LOOP SET hd_key = NEXT_SOAP_HEADER( hd_key ); IF hd_key IS NULL THEN -- no more header entries LEAVE header_loop; END IF; IF hd_key = 'Authentication' THEN SET hd_entry = SOAP_HEADER( hd_key ); END IF; END LOOP header_loop; END;

Solution:

In SQL Server, there is no analogue.

SORTKEY(string-expression[,{collation-id | collation-name[ ( collation-tailoring-string)]]) Generates sort key values. That is, values that can be used to sort character strings based on alternate collation rules.

Page 111: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Anywhere example:

SELECT Surname, GivenName FROM GROUPO.Employees ORDER BY SORTKEY( Surname, 'dict' );

Solution:

In SQL Server, use the COLLATE.

SQL Server example:

SELECT Surname, GivenName FROM Employees ORDER BY Surname COLLATE Latin1_General_BIN

SQLDIALECT( sql-statement-string ) Returns either Watcom SQL or Transact-SQL, to indicate the SQL dialect of a statement.

SQL Anywhere example:

SELECT SQLDIALECT('SELECT EmployeeName = Surname FROM GROUPO.Employees') FROM SYS.DUMMY

Solution:

In SQL Server, there is no analogue.

SQLFLAGGER( sql-standard-string, sql-statement-string ) Returns either Watcom SQL or Transact-SQL, to indicate the SQL dialect of a statement.

SQL Anywhere example:

SELECT SQLFLAGGER('SQL:2003/Package', 'SELECT top 1 dummy_col FROM sys.dummy ORDER BY dummy_col')

Solution:

In SQL Server, there is no analogue.

Page 112: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SA_STACK_TRACE([ stack_frames[, detail_level[, connection_id ] ] ]) Returns information about the stack trace for the current statement.

SQL Anywhere example:

CREATE OR REPLACE PROCEDURE proc3() BEGIN DECLARE v INTEGER; SET v = 1; SELECT * FROM sa_split_list( STACK_TRACE('caller+procedure', 'stack+sql'), '\n' ); END; CREATE OR REPLACE PROCEDURE proc2() BEGIN CALL proc3(); END; CREATE OR REPLACE PROCEDURE proc1() BEGIN CALL proc2(); END; CALL proc1();

Solution:

In SQL Server, the call stack is available with Extended Events.

STDDEV (numeric-expression) Computes the standard deviation of a sample consisting of a numeric-expression.

SQL Anywhere example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT STDDEV(d) AS stddev FROM test

Page 113: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Solution:

In SQL Server, use the STDEV function.

SQL Server example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT STDEV(d) AS stddev FROM test

STDDEV_POP (numeric-expression) Computes the standard deviation of a population consisting of a numeric-expression.

SQL Anywhere example: DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT STDDEV_POP(d) AS stddev_pop FROM test

Solution:

In SQL Server, use the STDEVP function.

SQL Server example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO

Page 114: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT STDEVP(d) AS stddev_pop FROM test

STDDEV_SAMP (numeric-expression) Computes the standard deviation of a sample consisting of a numeric expression.

SQL Anywhere example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT STDDEV_SAMP(d) AS stddev_samp FROM test

Solution:

In SQL Server, use the STDEV function.

SQL Server example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT STDEV(d) AS stddev_samp FROM test

STRING( string-expression [, ... ] ) Concatenates one or more strings into one large string.

SQL Anywhere example:

SELECT STRING('testing', NULL, 123)

Solution:

In SQL Server, use the CONCAT function.

Page 115: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server example:

SELECT CONCAT('testing', NULL, 123)

STRTOUUID( string-expression ) Concatenates one or more strings into one large string.

SQL Anywhere example:

SELECT STRTOUUID('6c2b64a9-3c6f-47dc-9015-36b9ed49fec2'); SELECT STRTOUUID('{6c2b64a9-3c6f-47dc-9015-36b9ed49fec2}');

Solution:

In SQL Server, use the CONVERT function.

SQL Server example:

SELECT CONVERT(uniqueidentifier, '6c2b64a9-3c6f-47dc-9015-36b9ed49fec2' ); SELECT CONVERT(uniqueidentifier, '{6c2b64a9-3c6f-47dc-9015-36b9ed49fec2}' );

TO_CHAR( string-expression [, source-charset-name ] ) Converts character data from any supported character set into the CHAR character set for the database.

SQL Anywhere example:

SELECT TO_CHAR('cp850_data', 'cp850')

Solution:

In SQL Server, use the CONVERT or the CAST functions.

SQL Server example:

SELECT CONVERT(varchar(max), 'cp850_data') COLLATE SQL_Latin1_General_CP850_BIN

Page 116: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT CAST('cp850_data' as varchar(max)) COLLATE SQL_Latin1_General_CP850_BIN

TO_NCHAR( string-expression [, source-charset-name ] ) Converts character data from any supported character set into the NCHAR character set.

SQL Anywhere example:

SELECT TO_NCHAR('cp850_data', 'cp850')

Solution:

In SQL Server, use the CONVERT or the CAST functions.

SQL Server example:

SELECT CONVERT(nvarchar(max), 'cp850_data') COLLATE SQL_Latin1_General_CP850_BIN SELECT CAST('cp850_data' as nvarchar(max)) COLLATE SQL_Latin1_General_CP850_BIN

TODAY( * ) Returns the current date.

SQL Anywhere example:

SELECT TODAY(*)

Solution:

In SQL Server, use the GETDATE function.

SQL Server example:

SELECT CAST(GETDATE() as date)

Page 117: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

TRACEBACK( [ * ] ) Returns statements on the stack of the most recent exception (error) that occurred during a stored procedure, trigger, or custom function execution.

SQL Anywhere example:

SELECT TRACEBACK(*);

Solution:

In SQL Server, there is no analogue.

TRANSACTSQL( sql-statement-string ) Rewrites a Watcom SQL statement in the Transact-SQL dialect.

SQL Anywhere example:

SELECT TRANSACTSQL( 'SELECT empl_name as EmployeeName FROM GROUPO.Employees' ) FROM SYS.DUMMY;

Solution:

In SQL Server, there is no analogue.

TRIM (string-expression) Removes leading and trailing blanks from a string.

SQL Anywhere example:

SELECT TRIM(' chocolate ')

Solution:

In SQL Server, use the LTRIM and RTRIM functions one after another.

Page 118: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server example:

SELECT LTRIM(RTRIM( ' chocolate ' )) Starting with SQL Server 2017, use the TRIM function.

SELECT TRIM(' chocolate ')

TRIM_ARRAY( array-expression, integer-expression ) Returns an implicitly bounded array that consists of a specified number of elements in an array.

SQL Anywhere example:

DECLARE UntrimmedArray ARRAY( 4 ) OF INT; DECLARE TrimmedArray ARRAY( 2 ) OF INT; SET UntrimmedArray = ARRAY( 1, 2, 3, 4 ); SET TrimmedArray = TRIM_ARRAY( UntrimmedArray, 2 );

Solution:

In SQL Server, there is no analogue. The conversion of this function requires an individual approach in each case.

TRUNCNUM (numeric-expression, integer-expression) Truncates a number at a specified number of places after the decimal point.

SQL Anywhere example:

SELECT TRUNCNUM(655, -2), TRUNCNUM(655.348, 2)

Solution:

In SQL Server, use the ROUND function with the third parameter (type of operation) other than 0. In this case numeric-expression will be truncated.

SQL Server example:

SELECT ROUND(655, -2, 1), ROUND(655.348, 2, 1)

Page 119: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

UCASE( string-expression ) Converts all characters in a string to uppercase.

SQL Anywhere example:

SELECT UCASE('ChoCOlatE')

Solution:

In SQL Server, use the UPPER function.

SQL Server example:

SELECT UPPER('ChoCOlatE')

UUIDTOSTR( uuid-expression ) Converts a unique identifier value (UUID, also known as GUID) to a string value.

SQL Anywhere Example:

SELECT UUIDTOSTR( NEWID())

Solution:

In SQL Server, use the CONVERT function.

SQL Server example:

SELECT CONVERT(varchar(max), NEWID())

VAR_POP (numeric-expression) Computes the statistical variance of a population consisting of a numeric-expression.

SQL Anywhere Example:

DROP TABLE IF EXISTS test GO

Page 120: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT VAR_POP(d) AS var_pop FROM test

Solution:

In SQL Server, use the VARP function.

SQL Server example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT VARP(d) AS var_pop FROM test

VAR_SAMP (numeric-expression) Computes the statistical variance of a sample consisting of a numeric-expression.

SQL Anywhere example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT VAR_SAMP(d) AS var_samp FROM test

Solution:

In SQL Server, use the VAR function.

SQL Server example:

Page 121: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT VAR(d) AS var_samp FROM test

VAREXISTS( variable-name-string [, owner ] ) Returns 1 if a user-defined variable exists with the specified name. Returns 0 if no such variable exists.

SQL Anywhere example:

IF VAREXISTS( 'start_time' ) = 0 THEN CREATE VARIABLE start_time TIMESTAMP; END IF; SET start_time = CURRENT TIMESTAMP;

Solution:

In SQL Server, there is no analogue.

VARIANCE (numeric-expression) Computes the statistical variance of a sample consisting of a numeric-expression.

SQL Anywhere example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT VARIANCE(d) AS variance FROM test

Solution:

In SQL Server, use the VAR function.

Page 122: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SQL Server example:

DROP TABLE IF EXISTS test GO CREATE TABLE test(d int NOT NULL) GO INSERT INTO test (d) VALUES (1), (2), (3) GO SELECT VAR(d) AS variance FROM test

WATCOMSQL( sql-statement-string ) Rewrites a Transact-SQL statement in the Watcom SQL dialect. This can be useful when converting existing Adaptive Server Enterprise stored procedures into Watcom SQL syntax.

SQL Anywhere example:

SELECT WATCOMSQL('SELECT last_name = Surname FROM GROUPO.Employees') FROM SYS.DUMMY;

Solution:

In SQL Server, there is no analogue.

WEEKS Manipulates a TIMESTAMP or returns the number of weeks between two TIMESTAMP values. ( timestamp-expression ) Returns the number of weeks between 0000-02-29 and a TIMESTAMP value. ( timestamp-expression, timestamp-expression ) Returns the number of weeks between two TIMESTAMP values. ( timestamp-expression, integer-expression ) Adds weeks to a TIMESTAMP value.

SQL Anywhere example:

SELECT WEEKS('2008-07-13 06:07:12') SELECT WEEKS('2008-07-13 06:07:12', '2008-09-13 10:07:12') SELECT WEEKS(CAST('2008-05-12 21:05:07' AS TIMESTAMP), 5)

Solution:

Page 123: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, use the DATEDIFF and the DATEADD functions.

SQL Server example:

SELECT DATEDIFF(ww, CONVERT(datetime2, '0001-01-01'), CONVERT(datetime2, '2008-07-13 06:07:12')) + 44 SELECT DATEDIFF(ww, CONVERT(datetime2, '2008-07-13 06:07:12'), CONVERT(datetime2, '2008-09-13 10:07:12')) SELECT DATEADD(ww, 5, CAST('2008-05-12 21:05:07' as datetime))

WRITE_CLIENT_FILE( filename, blob-expression [, 'A' ] ) Creates and writes to a file on the client computer.

SQL Anywhere example:

SELECT WRITE_CLIENT_FILE( ... )

Solution:

In SQL Server, you can use the FILESTREAM capability to output data to client files.

XMLAGG( expression [ ORDER BY order-by-expression ] ) Generates a forest of XML elements from a collection of XML values.

SQL Anywhere example:

SELECT XMLAGG(XMLELEMENT(NAME "Products", XMLATTRIBUTES(ProductID, Quantity AS "quantity_shipped"))) FROM (SELECT 300 ProductID, 12 Quantity UNION ALL SELECT 301 ProductID, 12 Quantity UNION ALL SELECT 400 ProductID, 24 Quantity UNION ALL SELECT 401 ProductID, 24 Quantity UNION ALL SELECT 401 ProductID, 12 Quantity) s GROUP BY ProductID

Solution:

Page 124: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

In SQL Server, use the FOR XML.

SQL Server example:

;WITH s as (SELECT 300 ProductID, 12 Quantity UNION ALL SELECT 301 ProductID, 12 Quantity UNION ALL SELECT 400 ProductID, 24 Quantity UNION ALL SELECT 401 ProductID, 24 Quantity UNION ALL SELECT 401 ProductID, 12 Quantity) SELECT (SELECT ProductID , Quantity [quantity_shipped] FROM s WHERE ProductID = s1.ProductID FOR XML RAW('Products'), TYPE) FROM s s1 GROUP BY ProductID FOR XML Path(''), TYPE

XMLCONCAT( xml-value [, ... ] ) Produces a forest of XML elements.

SQL Anywhere example:

SELECT XMLCONCAT(XMLELEMENT(NAME CustomerID, ID), XMLELEMENT(NAME cust_fname, GivenName), XMLELEMENT(NAME cust_lname, Surname) ) AS "Customer Information" FROM GROUPO.Customers WHERE ID < 120;

Solution:

In SQL Server, use the FOR XML.

Page 125: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

XMLELEMENT( { NAME element-name-expression } | string-expression [, XMLATTRIBUTES ( attribute-value-expression [ AS attribute-name ],... ) ] [, element-content-expression,... ] ) Produces an XML element within a query.

SQL Anywhere example:

SELECT XMLELEMENT(NAME x, 'abc', 'def');

Solution:

In SQL Server, use the FOR XML.

SQL Server example:

SELECT CONCAT('abc', 'def') FOR XML PATH('x')

XMLFOREST( element-content-expression [ AS element-name ],... ) Generates a forest of XML elements.

SQL Anywhere example:

SELECT EmployeeID, XMLFOREST( GivenName, Surname ) AS "Employee Name" FROM Employees;

Solution:

In SQL Server, use the FOR XML.

XMLGEN( xquery-constructor, content-expression [ AS variable-name ],... ) Generates an XML value based on an XQuery constructor.

SQL Anywhere example:

SELECT XMLGEN( '<emp EmployeeID="{$EmployeeID}"><StartDate>{$x}</StartDate></emp>',

Page 126: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

EmployeeID, StartDate AS x ) FROM GROUPO.Employees;

Solution:

In SQL Server, use the FOR XML.

YEARS Manipulates a TIMESTAMP or returns the number of years between two TIMESTAMP values. ( timestamp-expression ) Return the number of years between year 0000 and a TIMESTAMP value. ( timestamp-expression, timestamp-expression ) Return the number of years between two TIMESTAMP values. ( timestamp-expression, integer-expression ) Add years to a TIMESTAMP value.

SQL Anywhere example:

SELECT YEARS('1998-07-13 06:07:12') SELECT YEARS('1998-07-13 06:07:12', '1994-03-13 08:07:13') SELECT YEARS(CAST('1998-07-13 06:07:12' AS TIMESTAMP), 300)

Solution:

In SQL Server, use the DATEDIFF and the DATEADD functions.

SQL Server example:

SELECT DATEDIFF(yy, CONVERT(datetime2, '0001-01-01'), CONVERT(datetime2, '1998-07-13 06:07:12')) + 1 SELECT DATEDIFF(yy, CONVERT(datetime2, '1998-07-13 06:07:12'), CONVERT(datetime2, '1994-03-13 08:07:13')) SELECT DATEADD(yy, 300, CAST('1998-07-13 06:07:12' as datetime))

YMD( smallint-expression1, smallint-expression2, smallint-expression3 ) Returns a date value corresponding to the given year, month, and day of the month. Arguments are INTEGER values from -32768 to 32767.

SQL Anywhere example:

Page 127: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

SELECT YMD(1998, 06, 12);

Solution:

In SQL Server, use the DATEFROMPARTS function.

SQL Server example:

SELECT DATEFROMPARTS(1998, 06, 12);

Page 128: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Conclusion This migration guide covers the differences between SAP SQL Anywhere and SQL Server 2016 database platforms, and it discusses the steps necessary to convert an SAP SQL Anywhere database to SQL Server 2016 or SQL Server 2017.

About DB Best Technologies DB Best Technologies is a leading provider of database and application migration services and custom software development. We have been focused on heterogeneous database environments (SQL Server, Oracle, Sybase, DB2, MySQL) since starting at 2002 in Silicon Valley. Today, with over 140 employees in the United States and Europe, we develop database tools and provide services to customers worldwide.

DB Best developed migration tools to automate conversion between SQL dialects. In 2005 Microsoft acquired this technology, which later became a family of SQL Server Migration Assistant (SSMA) products. We continue to develop new versions of SSMA, and support Microsoft customers who are migrating to SQL Server.

We also provide migration services covering all major steps of a typical migration project: complexity assessment, schema conversion, data migration, application conversion, testing, integration, deployment, performance tuning, training, and support.

For more details, visit us at www.dbbest.com or e-mail us at [email protected].

Page 129: Guide to Migrating from SAP SQL Anywhere to SQL …€¦ · SAP SQL Anywhere database engine,also known as Sybase ASA, ... and you can upgrade your database platform to Standard or

Post Migration considerations Encryption

Auditing

High availability

Security center link as an example

Row level security

Pointer to on-line documentation for the hints for the items above

12 step process reference.

For more information:

http://www.microsoft.com/sqlserver/: SQL Server Web site

https://www.microsoft.com/en-us/sql-server/sql-server-editions-express : SQL Server 2016 SP1 Express edition

https://docs.microsoft.com/en-us/sql/sql-server/editions-and-supported-features-for-sql-server-2016 : Editions and Supported Features for SQL Server 2016

http://technet.microsoft.com/en-us/sqlserver/: SQL Server TechCenter

http://msdn.microsoft.com/en-us/sqlserver/: SQL Server DevCenter

Did this paper help you? Please give us your feedback. Tell us on a scale of 1 (poor) to 5 (excellent), how would you rate this paper and why have you given it this rating? For example:

• Are you rating it high due to having good examples, excellent screenshots, clear writing, or another reason?

• Are you rating it low due to poor examples, fuzzy screenshots, unclear writing?

This feedback will help us improve the quality of the white papers we release. Send feedback. Microsoft Corporation. All rights reserved. This document is provided "as-is." Information and views expressed in this document, including URL and

other Internet Web site references, may change without notice. You bear the risk of using it. Some examples are for illustration only and are fictitious.

No real association is intended or inferred. This document does not provide you with any legal rights to any intellectual property in any Microsoft

product. You may copy and use this document for your internal, reference purposes.