Примеры использования опций sqlways.ini

[Usage example]:IMPORT_CLIENT_OPTIONS

Цель этой статьи - продемонстрировать, как опция IMPORT_CLIENT_OPTIONS влияет на результаты конвертации. Ниже приведен пример командной строки таблицы: Конвертировано с пустым значением (IMPORT_CLIENT_OPTIONS=)

:create_table
echo Creating table using the MySQL command line utility "C:\Program Files\MySQL\MySQL Workbench 8.0 CE\mysql.exe" --host=localhost --user=root --password=root --comments --port=3306 --force -vvv test1 < 
test_add_opt_tab.sql >> test_add_opt.log
goto:eof 

Преобразовано без пустого значения (IMPORT_CLIENT_OPTIONS=-init-command=«SET SESSION FOREIGN_KEY_CHECKS=0;»).

:create_table
echo Creating table using the MySQL command line utility "C:\Program Files\MySQL\MySQL Workbench 8.0 CE\mysql.exe" host=localhost --user=root --password=root --comments --port=3306 – -init-command="SET SESSION 
FOREIGN_KEY_CHECKS=0;"  -force -vvv test1 < test_add_opt_tab.sql >> test_add_opt.log
goto:eof 


[Usage example]:DESIGN_PATTERN

Исходный код (Informix 4GL)

function test()
call gethcall()
end function;

Преобразованный код Informix 4GL (DESIGN_PATTERN=Empty)

static public void test()
  {
      Isp.gethcall();
  }

Преобразованный код Informix 4GL (DESIGN_PATTERN=Swagger)

  [HttpGet("test")]
    [SwaggerOperation("Inst")]
  public void test()
  {
      Isp.gethcall();
  }


[Usage example]:DESIGN_PATTERN1

Исходный код (PBScripts)

$PBExportHeader$w_test.srw
$PBExportComments$
forward
global type w_test from window
end type
end forward

global type w_test from window
integer x = 1083
integer y = 336
integer width = 1577
integer height = 896
end type
global w_test w_test

Преобразованный код PBScripts (DESIGN_PATTERN=Empty)

public partial class w_test : WindowBase
{
    #region Singleton

    private static w_test _instance;
    public static w_test Instance
    {
        get
        {
            if (_instance == null || ! _instance.IsLoaded)
            {
                _instance = new w_test();
            }

            return _instance;
        }
    }
    #endregion

    #region Constructors

    public w_test()
    {
        InitializeComponent();
        _instance = this;
    }
    #endregion

}

Преобразованный код PBScripts (DESIGN_PATTERN=MVVM)

[HttpGet("test")]
  [SwaggerOperation("Inst")]
    public partial class w_test_srwViewModel : WindowBaseViewModel
{
    #region Singleton

    private static w_test_srwViewModel _instance;
    public static w_test_srwViewModel Instance
    {
        get
        {
            if (_instance == null || _instance.IsClosed)
            {
                _instance = new w_test_srwViewModel();
            }

            return _instance;
        }
    }
    #endregion

    #region Constructors

    public w_test_srwViewModel() : this(null)
    {
    }
    public w_test_srwViewModel(UIElementViewModel parent) : base(parent)
    {
        _instance = this;
        _instance.Parent = parent;
        Name = "w_test";
        Height = 896;
        Width = 1577;
        Margin = new ThicknessViewModel(1083, 336, 0, 0);
    }
    #endregion

    #region ViewModel

    #endregion

    #region Classes
    #endregion

}


[Usage example]:TABLES_DDL

Чтобы использовать информацию о структуре таблиц для более корректной миграции, вы можете сохранить таблицу ddl в файл и затем использовать ее как при миграции с подключением. В примере ниже показана разница в результатах, когда структура таблицы учитывается и когда нет.

Допустим, у нас есть такая таблица и запрос в Oracle. Таблица:

create table table1 (id int, str varchar(20), dt DATE);
insert into table1 values (2, '10', current_date);

Запрос:

select
   case when id=str then 0 else 1 end, 
   dt+1 
from table1;

Если преобразовать этот запрос в PostgreSQL, не имея информации о структуре таблицы, он останется прежним. Но при выполнении запроса мы получим ошибки:
1) ERROR: operator does not exist: integer = character varying
2) ERROR: operator does not exist: timestamp without time zone + integer

Чтобы избежать подобных ошибок, необходимо учитывать все типы столбцов. Добавив путь к файлу с таблицей ddl, мы получим следующий результат:

Запрос:

select 
   case when id = cast(NULLIF(str,'') as INTEGER) then 0 else 1 end, 
   (dt+INTERVAL '1 day'):: date 
from table1;

Как видите, в этом случае никаких ошибок выдано не будет, а результат select будет корректным. Исходный код Oracle:

select
   case when id=str 
      then 0 else 1 end, 
   dt+1 
from table1;

Преобразование кода PostgreSQL по умолчанию:

select
   case when id=str 
      then 0 else 1 end, 
   dt+1 
from table1;

Преобразованный код PostgreSQL + путь к таблицам ddl:

select 
   case when id = cast(NULLIF(str,'') as INTEGER) 
      then 0 else 1 end, 
   (dt+INTERVAL '1 day'):: date 
from table1;

Если этот вариант не сработал, пожалуйста, свяжитесь с нашей технической службой: support@convertum.ru.


[Usage example]:ORACLE_USE_PREPROCESSOR

Обратите внимание: опция работает только для исходной базы данных Oracle!

По умолчанию Конвертум Мастер не выполняет предварительную компиляцию объектов при использовании условной компиляции с директивой $IF. Если же для параметра ORACLE_USE_PREPROCESSOR установлено значение «Yes», то перед преобразованием объектов инструмент выполняет предварительную компиляцию для получения тела объекта без директивы $if.

Oracle source code Converted to PostgreSQL code by default Converted to PostgreSQL code with the ORACLE_USE_PREPROCESSOR =No option
create or replace function FN_COND_COMPIL_NESTED 
return varchar2 is begin $IF PKG_COND_COMPIL_NESTED_2.G_true $THEN return 'YES!'; $ELSE return 'NO!'; $END end FN_COND_COMPIL_NESTED;
CREATE OR REPLACE FUNCTION FN_COND_COMPIL_NESTED() 
RETURNS VARCHAR LANGUAGE plpgsql
AS $$
BEGIN
/* Convertum comment - Conditional Compilation Directives are not supported.
$IF PKG_COND_COMPIL_NESTED_2.G_true $THEN */ return 'YES!'; /* Convertum comment - Conditional Compilation Directives are not supported.
$ELSE */ return 'NO!'; /* Convertum comment - Conditional Compilation Directives are not supported. $END */ END; $$;
CREATE OR REPLACE FUNCTION FN_COND_COMPIL_NESTED()
RETURNS VARCHAR LANGUAGE plpgsql
   AS $$ 
BEGIN
   return 'YES!';
END; $$;


[Usage example]:MISSEDLOGIC

Исходный код на языке Паскаль По умолчанию преобразованный код на языке Pascal Преобразованный код на языке Pascal с опцией MISSEDLOGIC=Yes
unit test1;
                interface
implementation
procedure test();
var par3 : integer;
begin
par3 := sum_proc2(); end; end.
public partial class test1Unit
    {
        public static void test()
        {
            int par3 = 0;
            par3 = sum_proc2();
        }
    }
public partial class test1Unit
    {
        public static void test()
        {
            int par3 = 0;
            par3 = ((int) MissedLogic.sum_proc2());
        }
    } 
+ new generated file in GeneratedCode\MissedLogic.cs:
namespace Missed
{
    public class MissedLogic
    {
        public static object sum_proc2()
        {
            return null;
        }
    }
}


[Usage example]:RETURN_STATUS_TO

Приведенный ниже пример демонстрирует разницу в способе возврата результирующей процедуры в обоих случаях.

Исходный код ASE

create procedure sp_tab_ret_stat as
declare @c_ch integer
begin
  select @c_ch=col2 from tab_ret_stat where col1=4
  IF ( @c_ch > 20 )
  BEGIN
      SELECT 1
      RETURN( -1 )
  END
  RETURN( 0 )
end   

Преобразованный код MySQL по умолчанию (опция RETURN_STATUS_TO=INOUT)

DELIMITER //
DROP PROCEDURE IF EXISTS sp_tab_ret_stat;
//
create procedure sp_tab_ret_stat(INOUT SWP_Ret_Value INT)
   SWL_return:
BEGIN
   DECLARE v_c_ch INT;
   select   col2 INTO v_c_ch from tab_ret_stat where col1 = 4;
   IF (v_c_ch > 20) then

      SELECT 1;
      SET SWP_Ret_Value =(-1);
      LEAVE SWL_return;
   end if;
   SET SWP_Ret_Value =(0);
   LEAVE SWL_return;
END;
//
DELIMITER ;

Преобразованный код MySQL и опция RETURN_STATUS_TO=LOCAL

DELIMITER //
DROP PROCEDURE IF EXISTS sp_tab_ret_stat;
//
create procedure sp_tab_ret_stat()
   SWL_return:
BEGIN
   DECLARE v_c_ch INT;
   DECLARE SWP_Ret_Value INT;
   select   col2 INTO v_c_ch from tab_ret_stat where col1 = 4;
   IF (v_c_ch > 20) then

      SELECT 1;
      SET SWP_Ret_Value =(-1);
      LEAVE SWL_return;
   end if;
   SET SWP_Ret_Value =(0);
   LEAVE SWL_return;
END;
//
DELIMITER ; 


[Usage example]:FULLY_QUALIFY_IDENTIFIERS

В этом примере есть 3 представления, 3 функции и 3 процедуры. Различные части каждого вида объектов включают одну из 3 таблиц: tab9 из схемы по умолчанию и tab9, tab10 из схемы «db».

 EMPTY_SCHEMA =
 OUTSCHEMA = schemaname2

Если FULLY_QUALIFY_IDENTIFIERS=Yes, то каждый объект имеет schemaname2 рядом со своим именем (потому что schemaname2 было указано в OUTSCHEMA).

Если FULLY_QUALIFY_IDENTIFIERS=No, то родительские объекты (в данном случае это представления, функции, процедуры) имеют schemaname2 рядом со своим именем (потому что schemaname2 было указано в OUTSCHEMA). Но дочерние объекты (в данном случае таблицы) имеют те же имена схем, что и в исходном коде.

Пример использования для разных значений:

Исходный код (Oracle)

 create or replace view viewfqi1 as
 select * from tab9

 create or replace view viewfqi2 as
 select * from db.tab9

 create or replace view viewfqi3 as
 select * from db.tab10 

Преобразованный код (PostgreSQL)

FULLY_QUALIFY_IDENTIFIERS=Yes, by default FULLY_QUALIFY_IDENTIFIERS=No
CREATE OR REPLACE VIEW schemaname2.VIEWFQI1(COL1,COL2,COL3,COL4,COL5,COL6) AS
select COL1,COL2,COL3,COL4,COL5,COL6 from schemaname2.TAB92;

CREATE OR REPLACE VIEW
schemaname2.VIEWFQI2(COL1,COL2,COL3,COL4,COL5,COL6) AS
select COL1,COL2,COL3,COL4,COL5,COL6 from schemaname2.TAB9;

CREATE OR REPLACE VIEW schemaname2.VIEWFQI3(COL1,COL2,COL3,COL4,COL5,COL6) AS
select COL1,COL2,COL3,COL4,COL5,COL6 from schemaname2.TAB10;
CREATE OR REPLACE VIEW schemaname2.VIEWFQI1(COL1,COL2,COL3,COL4,COL5,COL6) AS
select COL1,COL2,COL3,COL4,COL5,COL6 from tab9;

CREATE OR REPLACE VIEW schemaname2.VIEWFQI2(COL1,COL2,COL3,COL4,COL5,COL6) AS
select COL1,COL2,COL3,COL4,COL5,COL6 from db.tab9;

CREATE OR REPLACE VIEW schemaname2.VIEWFQI3(COL1,COL2,COL3,COL4,COL5,COL6) AS
select COL1,COL2,COL3,COL4,COL5,COL6 from db.tab10;

Исходный код (Oracle)

 create or replace FUNCTION funcfqi1 (p1 in number)
 RETURN number
 IS
 x number;
 BEGIN 
    select col1 into x from tab9;
    return 1;
 end;

 create or replace FUNCTION funcfqi2 (p1 in number)
 RETURN number
 IS
 x number;
 BEGIN 
    select col1 into x from db.tab9;
    return 1;
 end;

 create or replace FUNCTION funcfqi3 (p1 in number)
 RETURN number
 IS
 x number;
 BEGIN 
    select col1 into x from db.tab10;
    return 1;
 end;

Преобразованный код (PostgreSQL) (FULLY_QUALIFY_IDENTIFIERS=Yes, by default)

 CREATE OR REPLACE FUNCTION schemaname2.FUNCFQI1(in P1 DOUBLE PRECISION)
 RETURNS DOUBLE PRECISION LANGUAGE plpgsql
   AS $$ 
   DECLARE 
   X  DOUBLE PRECISION; 
 BEGIN 
   select COL1 into STRICT X from schemaname2.TAB92; 
   return 1; 
 END; $$; 

 CREATE OR REPLACE FUNCTION schemaname2.FUNCFQI2(in P1 DOUBLE PRECISION) 
 RETURNS DOUBLE PRECISION LANGUAGE plpgsql 
   AS $$ 
   DECLARE 
   X  DOUBLE PRECISION; 
 BEGIN 
   select COL1 into STRICT X from schemaname2.TAB9; 
   return 1; 
 END; $$; 

 CREATE OR REPLACE FUNCTION schemaname2.FUNCFQI3(in P1 DOUBLE PRECISION) 
 RETURNS DOUBLE PRECISION LANGUAGE plpgsql 
   AS $$ 
   DECLARE 
   X  DOUBLE PRECISION; 
 BEGIN 
   select COL1 into STRICT X from schemaname2.TAB10; 
   return 1; 
 END; $$;

Преобразованный код (PostgreSQL) (FULLY_QUALIFY_IDENTIFIERS=No)

 CREATE OR REPLACE FUNCTION schemaname2.FUNCFQI1(in P1 DOUBLE PRECISION)
 RETURNS DOUBLE PRECISION LANGUAGE plpgsql
   AS $$ 
   DECLARE 
   X  DOUBLE PRECISION; 
 BEGIN 
   select COL1 into STRICT X from tab9; 
   return 1; 
 END; $$; 

 CREATE OR REPLACE FUNCTION schemaname2.FUNCFQI2(in P1 DOUBLE PRECISION) 
 RETURNS DOUBLE PRECISION LANGUAGE plpgsql 
   AS $$ 
   DECLARE 
   X  DOUBLE PRECISION; 
 BEGIN 
   select COL1 into STRICT X from db.tab9; 
   return 1; 
 END; $$; 

 CREATE OR REPLACE FUNCTION schemaname2.FUNCFQI3(in P1 DOUBLE PRECISION) 
 RETURNS DOUBLE PRECISION LANGUAGE plpgsql 
   AS $$ 
   DECLARE 
   X  DOUBLE PRECISION; 
 BEGIN 
   select COL1 into STRICT X from db.tab10; 
   return 1; 
 END; $$; 

Исходный код (Oracle)

create or replace procedure procfqi1(p1 IN number) is
begin
insert into tab9(col1, col2, col3, col4) values (p1, p1, p1, p1);
end;

create or replace procedure procfqi2(p1 IN number) is
begin
insert into db.tab9(col1, col2, col3, col4) values (p1, p1, p1, p1);
end;

create or replace procedure procfqi3(p1 IN number) is
begin
insert into db.tab10(col1, col2, col3, col4) values (p1, p1, p1, p1);
end;

Преобразованный код (PostgreSQL) (FULLY_QUALIFY_IDENTIFIERS=Yes, by default)

CREATE OR REPLACE FUNCTION schemaname2.PROCFQI1(IN P1 DOUBLE PRECISION)
RETURNS VOID LANGUAGE plpgsql
  AS $$
BEGIN
  insert into schemaname2.TAB92(COL1, COL2, COL3, COL4) values(P1, P1, P1, P1);
RETURN;
END; $$;

CREATE OR REPLACE FUNCTION schemaname2.PROCFQI2(IN P1 DOUBLE PRECISION)
RETURNS VOID LANGUAGE plpgsql
  AS $$
BEGIN
  insert into schemaname2.TAB9(COL1, COL2, COL3, COL4) values(P1, P1, P1, P1);
RETURN;
END; $$;

CREATE OR REPLACE FUNCTION schemaname2.PROCFQI3(IN P1 DOUBLE PRECISION)
RETURNS VOID LANGUAGE plpgsql
  AS $$
BEGIN
  insert into schemaname2.TAB10(COL1, COL2, COL3, COL4) values(P1, P1, P1, P1);
RETURN;
END; $$;

Преобразованный код (PostgreSQL) (FULLY_QUALIFY_IDENTIFIERS=No)

CREATE OR REPLACE FUNCTION schemaname2.PROCFQI1(IN P1 DOUBLE PRECISION)
RETURNS VOID LANGUAGE plpgsql
  AS $$
BEGIN
  insert into tab9(COL1, COL2, COL3, COL4) values(P1, P1, P1, P1);
RETURN;
END; $$;

CREATE OR REPLACE FUNCTION schemaname2.PROCFQI2(IN P1 DOUBLE PRECISION)
RETURNS VOID LANGUAGE plpgsql
  AS $$
BEGIN
  insert into db.tab9(COL1, COL2, COL3, COL4) values(P1, P1, P1, P1);
RETURN;
END; $$;

CREATE OR REPLACE FUNCTION schemaname2.PROCFQI3(IN P1 DOUBLE PRECISION)
RETURNS VOID LANGUAGE plpgsql
  AS $$
BEGIN
  insert into db.tab10(COL1, COL2, COL3, COL4) values(P1, P1, P1, P1);
RETURN;
END; $$;


[Usage example]:CONVERT_ROUTINE_TO_SP_RESULTSET

По умолчанию процедура, возвращающая набор результатов, будет преобразована в процедуру с дополнительными параметрами out (столбец 2). В случае значения опции CONVERT_ROUTINE_TO_SP_RESULTSET=Yes, результат будет возвращен оператором SELECT.

Исходный код Informix:

 CREATE PROCEDURE sp_call_sp_with_param2(p1 char(10), p2 integer)
 RETURNING INTEGER,CHAR,INTEGER;
 DEFINE v1 INTEGER;
 DEFINE v2 CHAR(2);
 DEFINE v3 INTEGER;
 select col1, col2, col3 INTO v1,v2,v3 from tab1;
    RETURN v1,v2,v3;
 END PROCEDURE;

Преобразованный код MSSQL (CONVERT_ROUTINE_TO_SP_RESULTSET=No, by default)

 CREATE PROCEDURE dbo.sp_call_sp_with_param2 @p1 CHAR(10), @p2 INT,@SWP_Ret_Value INT = NULL OUTPUT ,@SWP_Ret_Value1 CHAR = NULL OUTPUT ,@SWP_Ret_Value2 INT = NULL OUTPUT 
 AS
 BEGIN
    declare @j_qte INT
    declare @v1 INT
    declare @v2 CHAR(2)
    declare @v3 INT
    select @v1 = col1, @v2 = col2, @v3 = col3 from dbo.tab1
    if @@ROWCOUNT = 0
       select @v1 = null, @v2 = null, @v3 = null
    set @SWP_Ret_Value = @v1
    set @SWP_Ret_Value1 = @v2
    set @SWP_Ret_Value2 = @v3
    RETURN
 END

Преобразованный код MSSQL (CONVERT_ROUTINE_TO_SP_RESULTSET=Yes)

 CREATE PROCEDURE dbo.sp_call_sp_with_param2 @p1 CHAR(10), @p2 INT 
 AS
 BEGIN
    declare @v1 INT
    declare @v2 CHAR(2)
    declare @v3 INT
    select @v1 = col1, @v2 = col2, @v3 = col3 from dbo.tab1
    if @@ROWCOUNT = 0
       select @v1 = null, @v2 = null, @v3 = null
    select @v1, @v2, @v3
    RETURN
 END


[Usage example]:CONVERT_SP_RETSTATUS_OUTPARAM

Результирующие значения могут быть возвращены из функции с оператором RETURN или из процедуры с параметром OUTPUT, как показано ниже:

Исходный код Oracle:

 create function ret_one 
 RETURN NUMBER 
 as 
 begin
    return 1 ;
 end;

Преобразованный код MSSQL Server (CONVERT_SP_RETSTATUS_OUTPARAM=No, by default)

 CREATE function RET_ONE() 
 RETURNS FLOAT 
 AS 
 begin    
    return 1  
 end

Преобразованный код MSSQL Server (CONVERT_SP_RETSTATUS_OUTPARAM=Yes)

 CREATE PROCEDURE RET_ONE @SWP_RET_VALUE FLOAT = NULL OUTPUT  
 AS 
 begin
    set @SWP_RET_VALUE = 1
    RETURN 
 end

Опцию можно установить в графическом интерфейсе (GUI): out_params

[Usage example]:ORACLE_GET_CHAR_COLUMN_SIZE

Пример использования для разных значений:

Исходный код Oracle:

 create table nihon.tabchar(col1 char(1 char), col2 char(2 char), 
 col3 char(6), col4 char(12), col5 numeric)

Преобразованный код PostgreSQL (ORACLE_GET_CHAR_COLUMN_SIZE=CHAR/Empty, by default)

 CREATE TABLE NIHON.TABCHAR
 (
    COL1 CHAR(2),
    COL2 CHAR(4),
    COL3 CHAR(6),
    COL4 CHAR(12),
    COL5 DECIMAL(38,0)
 );

Преобразованный код PostgreSQL (ORACLE_GET_CHAR_COLUMN_SIZE=BYTE)

 CREATE TABLE NIHON.TABCHAR
 (
    COL1 CHAR(1),
    COL2 CHAR(2),
    COL3 CHAR(6),
    COL4 CHAR(12),
    COL5 DECIMAL(38,0)
 );


Пример использования для разных значений:

Исходный код Sybase ASE:

create view dbo.convert_dblink_to_schema as
select ccdesk..test_tab1.col1, ccdesk..test_tab1.col2, model..tab2.col3, model..tab2.col4
from ccdesk..test_tab1, model..tab2 where ccdesk..test_tab1.col2 = model..tab2.col3 

Преобразованный код Sybase ASE по умолчанию

create or replace view convert_dblink_to_schema  as
select test_tab1.col1 as col1, test_tab1.col2 as col2, tab2.col3 as col3, tab2.col4 as col4
from test_tab1, tab2 where test_tab1.col2 = tab2.col3;

Преобразованный код Sybase ASE (CONVERT_DBLINK_TO_SCHEMA=Yes)

create or replace view convert_dblink_to_schema  as
select test_tab1.col1 as col1, test_tab1.col2 as col2, tab2.col3 as col3, tab2.col4 as col4
from ccdesk.test_tab1, model.tab2 where test_tab1.col2 = tab2.col3; 


[Usage example]:TEMPDB_TABLES_TO_TEMPORARY_TABLES

Исходный код Sybase ASE:

create procedure tempdb_tables_to_temporary_tables
as 
create table tempdb..test_tab1(col1 int, col2 int)
insert into tempdb..test_tab1 values(1,2)
drop table tempdb..test_tab1 

Преобразованный код PostgreSQL по умолчанию

create or replace procedure tempdb_tables_to_temporary_tables()
LANGUAGE plpgsql
   AS $$
BEGIN
   drop table IF EXISTS test_tab1 CASCADE;
   create table test_tab1
   (
      col1 INTEGER, 
      col2 INTEGER
   );
   insert into test_tab1  values(1,2);   drop table IF EXISTS test_tab1 CASCADE;
END; $$;

Преобразованный код PostgreSQL (TEMPDB_TABLES_TO_TEMPORARY_TABLES=Yes)

create or replace procedure tempdb_tables_to_temporary_tables()
LANGUAGE plpgsql
   AS $$
BEGIN
   drop table IF EXISTS test_tab1 CASCADE;
   create TEMPORARY table test_tab1
   (
      col1 INTEGER, 
      col2 INTEGER
   );
   insert into test_tab1  values(1,2);   drop table IF EXISTS test_tab1 CASCADE;
END; $$;


[Usage example]:USE_INDEX_NAMES

Пример ниже показывает разницу в результирующей процедуре в обоих случаях. Пожалуйста, сравните:

Исходный код MSSQL Преобразованный код в PostgreSQL по умолчанию Преобразованный код в PostgreSQL USE_INDEX_NAMES =No
CREATE
         INDEX index1
        ON
        dbo.t_index1
(col1 ASC);

CREATE
        UNIQUE  INDEX index2
        ON
        dbo.t_index1
(col1 ASC, col2 ASC); 
CREATE
INDEX index1
ON
t_index1
(col1 ASC);

CREATE
UNIQUE  INDEX index2
ON
t_index1
(col1 ASC,
col2 ASC); 
CREATE
INDEX
ON
t_index1
(col1 ASC);

CREATE
UNIQUE  INDEX
ON
t_index1
(col1 ASC,
col2 ASC); 


Если этот вариант не сработал, пожалуйста, свяжитесь с нашей технической службой: support@convertum.ru.


[Usage example]:ENSURE_UNIQUE_INDEX_NAMES

Ниже приведен пример исходного кода для создания индексов в Sybase ASA. В левой колонке приведен исходный код, во второй - преобразованный код без опции, а в третьей - результаты преобразования при установке опции ENSURE_UNIQUE_INDEX_NAMES в значение YES.

Исходный код (Sybase ASA) Преобразованный код Oracle (без опции ENSURE_UNIQUE_INDEX_NAMES или ENSURE_UNIQUE_INDEX_NAMES=No) Преобразованный код Oracle (с опцией ENSURE_UNIQUE_INDEX_NAMES=Yes)
 CREATE INDEX idx_order ON orders (order_id);

CREATE INDEX idx_order ON customers (customer_id); 
 CREATE INDEX idx_order ON orders (order_id);

-- Error: ORA-00955: name is already used by an existing object 
 CREATE INDEX orders_idx_order ON orders (order_id);

CREATE INDEX customers_idx_order ON customers (customer_id); 


Как видно, если опция ENSURE_UNIQUE_INDEX_NAMES не включена (ENSURE_UNIQUE_INDEX_NAMES=No), в процессе миграции могут возникать конфликты имен индексов, когда несколько таблиц имеют индексы с одинаковыми именами, что приводит к ошибкам в целевой базе данных.

Если опция ENSURE_UNIQUE_INDEX_NAMES включена (ENSURE_UNIQUE_INDEX_NAMES=Yes), имя таблицы ставится префиксом к имени индекса, обеспечивая его уникальность для всех таблиц. Это предотвращает конфликты и обеспечивает беспрепятственный процесс миграции.

Установка ENSURE_UNIQUE_INDEX_NAMES=Yes гарантирует, что все индексы будут успешно созданы в целевой базе данных, не требуя ручного переименования.

Напротив, если установлено значение No, существующие имена индексов сохраняются, что может привести к конфликтам, когда в таблицах существуют дублирующиеся имена индексов.

Если этот вариант не сработал, пожалуйста, свяжитесь с нашей технической службой: support@convertum.ru.


йцкйцкй