Quantcast
Channel: SQL Server Migration Assistant (SSMA) Team's Blog
Viewing all 38 articles
Browse latest View live

Migrating Oracle to SQL Server using SSMA - Error O2SS0408 Collection or Record Type is not supported

$
0
0

By Bill Ramos and Vishal Soni, Advaiya Inc.

This blog post covers the reasons why SQL Server Migration Assistant (SSMA) for Oracle does not support Collection or Records Type. A collection is an ordered group of elements, all of the same type. It is a general concept that encompasses lists, arrays, and other familiar data types. Each element has a unique subscript that determines its position in the collection.

Error O2SS0408 Collection or Record Type is not supported

Background

Whenever you make a reference of a user defined data type in collection query, SSMA is not able to resolve that data type. Hence, when you try to insert the values in table, SSMA generates an error. SSMA provides direct emulation of only the Integer and String data type and rest of the things are treated as Records.

Possible Remedies

Consider the below example:

CREATEORREPLACETYPE TEST_UDT ASOBJECT (ATTR_1 NUMBER);

/

 

DECLARE

      TYPE COLLECTION_TEST ISTABLEOF TEST_UDT;

      ColTest COLLECTION_TEST;

BEGIN

      ColTest := COLLECTION_TEST(TEST_UDT(10), TEST_UDT(20), TEST_UDT(30));

      DBMS_OUTPUT.PUT_LINE('COLLECTION COUNT IS -- ' || ColTest.COUNT);

END;

When SSMA tries to convert the above code, it does not resolve the operations to be performed on the user defined datatype and hence generates “Error O2SS0408 Collection or Record Type is not supported”.

Error_O2SS0408_01

 

The solution of the above error is to rewrite the code in Oracle. Instead of creating a user defined data type separately, just declare a data type as a record of INTEGER data type and make its reference while assigning the values.

DECLARE

TYPE TEST_UDT ISRECORD (ATTR_1 NUMBER);

TYPE COLLECTION_TEST ISTABLEOF TEST_UDT Index By Binary_Integer;

ColTest COLLECTION_TEST;

BEGIN

ColTest(1).ATTR_1 := 10;

ColTest(2).ATTR_1 := 20;

ColTest(3).ATTR_1 := 30;

DBMS_OUTPUT.PUT_LINE('COLLECTION COUNT IS -- ' || ColTest.COUNT);

END;

Corresponding SQL Server code generated by SSMA

BEGIN

   DECLARE

      @CollectionIndexInt$TYPE varchar(max) = ' TABLE INDEX BY INT OF ( RECORD ( ATTR_1 DOUBLE ) )'

   DECLARE

      @ColTest dbo.CollectionIndexInt = dbo.CollectionIndexInt ::[Null].SetType(@CollectionIndexInt$TYPE)

 

   SET @ColTest = @ColTest.SetRecord(1, @colTest.GetOrCreateRecord(1).SetInt(N'ATTR_1', 10))

 

   SET @ColTest = @ColTest.SetRecord(2, @colTest.GetOrCreateRecord(2).SetInt(N'ATTR_1', 20))

 

   SET @ColTest = @ColTest.SetRecord(3, @colTest.GetOrCreateRecord(3).SetInt(N'ATTR_1', 30))

 

   PRINT'COLLECTION COUNT IS -- ' + ISNULL(CAST(@ColTest.CountAS nvarchar(max)), '')

 

END

GO

Related Errors

There are several other errors related to “Collection and Records” that you may encounter. These include the following:

·         Emulating Records and Collections using CLR UDTs

·         Error O2SS0407 Unsupported collection key type

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper


Migrating Oracle to SQL Server using SSMA - Error O2SS0029 Cannot convert EXIT statement

$
0
0

By Bill Ramos and Mayank Bhanawat, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle doesn’t convert the EXIT statement when an outer loop is exited from inside the scope of inner loop. The LOOP statement is used to define a loop with an indeterminate number of iterations. The EXIT statement exits a loop and transfers control immediately to the end of the loop.

Error O2SS0029 Cannot convert EXIT statement

Background

Whenever an outer loop is exited from inside the scope of inner loop, SSMA cannot always convert the exit statement and generates following error:Error O2SS0029 Cannot convert EXIT statement’

Possible Remedies

Consider the example below in which outer loop is exited from inside the scope of inner loop.

DECLARE

  s      PLS_INTEGER := 0;

  i      PLS_INTEGER := 0;

  j      PLS_INTEGER;

BEGIN

  <<outer_loop>>

  LOOP

    i := i + 1;

    j := 0;

    <<inner_loop>>

    LOOP

        j := j + 1;

        s := s + i * j; -- sum a bunch of products

        DBMS_OUTPUT.PUT_LINE('i: ' || TO_CHAR(i));

        DBMS_OUTPUT.PUT_LINE('j: ' || TO_CHAR(j));

        DBMS_OUTPUT.PUT_LINE('s: ' || TO_CHAR(s));

      EXIT inner_loop WHEN (j > 5);

      EXIT outer_loop WHEN ((i * j) > 15);

    ENDLOOP inner_loop;

  ENDLOOP outer_loop;

  DBMS_OUTPUT.PUT_LINE('The sum of products equals: ' || TO_CHAR(s));

END;

 

 

When SSMA tries to convert the above code, it generates following error:“Error O2SS0029 Cannot convert EXIT statement”.

 

The solution of the above problem is, first close the inner loop (ENDLOOP inner_loop;) and then EXIT the outer loop as shown below in the highlighted code:

DECLARE

  s      PLS_INTEGER := 0;

  i      PLS_INTEGER := 0;

j      PLS_INTEGER;

BEGIN

  <<outer_loop>>

  LOOP

    i := i + 1;

    j := 0;

    <<inner_loop>>

    LOOP

        j := j + 1;

        s := s + i * j; -- sum a bunch of products

        DBMS_OUTPUT.PUT_LINE('i: ' || TO_CHAR(i));

        DBMS_OUTPUT.PUT_LINE('j: ' || TO_CHAR(j));

        DBMS_OUTPUT.PUT_LINE('s: ' || TO_CHAR(s));

      EXIT inner_loop WHEN (j > 5);

  ENDLOOP inner_loop;

EXIT outer_loop WHEN ((i * j) > 15);

  ENDLOOP outer_loop;

  DBMS_OUTPUT.PUT_LINE('The sum of products equals: ' || TO_CHAR(s));

END;

When you execute the above code in SSMA, it executed successfully. But in this query, the loop iterates one time less than source example because in the resolution we have first closed the inner loop and then EXIT the outer loop.

The resolution of this problem is to use the GOTO approach in SQL Server. The GOTO statement is used to transfer control of program execution to the statement that has a specified statement label. For this, we need to update the SQL Server code as follows:

BEGIN

 

   DECLARE

      @s int = 0,

      @i int = 0,

      @j int

 

   condition1:

 

   WHILE (@i * @j) > 15 break

       BEGIN

         SET @i = @i + 1

         SET @j = 0

      condition2:

         WHILE1 = 1

            BEGIN

               PRINT 's: ' + ISNULL(CAST(@s ASvarchar(max)), '')                       

               IF ((@i * @j) > 15)   BREAK

                 SET @j = @j + 1

                 SET @s = @s + @i * @j                    

               IF (@j > 5) goto condition1

                 PRINT 'i: ' + ISNULL(CAST(@i ASvarchar(max)), '')

                 PRINT 'j: ' + ISNULL(CAST(@j ASvarchar(max)), '')

               IF ((@i * @j) > 15) goto condition2  

            END      

                     PRINT 'The sum of products equals: ' + ISNULL(CAST(@s ASvarchar(max)), '')    

       END

END

GO

 

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle to SQL Server using SSMA - Error O2SS0343 FORALL statement with SAVE EXCEPTION clause is not supported

$
0
0

By Bill Ramos and Mayank Bhanawat, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle doesn’t support the SAVE EXCEPTION clause in the FORALL statement. Exception handling is a programming language construct or mechanism designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution.  In Oracle, FORALL statement lets you run multiple DML statements very efficiently and can only repeat a single DML statement, unlike a general-purpose FOR loop. SAVE Exception statement is an optional keywords that cause the FORALL loop to continue even if some DML operations fail.

Error O2SS0343 FORALL statement with SAVE EXCEPTION clause is not supported

Background

The Oracle exception model differs from Microsoft SQL Server 2008 both in exception raising and exception handling. It is preferable to use the SQL Server exceptions model as part of the Oracle PL/SQL code migration.

Whenever FORALL statement used with SAVE exception clause, SSMA doesn’t support it and generate following error message:Error O2SS0343 FORALL statement with SAVE EXCEPTION clause is not supported.

Possible Remedies

Consider the example below which uses a FORALL statement with SAVE EXCEPTION clause.

CREATETABLE DIVISION_RESULT_Exception (RESULTNUMBER);

/

DECLARE

  TYPE NUMLIST ISTABLEOFNUMBER;

  NUM_TAB NUMLIST := NUMLIST(1000,0,100,0,10);

  ERRORSNUMBER;

  DML_ERRORS EXCEPTION;

  PRAGMA EXCEPTION_INIT(DML_ERRORS, -24381);

BEGIN

  FORALL i IN NUM_TAB.FIRST..NUM_TAB.LASTSAVEEXCEPTIONS

     INSERTINTO DIVISION_RESULT_Exception VALUES(1000/NUM_TAB(i));

EXCEPTION

WHEN DML_ERRORS THEN

  ERRORS := SQL%BULK_EXCEPTIONS.COUNT;

  DBMS_OUTPUT.PUT_LINE('Number of errors is ' || ERRORS);

  FOR i IN1..ERRORSLOOP

     DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);

     DBMS_OUTPUT.PUT_LINE('SQLERRM: ' ||SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));

  ENDLOOP;

END;

 

 

When SSMA tries to convert the above code, it generates following error: “Error O2SS0343 FORALL statement with SAVE EXCEPTION clause is not supported”.

 

Error O2SS0343

One possible remediation is to use the try and catch block to handle the exceptions in T-SQL using ERROR_NUMBER and ERROR_MESSAGE functions instead of the SQLCODE and SQLERRM Oracle functions. For this, we need to update the SQL Server code as follows:

BEGIN

/*Declaration and initialization of table of input values*/

   DECLARE

      @CollectionIndexInt$TYPE varchar(max)=' TABLE OF DOUBLE'

 

   DECLARE

      @NUM_TAB dbo.CollectionIndexInt = dbo.CollectionIndexInt ::[Null].SetType(@CollectionIndexInt$TYPE).AddDouble(1000).AddDouble(0).AddDouble(100).AddDouble(0).AddDouble(10),

/* Declaration and initialization of other variables*/

      @ERRORS int,

      @DML_ERRORS$exception nvarchar(1000)

        SET @DML_ERRORS$exception =N'ORA-24381%'

 

   DECLARE

/* Declaration and initialization of temporary variables */

      @i int

      SET @i = 1

     

/* Running the loop for all the input values*/

      WHILE @i <= @NUM_TAB.Count

  

      BEGIN

/* Performing the required operation in Try block */

        BEGINTRY

            INSERT dbo.DIVISION_RESULT_EXCEPTION(RESULT)

            VALUES (1000 / @NUM_TAB.GetDouble(@i))

        ENDTRY

/* Catch block to handle exception generated in Try block */

        BEGINCATCH

           set  @Errors = @Errors + 1;

          Print ('SQL error is '+convert(varchar(20),Error_Number())+':'+convert(varchar(100),ERROR_MESSAGE()))

           Print(Convert(Varchar(30),(Error_Number())))

        ENDCATCH;

/*Incrementing the loop variable*/          

  SET @i = @i + 1

      END

END

GO

 

Related Errors

There are several other errors related to “Exception Handling” that you may encounter. These include the following:

·         Error O2SS0282: RAISE without exception specified can be placed only in exception handler

 

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

Migrating Oracle to SQL Server using SSMA - Error O2SS0101 A parameter has been omitted, so there is no default value

$
0
0

By Bill Ramos and Badal Bordia, Advaiya Inc.

This blog post covers the reasons why SQL Server Migration Assistant (SSMA) for Oracle cannot get description for packaged function or a packaged procedure call when a parameter has been omitted.

A package is an encapsulated collection of related program objects (for example, procedures, functions, variables, constants, cursors, and exceptions) stored together in the database. To execute a function or procedure that is defined in a package, you'll have to prefix the function name (through required parameters) along with the package name

Error O2SS0101 A parameter has been omitted, so there is no default value 

Background

Whenever you invoke a function or procedure that is defined in a package with omitting invalid parameter, SSMA generated an error. When no values are passed to a packaged function or a packaged procedure call, the omitted parameters holding no default values causes this error.

 

Possible Remedies

Consider the below example of Oracle. In this example we have created a package (math_pkg) that contains a function (get_sum)

Package Specification and Package Body

CREATEORREPLACEPACKAGE math_pkg AS

   FUNCTION get_sum (n1 INT, n2 INTDEFAULT0, n3 INTDEFAULT0) RETURNINT;

END math_pkg;

 

 

CREATEORREPLACEPACKAGEBODY math_pkg AS

   FUNCTION get_sum (n1 INT, n2 INTDEFAULT0, n3 INTDEFAULT0) RETURNINTIS

   BEGIN

       RETURN n1 + n2 + n3;

   END;

END math_pkg;

 

Statement

DECLARE

addition INT;

BEGIN     

addition := math_pkg.get_sum();

END;

 

When SSMA tries to convert the above statement, it does not resolve the operations of called function (get_sum)that is invoked without required parameter passing or wrong number of arguments. Hence generates error “O2SS0101: A parameter has been omitted, so there is no default value: n1”.

 

 

clip_image001[4]

 

The solution of the above error is to rewrite the code in Oracle. Actually in Oracle when you call the above package in the statement, it also raises the PL/SQL error of wrong number or types of arguments in call to 'GET_SUM'.

So you have to rectify the problem in Oracle itself by assigning optional value to parameter within a function. By doing this we are matching the number and types of argument required to invoke the function. To make a parameter optional you can set a default value in the case if the value is not passed, the default value will be taken. In Oracle the first two parameters are mandatory and only the last parameter is optional.

Below is the rewrite code of an above Oracle example- In below function defined in a package  we are assigning default value (n1 INT DEFAULT 0) to the first parameter of get_sum() function.

CREATEORREPLACEPACKAGE math_pkg AS

   FUNCTION get_sum (n1 INTDEFAULT0, n2 INTDEFAULT0, n3 INTDEFAULT0) RETURNINT;

END math_pkg;

 

 

CREATEORREPLACEPACKAGEBODY math_pkg AS

   FUNCTION get_sum (n1 INTDEFAULT0, n2 INTDEFAULT0, n3 INTDEFAULT0) RETURNINTIS

   BEGIN

       RETURN n1 + n2 + n3;

   END;

END math_pkg;


SSMA will now properly convert the code.

Related Errors

There are several other errors related to “Invalid parameter” that you may encounter. These include the following:

·         Error O2SS0102 Procedure (function) call is missing a parameter

·         Error O2SS0104 Unpackaged function call is missing a parameter

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

Migrating Oracle to SQL Server using SSMA - Error O2SS0160 SELECT statement not converted

$
0
0

By Bill Ramos and Mayank Bhanawat, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle doesn’t convert the SELECT statement in two scenarios that have ill formed ORDER BY clauses.

Error O2SS0160 SELECT statement not converted

Background

There are two scenarios, in which SSMA doesn’t convert the select statement and generate the same ‘Error O2SS0160 SELECT statement not converted’ due to following reason:

·         When SELECT DISTINCT statement is used with CONNECT BY PRIOR statement in the hierarchical query, SSMA cannot convert the select statement.

·         When ORDER BY clause sorts the result set based on the two columns/fields but you have specify only one column/field in SELECT statement, SSMA cannot convert the select statement

Possible Remedies

Scenario 1:

Consider the example below in which SELECT DISTINCT statement is used with CONNECT BY PRIOR statement in the hierarchical query.

SELECTdistinct empno, MGR, ename

    FROM emp

STARTWITH MGR = 7902

CONNECTBYPRIOR MGR = empno;

 

When SSMA tries to convert the above code, it generates following error:Error O2SS0160 SELECT statement not converted”.

 

Error_O2SS0160

To resolve the above issue, you can use the ORDER BY statement in the source code of Oracle, as shown below: 

SELECTdistinct empno, MGR, ename

    FROM emp

STARTWITH MGR = 7902

CONNECTBYPRIOR MGR = empno

Orderby empno;

When you execute the above query in SSMA, it converts successfully.

Scenario2: Consider the other example in which ORDER BY clause sorts the result set based on the two columns/fields but SELECT statement only have one columns/field.

Select Empno from emp ORDERBY1, 2;

When SSMA tries to convert the above statement, it generates following Error O2SS0160 SELECT statement not converted”.

Error_O2SS0160_1

If the number of fields/columns used with ORDER BY clause is greater than number of field/column in the SELECT statement than SSMA generate the error. To solve this error either reduce the number of field/column in ORDER BY statement or equalize number of field/column in both SELECT statement and ORDER BY statement.

To solve this issue in our example, we equalize the field/column of SELECT statement with ORDER BY statement by removing the second column reference from the ORDER BY clause as shown below:

Select Deptno from emp ORDERBY1;

When you execute the above code in SSMA, it converts successfully.

Related Errors

There are several other errors related to “Hierarchical query” that you may encounter. These include the following:

·         Error O2SS0268: Hierarchical query with outer join cannot be converted

·         Error O2SS0285: Hierarchical query was not converted

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

Migrating Oracle to SQL Server using SSMA - Error O2SS0418 Failed to parse statement batch with package definition

$
0
0

By Bill Ramos and Vishal Soni, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle doesn’t convert the PL/SQL block when using invalid syntax while creating a package in Oracle code.

Error O2SS0418 Failed to parse statement batch with package definition

Background

Whenever we used the invalid syntax while creating a package in Oracle code, SSMA generates following error: “Error O2SS0418 Failed to parse statement batch with package definition”

Possible Remedies

Consider the example below, in which we have created a package Empty_Pkg4 with invalid syntax:

CREATEORREPLACEpackage Empty_Pkg4

IS

Begin

PVT INT := 10;

END;

 

When SSMA tries to convert the above statement, it generates following error: “Error O2SS0418 Failed to parse statement batch with package definition”.

 Error_O2SS0418

 

To resolve this error, you can correct the source code and delete the invalid syntax in Oracle. In our example we have to delete the Begin statement from the Oracle source code as shown below:

CREATEORREPLACEpackage Empty_Pkg4

IS

PVT INT := 10;

END;

When you convert the above code in SSMA, it converted successfully.

O2SS0418_1

Another remedy to consider is verifying if any application code calls the package containing the invalid syntax. If not, consider removing the package from your migration project.

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle to SQL Server using SSMA - Error O2SS0274 Call to function with cursor return value cannot be converted in current context

$
0
0

By Bill Ramos and Vishal Soni, Advaiya Inc.

This blog post covers the reason why SQL Server Migration Assistant (SSMA) for Oracle cannot convert some of the statements that have cursor as a return type in any function.

A cursor is a mechanism by which you can assign a name to a "SELECT statement" and manipulate the information within that SQL statement. Cursors are used by database programmers to process individual rows returned by database system queries.

Error O2SS0274 Call to function with cursor return value cannot be converted in current context

Background

In SSMA, the conversion of cursors in return statements is not supported. So if a function is defined with a cursor as return type, then SSMA generates Error O2SS0274.

Possible Remedies

Consider the following example:

 

CREATEORREPLACEFUNCTION F_RETURN_CUR

   RETURN SYS_REFCURSOR

IS

   refCursorValue SYS_REFCURSOR;

BEGIN

   OPEN refCursorValue

   FORSELECT*FROM dept;

   RETURN (refCursorValue);

END;

 

DECLARE

   refCursorValue SYS_REFCURSOR;

   myRecord dept%ROWTYPE;

BEGIN

   refCursorValue := F_RETURN_CUR;

   LOOP

      FETCH refCursorValue

         INTO myRecord;

      EXITWHEN refCursorValue%NOTFOUND;

      dbms_output.put_line(refCursorValue%ROWCOUNT);

   ENDLOOP;

END;

 

When you execute the above code in Oracle, a function with name “F_RETURN_CUR” is created. This function returns the cursor refCursorValue. While migrating this function, SSMA generates the error “Error O2SS0274 Call to function with cursor return value cannot be converted in current context”.

Error_O2SS0274_01 

 

One possible remediation is to create and use temporary table inside the function in SQL Server instead of using cursor. And then the reference of this temporary table is returned by the function. For this, we need to update the SQL Server code as follows:

 

CREATEFUNCTION dbo.F_RETURN_CUR(@Choice int)

 

RETURNS @TempEmp TABLE

(

   [DEPTNO] [numeric](4, 0)NOTNULL,

   [DNAME] [varchar](10)NOTNULL

)

AS

BEGIN 

   INSERTINTO @TempEmp

   SELECT*FROM dept;                

RETURN;

END

 

 

BEGIN

   DECLARE

      @v_refCursorValue_rowcount int,

      @refCursorValue CURSOR

   DECLARE

      @myRecord$DEPTNO float(53),

      @myRecord$DNAME varchar(20)

   DECLARE

    @TableVariable TABLE (DEPTNO INT, DNAME NVARCHAR)

    SET @refCursorValue =CURSORFORSELECT*FROM F_RETURN_CUR(1)

    OPEN @refCursorValue

SET @v_refCursorValue_rowcount = 0

   WHILE 1 = 1

     BEGIN

        FETCH @refCursorValue

          INTO @myRecord$DEPTNO, @myRecord$DNAME

            IF@@FETCH_STATUS= 0

              SET @v_refCursorValue_rowcount = @v_refCursorValue_rowcount + 1

            IF@@FETCH_STATUS<> 0

              BREAK

            PRINT @v_refCursorValue_rowcount

      END

END

GO

Related Errors

There are several other errors related to returning a CURSOR that you may encounter. These include the following:

·         Error O2SS0245 - Cursor conversion in return statements not supported

·         Error O2SS0094 Unable to convert CURSOR as parameter.

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle to SQL Server using SSMA Error O2SS0007 Check constraint condition not parsed

$
0
0

By Bill Ramos and Ankit Matta, Advaiya Inc.

This blog post covers the reason why SQL Server Migration Assistant (SSMA) for Oracle is not able to convert a BINARY_FLOAT column with a constraint for checking a NAN (Not a Number) condition. In Oracle, the BINARY_FLOAT data type allows an application to store number underflow or overflow values. SQL Server generates an error as soon as a number overflow or underflow is computed and thus can’t store the value in a FLOAT data type.

Error O2SS0007 Check constraint condition not parsed

Background

When you try to convert the schema of a table having a constraint condition which is checking for NAN values, SSMA generates an error “Error O2SS0007 Check constraint condition not parsed” becauseSQL Server doesn’t support floating point conditions like NAN.

Possible Remedies

Consider the below example where we have created a table and altered it by adding a constraint of NAN type:

 

CREATETABLE NANTEST

(

      COL1 BINARY_FLOAT

);

/

ALTERTABLE NANTEST ADDCONSTRAINT NANCHECK1 CHECK (COL1 ISNOT NAN);

When you try to convert the schema of the above table in SSMA, it generates the below error message:

clip_image001

The solution of the above error can be, divided into 2 steps

Step 1: Create a new table in SQL Server [The equivalent of BINARY_FLOAT in SQL Server is FLOAT(53)] without including the check constraint.

 

CREATETABLE NANTEST

(

      COL1 FLOAT(53)

)

 

Step 2: Modify the application code for inserting the values in this table. Create a TRY… CATCH block which would be restricting the users to insert an unsupported value and generate an error message similar to an error generated from a check constraint.

 

DECLARE

      @VAL FLOAT(53)

BEGIN TRY

      SET @VAL = 1/0

      INSERTINTO NANTEST VALUES (@VAL)

END TRY

 

BEGIN CATCH

      Print ('SQL error is ' + convert(varchar(20),Error_Number()) + ' : ' + convert(varchar(100),ERROR_MESSAGE()))

END CATCH;

 

Trying to use the Transact-SQL ISNUMERIC() function in a check constraint for this scenario is not a viable solution in the check constraint because ISNUMERIC() is designed to check for strings that might represent numeric values and not numeric underflow and overflow conditions.

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 


Migrating Oracle to SQL Server using SSMA - Error O2SS0038 Hierarchical query not converted

$
0
0

By Bill Ramos and Ankit Matta, Advaiya Inc.

This blog post covers one of the reasons why SQL Server Migration Assistant (SSMA) for Oracle cannot convert a hierarchical query containing complex functions in any sub query. A hierarchical query is a type of SQL query that handles hierarchical model data. For each hierarchical query one has to specify a starting condition with the START WITH clause, which will trickle down to all dependent rows using one or more conditions specified by the CONNECT BY clause.

Error O2SS0038 Hierarchical query not converted

Background

When converting the hierarchical query, SSMA provides emulation. SSMA emulates it to a corresponding solution as a recursive query. Note: A recursive CTE can greatly simplify the code required to run a recursive query within a statement. Oracle's START WITH clause becomes the first nested SELECT, the base case of the recursion, to be UNIONed with the recursive part which is just another SELECT.

Whenaggregatefunction (i.e. MAX, MIN, etc.) is used as a part of sub query in a hierarchical query, SSMA cannot convert the hierarchical query to corresponding SQL Server query and generates the O2SS0038 error message.

Possible Remedies

Consider the following example that has an aggregate function (i.e. MAX, MIN, etc.) used as a part of sub query in a hierarchical query:

CREATEORREPLACEPROCEDURE  Hierarchy_Test AS

BEGIN

  FOR c IN (

SELECT p.id, p.NAME, p.parent_id, pp.podr_cod, pp.count_chel, pp.date_start, pp.date_finish, pp.parent_podr_id

                  FROM podr p,

                  (SELECT *

                   FROM podr_param pp

                   WHERE pp.ROWID = (SELECTSUBSTR(MAX(TO_CHAR(date_start,'YYYYMMDD')||rowid),9)

                                     FROM podr_param

                                     WHERE podr_id=pp.podr_id)) pp

                   WHERE p.id = pp.podr_id

                   STARTWITH p.id = 123

                   CONNECTBYPRIOR p.id = pp.parent_podr_id)

 

LOOP

dbms_output.put_line(RPAD(c.id||'  ',15) || RPAD(c.podr_cod||'  ',15) || RPAD(c.NAME||'  ',15) || RPAD(TO_CHAR(c.date_start,'DD.MM.YYYY')||'  ',15) || RPAD(TO_CHAR(c.date_finish,'DD.MM.YYYY'),15));

ENDLOOP;

END;

The solution is to simplify the nested sub query containing any aggregate Function. In our example, the hierarchical query containing aggregate function (MAX) in a sub query is not converted into the equivalent SQL query.

To resolve this error, we’ll create a new function in Oracle and call that function in the nested query. The function will calculate the desired value and pass it into the nested query. Below is the sample Function, for the above query:

CREATEORREPLACEfunction max_val(date_start DATE)

RETURNVARCHAR

IS val VARCHAR(20);

BEGIN

SELECTROWIDfrom podr_param WHERE date_start=(SELECTMAX(date_start)

INTO val

FROM podr_param);

RETURN (val);

END;

You can then call this function in within the modified procedure in the nested query and the error will be resolved. The end result would translate the Oracle's START WITH clause into the first nested SELECT, and UNION it with the recursive part which is just another SELECT.

Below is the example of the simplified procedure along with the screenshot of the converted query:

CREATEORREPLACEPROCEDURE Hierarchy_Test AS

BEGIN

FOR c IN (

SELECT p.id, p.NAME, p.parent_id, pp.podr_cod, pp.count_chel,   pp.date_start, pp.date_finish, pp.parent_podr_id

              FROM podr p,

              (SELECT *

               FROM podr_param pp

               WHERE pp.ROWID = max_val(date_start)) pp

           WHERE p.id = pp.podr_id

           STARTWITH p.id = 123

           CONNECTBYPRIOR p.id = pp.parent_podr_id) LOOP

 

dbms_output.put_line(RPAD(c.id||'  ',15) || RPAD(c.podr_cod||'  ',15) || RPAD(c.NAME||'  ',15) || RPAD(TO_CHAR(c.date_start,'DD.MM.YYYY')||'  ',15) || RPAD(TO_CHAR(c.date_finish,'DD.MM.YYYY'),15));

ENDLOOP;

END;

You can now use SSMA to convert the result to SQL Server without errors as shown below.

 

clip_image002

Related Errors

There are several other errors related to Hierarchical queries that you may encounter. These include the following:

  • O2SS0047 Hierarchical queries with asterisk not supported
  • O2SS0119 Hierarchical queries in sub query factoring clauses are not supported
  • O2SS0268 Hierarchical query with outer join cannot be converted
  • O2SS0285 Hierarchical query was not converted

In most of these situations, consider what the query is trying to accomplish and rewrite it to use the emulation.

References

For more information, check out the following references.

Migrating Oracle to SQL Server 2008 White Paper

Recursive Queries Using Common Table Expressions

Migrating Oracle to SQL Server using SSMA - Error O2SS0260 Wrapped package cannot be converted

$
0
0

By Bill Ramos and Ankit Matta, Advaiya Inc.

This blog post covers the reason why SQL Server Migration Assistant (SSMA) for Oracle does not convert the wrapped code. Wrapping (encrypting) is a process of hiding the source code. Wrapping helps to protect the source code from the competitors and others who might misuse it. In Oracle, one can wrap the source code using DBMS_DDL subprograms.

Error O2SS0260 Wrapped package cannot be converted

Background

Whenever you try to convert the WRAPed (encrypted) PL/SQL code, SSMA gives a warning message saying that the “Required code is wrapped”.  When you skip this warning by clicking Continue button, SSMA generates an error message, “Error O2SS0260 Wrapped package cannot be converted”. Also, you will be able to view only the Conversion statistics and not the code in the Assessment Report window, as the code is wrapped.

Possible Remedies

Consider the below example, where we have declared two variables, one to store the Package specification and another to store Package body as strings. These variables are then passed to a predefined stored procedure “DBMS_DDL.CREATE_WRAPPED”, which will create a wrapped package.

 

DECLARE

  src_pkg_header       VARCHAR2(32767);

  src_pkg_body         VARCHAR2(32767);

BEGIN

  src_pkg_header

      := 'CREATE OR REPLACE PACKAGE Wrapped_PKG IS '

      || 'x pls_integer; '

      || 'END Wrapped_PKG; ';

  src_pkg_body

      := 'CREATE OR REPLACE PACKAGE BODY Wrapped_PKG IS '

      || 'BEGIN '

      || 'x := 10; '

      || 'END Wrapped_PKG;';

 

  SYS.DBMS_DDL.CREATE_WRAPPED(ddl => src_pkg_header);

  SYS.DBMS_DDL.CREATE_WRAPPED(ddl => src_pkg_body);

END;

 

When you execute the above code in Oracle, a package with name “Wrapped_PKG” is created. This package is created in encrypted format, so you cannot view the text/code inside this package.

 

When you try to convert the package “Wrapped_PKG” code using SSMA, you will get Error O2SS0260.

 

clip_image001[4]

 

clip_image002[4]

 

 

The solution of the above error can be divided into steps, mentioned below:

Step 1– Create and execute only the package code in Oracle. Then convert this code into corresponding SQL Server code using SSMA.

 

CREATEORREPLACEPACKAGE Wrapped_PKG IS

x pls_integer;

END Wrapped_PKG;

 

CREATEORREPLACEPACKAGEBODY Wrapped_PKG IS

BEGIN

x := 10;

END Wrapped_PKG;

 

Below is the corresponding SQL Server code for the above Package.

 

CREATEPROCEDURE dbo.WRAPPED_PKG$SSMA_Initialize_Package

AS

   EXECUTE sysdb.ssma_oracle.db_clean_storage

   EXECUTE sysdb.ssma_oracle.set_pv_int

      'PROSEWARE',

      'DBO',

      'WRAPPED_PKG',

      'X',

      10

GO   

 

Step 2 – Copy this codeand Just add “WITH ENCRYPTION” keyword as highlighted in the code below. This will encrypt your code in SQL Server.

 

CREATEPROCEDURE dbo.WRAPPED_PKG$SSMA_Initialize_Package

WITH ENCRYPTION

AS

   EXECUTE sysdb.ssma_oracle.db_clean_storage

   EXECUTE sysdb.ssma_oracle.set_pv_int

      'PROSEWARE',

      'DBO',

      'WRAPPED_PKG',

      'X',

      10

GO

 

 

For more information regarding the ENCRYPTION clause, please refer to the MSDN help topic – CREATE PROCEDURE (Transact-SQL).  In SSMA, when you try to MODIFY the procedure by right clicking the procedure name, the MODIFY option is disabled automatically.

 

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

Migrating Oracle to SQL Server using SSMA - Error O2SS0268 Hierarchical query with outer join cannot be converted

$
0
0

By Bill Ramos and Mayank Bhanawat, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle doesn’t convert the PL/SQL block when outer joins are used in hierarchical queries.

In Oracle, CONNECT BY PRIOR is a condition that identifies the relationship between parent rows and child rows of the hierarchy. Outer Join includes data rows in the result set that do not have a match in the joined table and returns these missing columns as NULL values.

Error O2SS0268: Hierarchical query with outer join cannot be converted

Background

When an Outer Join statement is used with CONNECT BY PRIOR in hierarchical queries, SSMA doesn’t convert the statement and generate the following error ‘Error O2SS0268: Hierarchical query with outer join cannot be converted’

Possible Remedies

Consider the example below in which LEFT OUTER JOIN statement is used with CONNECT BY PRIOR statement in the hierarchical query.

Select e.empno, e1.empno, e1.mgr

From emp e LEFTOUTERJOIN emp1 e1

ON e.empno = e1.empno

Connectbyprior e1.mgr = e.deptno;

 

When SSMA tries to convert the above code, it generates following error:Error O2SS0268”

 

Error_O2SS0268

 

To resolve the above issue, rewrite the SQL code by using recursive CTE method as shown below: 

With EMPTEMP (empno, ename, mgr) as

(

select empno, ename, MGR

  from   emp

  unionall

  select e.empno, e.ename, e.MGR

  from   emp e

         join    

         emp1 e1

         on (e1.mgr = e.deptno)

)

 

SELECT e2.EMPNO, e1.EMPNO AS empno$2, e1.mgr

FROM

   EMPTEMP AS e2

      LEFTOUTERJOIN EMP1 AS e1

      ON e2.EMPNO = e1.EMPNO

GO

 

Related Errors

There are several other errors related to “Hierarchical query” that you may encounter. These include the following:

·         Error O2SS0160: SELECT statement not converted

·         Error O2SS0285: Hierarchical query was not converted

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle to SQL Server using SSMA - Error O2SS0054 Unable to convert EXCEPTION_INIT

$
0
0

By Bill Ramos and Vishal Soni, Advaiya Inc.

This blog post covers the reason why SQL Server Migration Assistant (SSMA) for Oracle cannot convert EXCEPTION_INIT.

Exception handling is a programming language construct or mechanism designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution. One can use the pragma EXCEPTION_INIT to associate exception names with other Oracle error codes that one can anticipate.

Error O2SS0054 Unable to convert EXCEPTION_INIT

Background

Whenever you try to convert PL/SQL code having an “EXCEPTION_INIT” exception with a user defined exception name in it, SSMA is unable to convert EXCEPTION_INIT because it doesn’t find an exception with the same name in the parameter section. Hence SSMA generates “Error O2SS0054 Unable to convert EXCEPTION_INIT”.

Possible Remedies

Consider the following example:

 

DECLARE

MYEXCEPTION EXCEPTION;

PRAGMA EXCEPTION_INIT(MYEXCEPTION_1, -20000);

BEGIN

NULL;

END;

 

When you execute this code in SSMA, it does not identify the user defined exception “MYEXCEPTION_1” and hence generates the error “Error O2SS0054 Unable to convert EXCEPTION_INIT”.

Note: - This is a bad code example of Oracle, as Oracle also generates an error message when you try to execute this code.

Error O2SS0054_01

 

Remediation of this error is to use the same name while declaring and defining an exception. For this, update the code as follows:

 

DECLARE

MYEXCEPTION EXCEPTION;

PRAGMA EXCEPTION_INIT(MYEXCEPTION, -20000);

BEGIN

NULL;

END;

 

SSMA will convert the updated code with no errors.

Related Errors

There are several other errors related to Exceptions that you may encounter. These include the following:

·         Error O2SS0343 FORALL statement with SAVE EXCEPTION clause is not supported

·         O2SS0055 Incorrect EXCEPTION_INIT PRAGMA parameter

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle to SQL Server using SSMA - Error O2SS0055 Incorrect EXCEPTION_INIT PRAGMA parameter

$
0
0

By Bill Ramos and Ankit Matta, Advaiya Inc.

This blog post covers the reason why SQL Server Migration Assistant (SSMA) for Oracle cannot convert EXCEPTION_INIT.

Exception handling is a programming language construct or mechanism designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution. One can use the pragma EXCEPTION_INIT to associate exception names with other Oracle error codes that one can anticipate. Once you know the error code, you can use it with pragma EXCEPTION_INIT and write a handler specifically for that error.

Error O2SS0055 Incorrect EXCEPTION_INIT PRAGMA parameter

Background

Whenever you try to convert PL/SQL code having a “PRAGMA EXCEPTION_INIT” exception without defining an error number in its parameter section, SSMA generates “Error O2SS0055 Incorrect EXCEPTION_INIT PRAGMA parameter” because it doesn’t find a numeric literal. It is mandatory to pass a negative number (i.e. the error number for which you want to throw this exception) in the parameter section.

Possible Remedies

Consider the following example:

 

DECLARE

MYEXCEPTION EXCEPTION;

PRAGMA EXCEPTION_INIT(MYEXCEPTION, '');

BEGIN

NULL;

END;

 

When SSMA doesn’t find a numeric literal in the parameter section of PRAGMA EXCEPTION_INIT, SSMA generates the error “Error O2SS0055 Incorrect EXCEPTION_INIT PRAGMA parameter”.

 

clip_image001[4]

 

Remediation of this error is to define an error number for which you want to throw this exception. For this, update the code as follows:

 

DECLARE

MYEXCEPTION EXCEPTION;

PRAGMA EXCEPTION_INIT(MYEXCEPTION, -10000);

BEGIN

NULL;

END;

 

SSMA will convert the updated code with no errors.

Related Errors

There are several other errors related to Exceptions that you may encounter. These include the following:

·         Error O2SS0343 FORALL statement with SAVE EXCEPTION clause is not supported

·         Error O2SS0054 Unable to convert EXCEPTION_INIT

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle to SQL Server using SSMA - Error O2SS0157 Dynamic string for OPEN...FOR not converted

$
0
0

By Bill Ramos and Badal Bordia, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle doesn’t convert the dynamic string within an OPEN...FOR statement and presents a natural alternative to returning cursors by using a result set returned by Transact-SQL procedures.

The OPEN-FOR statement implements the query associated with a cursor variable and assigns database resources to process the query and recognizes the result set. A CURSOR is a mechanism by which you can assign a name to a "SELECT statement" and manipulate the information within that SQL statement.

Error O2SS0157 Dynamic string for OPEN...FOR not converted

Background

In order to convert the OPEN … FOR cursor using SSMA, first you need to set the parameters in the SSMA project settings. Details about the relevant project settings are available in the blog post “Error O2SS0094 Unable to convert CURSOR as parameter”.

If you have any dynamic string in your code, the SSMA tool will generate the following error message:OPEN ... FOR statement will be converted, but the dynamic string must be converted manually”.

Possible Remedies

Consider the below example that you might find in an Oracle procedure:

Declare

     emp_refcur SYS_REFCURSOR;

      BEGIN

       OPEN emp_refcur

       FOR'Select ename from emp';

Close emp_refcur;

END;

 

When SSMA tries to convert the above code, it gives the error “Error O2SS0157 Dynamic string for OPEN...FOR not converted”.

clip_image001[4]

 

There are two possible remedies for correcting the dynamic string error:

1.       Remove the single quotes from the dynamic query to make it a static query and run SSMA against the code again. Below is the modified Oracle code:

Oracle:

Declare

     emp_refcur SYS_REFCURSOR;

     BEGIN

       OPEN emp_refcur

       FORSelect ename from emp;

Close emp_refcur;

END;

 

 

SSMA will generate the following block of Transact-SQL Code:

BEGIN

 

   DECLARE

      @emp_refcur CURSOR

 

   SET @emp_refcur =

      CURSORFOR

         SELECT EMP.ENAME

         FROM dbo.EMP

 

   OPEN @emp_refcur

 

END

GO

 

 

2.       Another way to solve this error is to use the natural approach followed in SQL Server which is returning the result set directly from executing stored procedures. In this approach, unlike Oracle, there is no need of using any cursor as output parameters.

 

For demonstrating this, let’s take the code of previous example i.e.

 

Declare

     emp_refcur SYS_REFCURSOR;

     BEGIN

       OPEN emp_refcur

       FORSelect ename from emp;

END;

 

 

SSMA generates the following corresponding SQL code. This code will simply return a cursor, which carries the reference of the values in the ename column of the emp table.

 

BEGIN

 

   DECLARE

      @emp_refcur CURSOR

 

   SET @emp_refcur =

      CURSORFOR

         SELECT EMP.ENAME

         FROM dbo.EMP

 

   OPEN @emp_refcur

 

END

 

 

SQL Server stored procedures are designed to return one or more result sets without having to define a cursor to handle the results. By executing the query used for the Oracle cursor inside of the stored procedure, you can process the result set in your application code.

 

Consider the following Transact-SQL stored procedure that can emulate the original Oracle dynamic SQL example:

 

 

ALTERPROCEDURE dbo.P_CURSOR_PROC 

  

AS

   BEGIN

     

      DECLARE

      @query nvarchar(max)

      SET @query ='Select ename from emp'

      EXECUTEsp_executesql@query

   END

GO

You can use an application written in PHP or ADO.NET to execute the query and process the results. You can refer to the MSDN help topic How to: Execute a Stored Procedure that Returns Rows for details. There is also a good tutorial on using C# from http://www.csharp-station.comLesson 07: Using Stored Procedures. For a PHP example, check out - http://www.devarticles.com/c/a/PHP/Executing-SQL-Server-Stored-Procedures-With-PHP/3/.

Related Errors

There are several other errors related to “CURSOR” that you may encounter. These include the following:

·         Error O2SS0094: Unable to convert CURSOR as parameter

·         Error O2SS0245: CURSOR conversion in return statements not supported

·         Error O2SS0330/Error O2SS0331: Unable to convert close/ FETCH statement

 

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

·         Conversion of Oracle REF CURSOR used as OUTPUT Parameter – A DB BEST Technologies blog

·         MSDN help topic How to: Execute a Stored Procedure that Returns Rows

 

Migrating Oracle to SQL Server using SSMA - Error O2SS0330/ O2SS0331: Unable to convert CLOSE/FETCH statement

$
0
0

 

By Bill Ramos and Vishal Soni, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle gives an error when converting the CLOSE and FETCH…INTO statements in a procedure where a SYS_REFCURSOR is returned as parameter.

In Oracle, SYS_REFCURSOR is used to pass cursors from and to a stored procedure

 

Error O2SS0330/O2SS0331: Unable to convert CLOSE/FETCH statement

Background

Whenever we declare a variable for SYS_REFCURSOR as a return type of the procedure and use the same variable with FETCH...INTO and CLOSE statement, it gives the following errors:

·         Error O2SS0330: Unable to convert CLOSE statement

·         Error O2SS0331: Unable to convert FETCH statement

Possible Remedies

Consider the below example query in which we have declared a variable as SYS_REFCURSOR, used as a return type of a procedure.

CREATEORREPLACEPROCEDURE p_close_refcursor

      (

         emp_refcur OUT SYS_REFCURSOR

      )

   IS

      departmentno dept.deptno%TYPE;

   BEGIN

      OPEN emp_refcur

         FOR

            SELECT deptno

            FROM dept;

      LOOP

         FETCH emp_refcur

            INTO departmentno;

          EXITWHEN emp_refcur%NOTFOUND;

         DBMS_OUTPUT.PUT_LINE(departmentno);

      ENDLOOP;

      CLOSE emp_refcur;

   END;

 

When we execute the above query in SSMA, it generate the errors as shown in the below figure.

Error O2S0330_01

There are two possible remedies for correcting this error:

1.       First method is to create and use a local cursor for doing all operations, and then passing its value to the returning cursor before closing it. For this, declare a new variable of SYS_REFCURSOR type which will be local to this procedure. Modify the code to use this local cursor to perform the required operation including FETCH...INTO and CLOSE statement. Before closing the local cursor, pass the value of this local cursor to the cursor defined in the parameter section of procedure i.e. emp_refcur in our example.

The solution for the above error is shown in the code below:  

CREATEORREPLACEPROCEDURE p_close_refcursor

(

emp_refcur OUT SYS_REFCURSOR

)

AS

test_cursor SYS_REFCURSOR;

departmentno dept.deptno%TYPE;

   BEGIN

      OPEN test_cursor

         FOR

            SELECT deptno

            FROM dept;

      LOOP

         FETCH test_cursor

            INTO departmentno;

          EXITWHEN test_cursor%NOTFOUND;

         DBMS_OUTPUT.PUT_LINE(departmentno);

      ENDLOOP;

      emp_refcur := test_cursor;

      CLOSE test_cursor;

   END;

Error O2S0330_02 

2.       Another way to solve this error is to use the natural approach followed in SQL Server which is returning the result set directly from executing stored procedures. This approach is explained in detail in another blog related to SSMA “Error O2SS0157 Dynamic string for OPEN...FOR not converted”

Related Errors

There are several other errors related to “CURSOR” that you may encounter. These include the following:

·         Error O2SS0094: Unable to convert CURSOR as parameter

·         Error O2SS0245: CURSOR conversion in return statements not supported

·         Error O2SS0157 Dynamic string for OPEN...FOR not converted

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

·         Conversion of Oracle REF CURSOR used as OUTPUT Parameter – A DB BEST Technologies blog

 


Migrating Oracle to SQL Server using SSMA - O2SS0359 Cannot get description for return type of function call expression

$
0
0

By Bill Ramos and Badal Bordia, Advaiya Inc.

This blog post covers the reason why SQL Server Migration Assistant (SSMA) for Oracle is not able to convert the record set which is returned as the return type of the function. A Function is a block of code that performs a particular task and then returns control to the calling code. When it returns control, it also returns a value to the calling code. When a function returns a value, the value is returned via a return statement to the caller of the function, after being implicitly converted to the return type of the function in which it was defined.

Error O2SS0359 cannot get description for return type of function call expression

Background

Whenever you call a function that returns a record in another procedure, SSMA is not able to resolve that data type. Hence, when you try to use this record set in your called procedure, SSMA generates an error.

 

Possible Remedies

Consider the below example in which we have created a procedure (print_emp), in which we are calling another function (get_employeeTbl) that is returning a record.

Main Procedure “Print_emp” code

CREATEORREPLACEprocedure print_emp(p_empl_no in emp.empno%type) as

Proc_Table emp%rowtype;

begin

Proc_Table := get_employeeTbl(p_empl_no);

dbms_output.put_line(Proc_Table.empno);

dbms_output.put_line(Proc_Table.ename);

dbms_output.put_line(Proc_Table.job);

dbms_output.put_line(Proc_Table.mgr);

dbms_output.put_line(Proc_Table.hiredate);

dbms_output.put_line(Proc_Table.sal);

dbms_output.put_line(Proc_Table.comm);

dbms_output.put_line(Proc_Table.deptno);

end;

Called Function “Get_employeeTbl”

CREATEORREPLACEfunction get_employeeTbl

(p_empl_no in emp.empno%type)

return emp%rowtype

as

l_cust_record emp%rowtype;

begin

select * into l_cust_record from emp

where empno = p_empl_no;

return(l_cust_record);

end;

When SSMA tries to convert the above code of main procedure (print_emp), it does not resolve the operations of called function (get_emploreeTbl) which is returning a record and hence generates error “Error O2SS0359 cannot get description for return type of function call expression”.

clip_image001

 

The solution of the above error is to rewrite the code in SQL Server. As SQL Server supports scalar functions, inline table-valued functions and multi statement table-valued functions, you can declare a temporary Table (@my table) within the T_SQL Code of called function. In the code you fill this table using your same business Logic and then return this table back to the calling environment.  In the calling function, you also have to use table variable to store the return value (record set in our case) of called function.

Below is the rewritten code of above example

Main Procedure “Print_emp” code

CreatePROCEDURE [dbo].[PRINT_EMP](@p_empl_no Int)

AS   

BEGIN

Declare

@Proc_table Table

(EMPNO Int, ENAME Varchar(max), JOB Varchar(max), MGR Float,   

HIREDATE DATETIME  , SAL Float  , COMM Float  , DEPTNO Float);

Insertinto @Proc_table(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO)

Select*from dbo.GET_EMPLOYEETBL(@p_empl_no)

Select*from @Proc_table

END

Go

Called Function “Get_employeeTbl”

CreateFunction [dbo].[GET_EMPLOYEETBL](@p_empl_no Int)

Returns @Mytable Table

(EMPNO Int, ENAME Varchar(max), JOB Varchar(max), MGR Float,     

HIREDATE DATETIME, SAL Float, COMM Float, DEPTNO Float)

As 

BEGIN

Insertinto  @mytable(EMPNO,ENAME , JOB , MGR , HIREDATE , SAL , COMM ,

DEPTNO)SELECT

EMP.EMPNO,EMP.ENAME, EMP.JOB, EMP.MGR,EMP.HIREDATE, EMP.SAL, EMP.COMM,

EMP.DEPTNO  FROM dbo.EMP WHERE EMP.EMPNO = @p_empl_no

Return

End

Go    

Related Errors

There are several other errors related to “Collection and Records” that you may encounter. These include the following:

·         Error O2SS0380 Unable to convert function with record return type

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle to SQL Server using SSMA - O2SS0264 Unable to convert cursor or cursor variable as a function or procedure call parameter

$
0
0

By Bill Ramos and Mayank Bhanawat, Advaiya Inc.

This blog post describes why SQL Server Migration Assistant (SSMA) for Oracle does not convert the PLSQL block when a cursor or cursor variable is passed as a parameter to a function or procedure call.

A cursor is a mechanism by which you can assign a name to a "SELECT statement" and manipulate the information within that SQL statement. Cursors are used by database programmers to process individual rows returned by database system queries. In Oracle, SYS_REFCURSOR is used to pass cursors from and to a stored procedure

O2SS0264: Unable to convert cursor or cursor variable as a function or procedure call parameter

Background

When a cursor or cursor variable is passed as a parameter to a function or procedure call, SSMA cannot convert that statement and generates following error “ErrorO2SS0264: Unable to convert cursor or cursor variable as a function or procedure call parameter”

Possible Remedies

Consider the below example query in which we have declared a variable as SYS_REFCURSOR and passed this variable as parameter to a procedure call.

 

Procedure:

CREATEORREPLACEPROCEDURE p_close_refcursor

(

emp_refcur OUT SYS_REFCURSOR

)

AS

test_cursor SYS_REFCURSOR;

departmentno dept.deptno%TYPE;

   BEGIN

      OPEN test_cursor

         FOR

            SELECT deptno

            FROM dept;

      LOOP

         FETCH test_cursor

            INTO departmentno;

          EXITWHEN test_cursor%NOTFOUND;

         DBMS_OUTPUT.PUT_LINE(departmentno);

      ENDLOOP;

      emp_refcur := test_cursor;

      CLOSE test_cursor;

END;

 

Statement:

DECLARE

emp_cur SYS_REFCURSOR;

BEGIN

p_close_refcursor(emp_cur);

END;

 

When we execute the above statement in SSMA, it generate the Error ‘O2SS0264’ as shown in the below figure.

 

clip_image001

 

To solve this error, first you can convert the procedure (P_CLOSE_REFCURSOR) in SQL Server using SSMA and do following modifications in SQL code:

1.       When SSMA convert the Oracle procedure in SQL Server, it converted the CURSOR (@emp_refcur) type to varchar (8000). But in SQL server we can declare cursor data type in an OUTPUT Parameter in following way    “@emp_refcur CursorVarying  OUTPUT”.

2.       Also SSMA initializes the variable @emp_refcur (which was a of type varchar (8000)) with null value. So after changing its type we have to remove this initialization by commenting the statement (SET @emp_refcur = NULL).

For this, we need to update the SQL Server Transact-SQL code as follows:

 

Procedure:  

 

CREATEPROCEDURE dbo.P_CLOSE_REFCURSOR 

   @emp_refcur CursorVarying  OUTPUT

AS

  

   BEGIN

 

      --SET @emp_refcur = NULL

 

      DECLARE

         @test_cursor CURSOR,

         @departmentno float(53)

 

      SET @test_cursor =

         CURSORFOR

            SELECT DEPT.DEPTNO

            FROM dbo.DEPT

 

      OPEN @test_cursor

 

      WHILE1 = 1

 

        BEGIN

            FETCH @test_cursor

                INTO @departmentno

                  IF @@FETCH_STATUS <> 0

               BREAK

            PRINT @departmentno

         END

 

      SET @emp_refcur = @test_cursor

      CLOSE @test_cursor

      DEALLOCATE @test_cursor

 

   END

Go

 

Now you can use the below code to call the above mentioned procedure by passing the cursor variable

 

Statement:

Declare @cursor_variable cursor

Execute dbo.P_CLOSE_REFCURSOR@cursor_variable

 

 

Related Errors

There are several other errors related to “CURSOR” that you may encounter. These include the following:

·         Error O2SS0094: Unable to convert CURSOR as parameter

·         Error O2SS0245: CURSOR conversion in return statements not supported

·         Error O2SS0157 Dynamic string for OPEN...FOR not converted

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

·         Conversion of Oracle REF CURSOR used as OUTPUT Parameter – A DB BEST Technologies blog

 

Migrating Oracle to SQL Server using SSMA - Error O2SS0347 Comparison of record or collection expressions is not supported

$
0
0

By Bill Ramos and Badal Bordia, Advaiya Inc.

This blog post covers the reasons why SQL Server Migration Assistant (SSMA) for Oracle does not support comparison of Records or collection variables.

A collection is an ordered group of elements, all of the same type. It is a general concept that encompasses lists, arrays, and other familiar data types. Each element has a unique subscript that determines its position in the collection.

Error O2SS0347 Comparison of record or collection expressions is not supported

Background

Whenever a PL/SQL block with comparison operator like “=” or “IN” etc. is encountered with operands of type collection or record, “Error O2SS0347 Comparison of record or collection expressions is not supported” is generated.

Possible Remedies

Consider the below example, where we are comparing two collections by using “=” operator:

DECLARE

      TYPE SIMPLE_COLLECTION ISTABLEOFINTEGER;

      VARCOLL1 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 1, 1);

      VARCOLL2 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 1, 1);

BEGIN

      IF VARCOLL1 = VARCOLL2 THEN

            DBMS_OUTPUT.PUT_LINE(1);

      ELSE

            DBMS_OUTPUT.PUT_LINE(0);

      ENDIF;

END;

 

When SSMA tries to convert the above code, it does not resolve the operator and hence generates error “Error O2SS0347 Comparison of record or collection expressions is not supported

 

clip_image001

The solution of the above error is to rewrite the code in Oracle.Unlike Oracle, Microsoft SQL Server supports neither records nor collections and its associated operations on them. So, when you migrate from Oracle to SQL Server using SSMA, you must apply substantial transformations to the PL/SQL code. Below is the rewritten Oracle code:

DECLARE

      TYPE SIMPLE_COLLECTION ISTABLEOFINTEGER;

      VARCOLL1 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 2,3);

      VARCOLL2 SIMPLE_COLLECTION := SIMPLE_COLLECTION(1, 2,3);

      j PLS_INTEGER := 0;

 

BEGIN

      if VARCOLL1.count=VARCOLL2.countthen

      FOR i IN1..VARCOLL1.count

      LOOP

            IF VARCOLL1(i) = VARCOLL2(i) THEN

                  j:=1;

            else

                  j:=0;

                  DBMS_OUTPUT.PUT_LINE(0);

            Exit;

            Endif;

      ENDLOOP;

If j=1then

DBMS_OUTPUT.PUT_LINE(1);

Endif;

      Else

        DBMS_OUTPUT.PUT_LINE(0);

      Endif;

END;

 

Corresponding SQL Server Code:

 

BEGIN

   DECLARE

      @CollectionIndexInt$TYPE varchar(max) = ' TABLE OF INT'

   DECLARE

      @VARCOLL1 dbo.CollectionIndexInt = dbo.CollectionIndexInt ::[Null].SetType(@CollectionIndexInt$TYPE).AddInt(1).AddInt(2).AddInt(3),

      @VARCOLL2 dbo.CollectionIndexInt = dbo.CollectionIndexInt ::[Null].SetType(@CollectionIndexInt$TYPE).AddInt(1).AddInt(2).AddInt(3),

      @j int = 0

   IF @VARCOLL1.Count = @VARCOLL2.Count

      BEGIN

         BEGIN

            DECLARE

               @i int

               SET @i = 1

            DECLARE

               @loop$bound int

            SET @loop$bound = @VARCOLL1.Count

            WHILE @i <= @loop$bound

          BEGIN

             IF @VARCOLL1.GetInt(@i) = @VARCOLL2.GetInt(@i)

                   SET @j = 1

             ELSE

          BEGIN

                   SET @j = 0

                   PRINT 0

                   BREAK

          END

               SET @i = @i + 1

          END

         END

               IF @j = 1

               PRINT 1

      END

   ELSE

      PRINT 0

END

GO

Related Errors

There are several other errors related to “Collection” that you may encounter. These include the following:

·         Error O2SS0407 Unsupported collection key type

·         Error O2SS0408 Collection or record type is not supported

·         Error O2SS0352 BULK COLLECT INTO clause in SELECT statement not converted

References

For more information, check out the following references:

·         Migrating Oracle to SQL Server 2008 White Paper

 

Migrating Oracle ANYDATA to SQL Server

$
0
0

By Welly Lee, Pinaki Bag, and Jayakumar Tanneru.

Oracle has an object data type called anydata. This data type supports wide range of data types. For example when creating a table with a column defined as anydata type, the column can store many types of data from string to numeric . SSMA does not support migration of anydata and when migrating Oracle database containing the type, SSMA raise a migration error O2SS0005: Source datatype not recognized.

SQL Server has a similar data type called sql_variant. sql_variant provides simpler data management and provide additional capabilities:

  1. Oracle anydata is an object type that includes static and member procedures and functions. Using anydata type requires the use of convert function to store and an utility function to retrieve the value. sql_variant stores data value directly and values can be retrieved without explicit conversion.

    Oracle

    SQL Server

    CREATE TABLE tbl1 (col1 anydata);

    CREATE TABLE tbl1 (col1 sql_variant)

    INSERT INTO tbl1 (col1) VALUES (sys.anydata.convertnumber(123.4));

    INSERT INTO tbl1 (col1) VALUES (123.4)

    INSERT INTO tbl1 (col1) VALUES (sys.anydata.convertvarchar2('abc'));

    INSERT INTO tbl1 (col1) VALUES ('abc')

    INSERT INTO tbl1 (col1) VALUES (sys.anydata.convertdate(sysdate));

    INSERT INTO tbl1 (col1) VALUES (getdate())


    SELECT * FROM tbl1;

    COL1()
    -------------------------------
    ANYDATA()
    ANYDATA()
    ANYDATA() 

    /* anydata values can be retrieving by using function such as described in this article */

    SELECT getData(col1) FROM tbl1;

    GETDATA(COL1)
    ---------------------------------
    123.4
    abc
    21-JUN-11

    SELECT * FROM tbl1

    Col1
    --------------------
    123.4
    abc
    2011-06-21 00:00:00.001

    /* note that a sql_variant data type must first be cast to its base data type value before participating in operations such as addition and subtraction. For example: */

    DECLARE @var sql_variant
    SET @var = 2
    SELECT CONVERT(int,@var) - 1
  2. Index cannot be created on the column with anydata type. sql_variant column can be included in the index (as long as the value does not exceed 900 bytes).

    -- Sample SQL Server statement:
    CREATE INDEX idx_test ON tbl1 (col1)
  3. sql_variant can be assigned a default value. This data type can also have NULL as its underlying value, but the NULL values will not have an associated base type.

    -- Sample SQL Server statements:
    CREATE TABLE tbl2 (col1 int, col2 sql_variant DEFAULT 'some value')
    CREATE TABLE tbl3 (col1 int, col2 sql_variant DEFAULT NULL)

For many cases, sql_variant can be used to replace anydata type when migrating Oracle to SQL Server. However, note the following limitation:

  1. sql_variant supports smaller size and fewer data types. sql_variant can have a maximum length of 8016 bytes. This includes both the base type information and the base type value. The maximum length of the actual base type value is 8,000 bytes. sql_variant also have limitation for supporting the following types:
    Oracle Data TypeComparable SQL Server Data Type
    rawvarbinary(max)
    blobvarbinary(max)
    cblobvarchar(max)
    bfileFILESTREAM storage
    user defined typeuser defined type
    timestamptimestamp/datetime2
    interval 
    spatial (geography/geometry)spatial (geography/geometry)
    xmltypexml
  2. ODBC does not fully support sql_variant. Therefore, queries of sql_variant columns are returned as binary data when you use Microsoft OLE DB Provider for ODBC (MSDASQL).

If you are unable to use sql_variant due to the technical limitation above, you may consider to migrate the anydata as separate columns based on its individual types (SQL Server 2008 supports Sparse Column to optimize storing data across multiple columns with many NULL values). Alternatively, you can also consider to convert anydata to xml type (note the limitations of xml data type)

-- Sample SQL Server Statements:
CREATE TABLE tbl1 (col1 xml)
INSERT INTO tbl1 VALUES ('<root><data>123.4</data><datatype>decimal(13,5)</datatype></root>')
INSERT INTO tbl1 VALUES ('<root><data>abc</data><datatype>varchar(max)</datatype></root>')
INSERT INTO tbl1 VALUES ('<root><data>'+cast(getdate() as varchar(max))+'</data><datatype>datetime</datatype></root>')

SELECT col1.value('(/root/data)[1]','varchar(max)') from tbl1  -- returning data values
SELECT col1.value('(/root/datatype)[1]','varchar(max)') from tbl1  -- returning data types

REFERENCE

SQL Server 2008R2 Books Online : sql_variant

Migrating Oracle to SQL Server using SSMA - Error O2SS0217 Call to identity sequence CURRVAL not supported

$
0
0

By Bill Ramos and Badal Bordia, Advaiya Inc.

[Updated 2/8/2012 Jiafei Yuan - Microsoft SQL Server Migration Assistant (SSMA) for Oracle v5.2. The information provided below is still valid for SSMA for Oracle v5.2. However, with SSMA v5.1, we can leverage SQL Server 2012's sequence as the conversion target for Oracle's sequences (Converting Oracle Sequence to SQL Server "Denali").]

This blog post covers some of the reasons why SQL Server Migration Assistant (SSMA) for Oracledoesn’t convert some procedure containing a Sequence with CURRVAL function. A Sequence is an independent database object in Oracle, which automatically creates unique integers typically for primary key/foreign values. A CURRVAL is used to access the current value of the specified Sequence.

Error O2SS0217 Call to identity Sequence CURRVAL not supported

Background

When converting Sequence object with the CURRVAL function, SSMA uses two techniques namely, ‘Emulation’ and ‘Sequence to Identity conversion’. In Emulation, SSMA converts the source schema and generates two additional objects in the target SQL Server schema for each Sequence. In the ‘Sequence to Identity conversion’, SSMA does not convert the Oracle Sequence to the IDENTITY in SQL Server and generates an error, which is described in this post.

For more information on how SSMA implements the Oracle sequence object, please see the article from DBBest titledMigration of Oracle sequences to SQL Server 2005/ 2008

Reasons

In Oracle, a sequence that generates a value typically used for a primary key/foreign key relationship and the table that is using the Sequence value are completely independent. Typically, to load sequence values into table, the CURRVAL method is used with the INSERT statement.

In SQL server, we don’t have the same feature. When we want to produce key values for a table in SQL Server, we use a numeric column and call it as IDENTITY. An IDENTITY value cannot be set explicitly in SQL Server as a part of INSERT statement; hence, it generates error O2SS0217 during migration.

Possible Remedies

SSMA provides two option settings that determine how sequences are converted. One option is to convert the column using the sequence to use an identity column in SQL Server. However, if you use CURRVAL as part of an insert statement, the identity column approach will not work and triggers the error.

Consider the following example:

CREATEORREPLACEPROCEDURE  proc1 AS

  t1 NUMBER;

  t2 NUMBER;

BEGIN

      SELECT customers_seq.NEXTVALinto t1 FROM dual;

      SELECT customers_seq.currvalinto t2 FROM dual;

END;

Here, this query refers to the procedure proc1 created in Oracle, which SSMA will try to migrate to SQL server. But if the SSMA project settings as mentioned below are your default settings:

Under the Change Sequence-to-identity Conversion tab:

·         Allow sequence-to-identity conversion is selected “YES”

       [Updated: For SSMA v5.1 and later, under the Convert Sequence Generator setting, select the Using column identity option.]

·         Convert CURRVAL outside triggers is selected “NO”

Then, it should give the following error:

“O2SS0217: SQL Server Migration Assistant for Oracle Error message: Call to identity sequence CURRVAL not supported”

To resolve this error, you should perform the following steps:

1.       Click the Tools menu and select Project Settings.

clip_image001[4]

 

2.       Then, click the General tab.

clip_image002[4]

 

3.       Now, under ‘Sequence-to-identity Conversion’, select ‘Allow sequence-to-identity conversion’ to “NO”.  

       [Updated: In SSMA v5.1 later, select 'Convert Sequence Generator' to “Using SSMA sequence generator”.]

clip_image003[4]

 

Now, apply these settings and click OK.

clip_image004[4]

Related Errors

There are several other errors related to CURRVAL that you may encounter. These include the following:

·         O2SS0214 Column has bound sequence, but sequence was not found in source metadata

·         O2SS0221 Call to identity sequence NEXTVAL not supported

·         O2SS0188 Sequence not found in source metadata

References

For more information, check out the following references:

Migrating Oracle to SQL Server 2008 White Paper

CREATE SEQUENCE – Oracle Database SQL Language Reference 11g Release

Migration of Oracle sequences to SQL Server 2005/ 2008

 

Viewing all 38 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>