SnowConvert AI - Oracle - DML STATEMENTS

Descrição

As extensões de instrução DML diferem das instruções DML normais porque podem usar elementos de PL/SQL como coleções e registros. Até o momento, alguns desses elementos não são compatíveis com o Snowflake Scripting. Se uma instrução não for suportada, um EWI será adicionado durante a conversão. Outras instruções DML serão convertidos como se não estivessem dentro de um procedimento.

Extensão da instrução INSERT

Referência de tradução para converter a extensão de instrução Oracle INSERT para o Script Snowflake

Nota

Algumas partes do código de saída foram omitidas por motivos de clareza.

Descrição

A extensão PL/SQL da instrução SQL INSERT permite especificar um nome de registro na values_clause da single_table_insert em vez de especificar uma lista de colunas na insert_into_clause. (Extensão da instrução INSERT da referência de linguagem Oracle PL/SQL)

O Snowflake INSERT INTO difere do Snowflake Scripting nas restrições de variáveis; é necessário que os nomes sejam precedidos por dois pontos «:» para vincular o valor das variáveis.

Recomendações

Nota

Esse código foi executado para uma melhor compreensão dos exemplos:

Oracle

CREATE TABLE numbers_table(num integer, word varchar2(20));
Copy
Snowflake
CREATE OR REPLACE TABLE PUBLIC.numbers_table (num integer,
word VARCHAR(20));
Copy

Extensão da instrução INSERT de caso simples

Oracle
CREATE OR REPLACE PROCEDURE proc_insert_statement
AS
number_variable integer := 10;
word_variable varchar2(20) := 'ten';
BEGIN 
	INSERT INTO numbers_table VALUES(number_variable, word_variable);	
	INSERT INTO numbers_table VALUES(11, 'eleven');	
END;

CALL proc_insert_statement();
SELECT * FROM numbers_table ;
Copy
Resultado

NUM

WORD

10

ten

11

onze

Script Snowflake
CREATE OR REPLACE PROCEDURE proc_insert_statement ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
	DECLARE
		number_variable integer := 10;
		word_variable VARCHAR(20) := 'ten';
	BEGIN
		INSERT INTO numbers_table
		VALUES(:number_variable, :word_variable);
		INSERT INTO numbers_table
		VALUES(11, 'eleven');
	END;
$$;

CALL proc_insert_statement();

SELECT * FROM
	numbers_table;
Copy
Resultado

NUM

WORD

10

ten

11

onze

Problemas conhecidos

1. Records are not supported by Snowflake Scripting

Como os registros não são suportados pelo script Snowflake, em vez de usar o registro VALUES, cláusula , é necessário mudá-la para uma cláusula SELECT e dividir as colunas do registro. Para obter mais informações, consulte a Seção de definição do tipo de registro.

Instrução MERGE

Referência de tradução para converter a instrução Oracle MERGE para Script Snowflake

Nota

Algumas partes do código de saída foram omitidas por motivos de clareza.

Descrição

A instrução MERGE é usada para selecionar linhas de uma ou mais fontes para atualização ou inserção em uma tabela ou exibição. É possível especificar condições para determinar se é necessário atualizar ou inserir na tabela ou exibição de destino. Essa instrução é uma maneira conveniente de combinar múltiplas operações. Permite evitar várias instruções INSERT, UPDATEe DELETE DML. MERGE é uma instrução determinística. Não é possível atualizar a mesma linha da tabela de destino várias vezes na mesma instrução MERGE. (Referência de linguagem Oracle PL/SQL, instrução MERGE)

Sintaxe Oracle MERGE

MERGE [ hint ]
   INTO [ schema. ] { table | view } [ t_alias ]
   USING { [ schema. ] { table | view }
         | ( subquery )
         } [ t_alias ]
   ON ( condition )
   [ merge_update_clause ]
   [ merge_insert_clause ]
   [ error_logging_clause ] ;

merge_update_clause := WHEN MATCHED THEN
UPDATE SET column = { expr | DEFAULT }
           [, column = { expr | DEFAULT } ]...
[ where_clause ]
[ DELETE where_clause ]

merge_insert_clause := WHEN NOT MATCHED THEN
INSERT [ (column [, column ]...) ]
VALUES ({ expr | DEFAULT }
          [, { expr | DEFAULT } ]...
       )
[ where_clause ]

error_logging_clause := LOG ERRORS 
  [ INTO [schema.] table ]
  [ (simple_expression) ]
  [ REJECT LIMIT { integer | UNLIMITED } ]

where_clause := WHERE condition
Copy
Sintaxe de script Snowflake MERGE
MERGE INTO <target_table> USING <source> ON <join_expr> 
{ matchedClause | notMatchedClause } [ ... ]

matchedClause ::= WHEN MATCHED [ AND <case_predicate> ] 
THEN { UPDATE SET <col_name> = <expr> [ , <col_name2> = <expr2> ... ] | DELETE } [ ... ]

notMatchedClause ::= WHEN NOT MATCHED [ AND <case_predicate> ] 
THEN INSERT [ ( <col_name> [ , ... ] ) ] VALUES ( <expr> [ , ... ] )
Copy

Amostra de padrões da origem

Amostra de dados auxiliares

Nota

Esse código foi executado para uma melhor compreensão dos exemplos:

Oracle
CREATE TABLE people_source (
    person_id INTEGER NOT NULL PRIMARY KEY,
    first_name VARCHAR2(20) NOT NULL,
    last_name VARCHAR2(20) NOT NULL,
    title VARCHAR2(10) NOT NULL
);

CREATE TABLE people_target (
    person_id INTEGER NOT NULL PRIMARY KEY,
    first_name VARCHAR2(20) NOT NULL,
    last_name VARCHAR2(20) NOT NULL,
    title VARCHAR2(10) NOT NULL
);

CREATE TABLE bonuses (
    employee_id NUMBER,
    bonus NUMBER DEFAULT 100
);

INSERT INTO people_target
VALUES (1, 'John', 'Smith', 'Mr');

INSERT INTO people_target
VALUES (2, 'alice', 'jones', 'Mrs');

INSERT INTO people_source
VALUES (2, 'Alice', 'Jones', 'Mrs.');

INSERT INTO people_source
VALUES (3, 'Jane', 'Doe', 'Miss');

INSERT INTO people_source
VALUES (4, 'Dave', 'Brown', 'Mr');

INSERT INTO
    bonuses(employee_id) (
        SELECT
            e.employee_id
        FROM
            hr.employees e,
            oe.orders o
        WHERE
            e.employee_id = o.sales_rep_id
        GROUP BY
            e.employee_id
    );
Copy
Snowflake
CREATE OR REPLACE TABLE people_source (
    person_id INTEGER NOT NULL PRIMARY KEY,
    first_name VARCHAR(20) NOT NULL,
    last_name VARCHAR(20) NOT NULL,
    title VARCHAR(10) NOT NULL
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

CREATE OR REPLACE TABLE people_target (
    person_id INTEGER NOT NULL PRIMARY KEY,
    first_name VARCHAR(20) NOT NULL,
    last_name VARCHAR(20) NOT NULL,
    title VARCHAR(10) NOT NULL
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

CREATE OR REPLACE TABLE bonuses (
    employee_id NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/,
    bonus NUMBER(38, 18) /*** SSC-FDM-0006 - NUMBER TYPE COLUMN MAY NOT BEHAVE SIMILARLY IN SNOWFLAKE. ***/ DEFAULT 100
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

INSERT INTO people_target
VALUES (1, 'John', 'Smith', 'Mr');

INSERT INTO people_target
VALUES (2, 'alice', 'jones', 'Mrs');

INSERT INTO people_source
VALUES (2, 'Alice', 'Jones', 'Mrs.');

INSERT INTO people_source
VALUES (3, 'Jane', 'Doe', 'Miss');

INSERT INTO people_source
VALUES (4, 'Dave', 'Brown', 'Mr');

INSERT INTO bonuses(employee_id) (
    SELECT
        e.employee_id
    FROM
        hr.employees e,
        oe.orders o
    WHERE
        e.employee_id = o.sales_rep_id
    GROUP BY
        e.employee_id
);
Copy

Caso simples da instrução MERGE

Oracle
MERGE INTO people_target pt USING people_source ps ON (pt.person_id = ps.person_id)
WHEN MATCHED THEN
UPDATE
SET
    pt.first_name = ps.first_name,
    pt.last_name = ps.last_name,
    pt.title = ps.title
    WHEN NOT MATCHED THEN
INSERT
    (
        pt.person_id,
        pt.first_name,
        pt.last_name,
        pt.title
    )
VALUES
    (
        ps.person_id,
        ps.first_name,
        ps.last_name,
        ps.title
    );

SELECT * FROM people_target;
Copy
Resultado

PERSON_ID

FIRST_NAME

LAST_NAME

TITLE

1

John

Smith

Mr

2

Alice

Jones

Mrs.

3

Jane

Doe

Miss

4

Dave

Brown

Mr

Snowflake
MERGE INTO people_target pt USING people_source ps ON (pt.person_id = ps.person_id)
WHEN MATCHED THEN
    UPDATE
SET
    pt.first_name = ps.first_name,
    pt.last_name = ps.last_name,
    pt.title = ps.title
WHEN NOT MATCHED THEN
INSERT
    (
        pt.person_id,
        pt.first_name,
        pt.last_name,
        pt.title
    )
VALUES
    (
        ps.person_id,
        ps.first_name,
        ps.last_name,
        ps.title
    );

SELECT * FROM
    people_target;
Copy
Resultado

PERSON_ID

FIRST_NAME

LAST_NAME

TITLE

1

John

Smith

Mr

2

Alice

Jones

Mrs.

3

Jane

Doe

Miss

4

Dave

Brown

Mr

Instrução MERGE com DELETE e cláusula where

Para encontrar uma equivalência entre a instrução DELETE e a cláusula where, é necessário reordenar e implementar algumas alterações na instrução de mesclagem do Snowflake.

Alterações necessárias:
  • Substitua DELETE where_clause do Oracle por uma nova matchedClause do Snowflake com a instrução AND predicate

  • Substitua where_clause de merge_insert_clause do Oracle por uma instrução AND predicate no Snowflake notMatchedClause

Oracle
MERGE INTO bonuses D USING (
    SELECT
        employee_id,
        salary,
        department_id
    FROM
        hr.employees
    WHERE
        department_id = 80
) S ON (D.employee_id = S.employee_id)
WHEN MATCHED THEN
UPDATE
SET
    D.bonus = D.bonus + S.salary *.01 DELETE
WHERE
    (S.salary > 8000)
    WHEN NOT MATCHED THEN
INSERT
    (D.employee_id, D.bonus)
VALUES
    (S.employee_id, S.salary *.01)
WHERE
    (S.salary <= 8000);

SELECT * FROM bonuses ORDER BY employee_id;
Copy
Resultado

EMPLOYEE_ID

BONUS

153

180

154

175

155

170

159

180

160

175

161

170

164

72

165

68

166

64

167

62

171

74

172

73

173

61

179

62

Snowflake
--** SSC-FDM-OR0018 - SNOWFLAKE MERGE STATEMENT MAY HAVE SOME FUNCTIONAL DIFFERENCES COMPARED TO ORACLE **
MERGE INTO bonuses D USING (
 SELECT
     employee_id,
     salary,
     department_id
 FROM
     hr.employees
 WHERE
     department_id = 80) S ON (D.employee_id = S.employee_id)
    WHEN MATCHED AND
    (S.salary > 8000) THEN
 DELETE
    WHEN MATCHED THEN
 UPDATE SET
    D.bonus = D.bonus + S.salary *.01
    WHEN NOT MATCHED AND
    (S.salary <= 8000) THEN
 INSERT
 (D.employee_id, D.bonus)
VALUES
 (S.employee_id, S.salary *.01);

SELECT * FROM
bonuses
ORDER BY employee_id;
Copy
Resultado

EMPLOYEE_ID

BONUS

153

180

154

175

155

170

159

180

160

175

161

170

164

72

165

68

166

64

167

62

171

74

172

73

173

61

179

62

Aviso

Em alguns casos, as alterações aplicadas podem não funcionar como esperado, como no exemplo a seguir:

Oracle
MERGE INTO people_target pt USING people_source ps ON (pt.person_id = ps.person_id)
WHEN MATCHED THEN
UPDATE
SET
    pt.first_name = ps.first_name,
    pt.last_name = ps.last_name,
    pt.title = ps.title DELETE
where
    pt.title = 'Mrs.'
    WHEN NOT MATCHED THEN
INSERT
    (
        pt.person_id,
        pt.first_name,
        pt.last_name,
        pt.title
    )
VALUES
    (
        ps.person_id,
        ps.first_name,
        ps.last_name,
        ps.title
    )
WHERE
    ps.title = 'Mr';

SELECT * FROM people_target;
Copy
Resultado

PERSON_ID

FIRST_NAME

LAST_NAME

TITLE

1

John

Smith

Mr

4

Dave

Brown

Mr

Snowflake
--** SSC-FDM-OR0018 - SNOWFLAKE MERGE STATEMENT MAY HAVE SOME FUNCTIONAL DIFFERENCES COMPARED TO ORACLE **
MERGE INTO people_target pt USING people_source ps ON (pt.person_id = ps.person_id)
    WHEN MATCHED AND
    pt.title = 'Mrs.' THEN
        DELETE
    WHEN MATCHED THEN
        UPDATE SET
    pt.first_name = ps.first_name,
    pt.last_name = ps.last_name,
    pt.title = ps.title
    WHEN NOT MATCHED AND
    ps.title = 'Mr' THEN
        INSERT
        (
            pt.person_id,
            pt.first_name,
            pt.last_name,
            pt.title
        )
VALUES
        (
            ps.person_id,
            ps.first_name,
            ps.last_name,
            ps.title
        );


SELECT * FROM
        people_target;
Copy
Resultado

PERSON_ID

FIRST_NAME

LAST_NAME

TITLE

1

John

Smith

Mr

2

Alice

Jones

Mrs.

4

Dave

Brown

Mr

Problemas conhecidos

1. Oracle’s error_logging_clause is not supported

Não há equivalente para a cláusula de registro de erros no Snowflake Scripting.

2. Changed applied do not work as expected

Às vezes, as alterações aplicadas para obter a equivalência funcional entre a instrução de mesclagem do Oracle e do Snowflake não funcionam como esperado.

EWIs relacionados

  1. SSC-FDM-0006: A coluna do tipo número pode não se comportar de forma semelhante no Snowflake.

  2. SSC-FDM-OR0018: A instrução de mesclagem pode não funcionar como esperado

Instrução SELECTINTO

Referência de tradução para converter a instrução Oracle SELECT INTO para Script Snowflake

Nota

Algumas partes do código de saída foram omitidas por motivos de clareza.

Descrição

A instrução SELECT INTO recupera valores de uma ou mais tabelas do banco de dados (como faz a instrução SQL SELECT) e os armazena em variáveis (o que não é feito pela instrução SQL SELECT). (Instrução SELECT INTO da referência de linguagem Oracle PL/SQL)

Sintaxe Oracle SELECT INTO

SELECT [ { DISTINCT | UNIQUE } | ALL ] select_list
    { into_clause | bulk_collect_into_clause } FROM rest-of-statement ;
Copy
Sintaxe da cláusula Oracle Into
INTO { variable [, variable ]... | record )
Copy
Sintaxe de Oracle Bulk Collect
BULK COLLECT INTO { collection | :host_array }
  [, { collection | :host_array } ]...
Copy
Sintaxe do Script Snowflake SELECT INTO
SELECT [ { ALL | DISTINCT } ]
    {
          [{<object_name>|<alias>}.]*
        | [{<object_name>|<alias>}.]<col_name>
        | [{<object_name>|<alias>}.]$<col_position>
        | <expr>
        [ [ AS ] <col_alias> ]
    }
    [ , ... ]
    INTO :<variable> [, :<variable> ... ]
    [...]
Copy

Amostra de padrões da origem

Amostra de dados auxiliares

Nota

Esse código foi executado para uma melhor compreensão dos exemplos:

Oracle
CREATE TABLE numbers_table(num integer, word varchar2(20));
INSERT INTO numbers_table VALUES (1, 'one');
CREATE TABLE aux_numbers_table(aux_num integer, aux_word varchar2(20));
Copy
Snowflake
CREATE OR REPLACE TABLE numbers_table (num integer,
word VARCHAR(20))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

INSERT INTO numbers_table
VALUES (1, 'one');

CREATE OR REPLACE TABLE aux_numbers_table (aux_num integer,
aux_word VARCHAR(20))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
Copy

Caso simples da instrução SELECTINTO

Oracle
CREATE OR REPLACE PROCEDURE proc_select_into_variables
AS
number_variable integer;
word_variable varchar2(20);
BEGIN 
	SELECT * INTO number_variable, word_variable FROM numbers_table;
	INSERT INTO aux_numbers_table VALUES(number_variable, word_variable);	
END;

CALL proc_select_into_variables();
SELECT * FROM aux_numbers_table;
Copy
Resultado

AUX_NUM

AUX_WORD

1

um

Script Snowflake
CREATE OR REPLACE PROCEDURE proc_select_into_variables ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
	DECLARE
		number_variable integer;
		word_variable VARCHAR(20);
	BEGIN
		SELECT * INTO
			:number_variable,
			:word_variable
		FROM
			numbers_table;
		INSERT INTO aux_numbers_table
		VALUES(:number_variable, :word_variable);
	END;
$$;

CALL proc_select_into_variables();

SELECT * FROM
	aux_numbers_table;
Copy
Resultado
|AUX_NUM|AUX_WORD|
|-------|--------|
|1      |one     |


Copy

Problemas conhecidos

1. BULK COLLECT INTO is not supported

O Script Snowflake não oferece suporte à cláusula BULK COLLECT INTO. Entretanto, é possível usar ARRAY_AGG para construir uma nova variável. Para obter mais informações, consulte a Seção de operações em massa de coleção.

2. Collections and records are not supported

O Script Snowflake não oferece suporte ao uso de coleções nem registros. É possível migrá-los usando tipos de dados semiestruturados, conforme explicado nesta seção.

EWIs relacionados

Sem EWIs relacionados.

Solução alternativa para simular o uso de registros

Aviso

Esta página está obsoleta, mas foi deixada para fins de compatibilidade. Se quiser ver a seção atualizada, consulte Coleções e registros

Descrição

Esta seção descreve como simular o comportamento dos registros Oracle em instruções SELECT e INSERT, usando RESULTSET e CURSORS do Snowflake Scripting.

Snowflake Scripting RESULTSET e CURSOR

Sintaxe do Snowflake RESULTSET
<resultset_name> RESULTSET [ DEFAULT ( <query> ) ] ;

LET <resultset_name> RESULTSET [ { DEFAULT | := } ( <query> ) ] ;

LET <resultset_name> RESULTSET [ { DEFAULT | := } ( <query> ) ] ;
Copy

Recomendações

Nota

Nos exemplos a seguir, esse código foi executado para melhor compreensão dos exemplos:

Oracle

CREATE TABLE numbers_table(num integer, word varchar2(20));
INSERT INTO numbers_table VALUES (1, 'one');
CREATE TABLE aux_numbers_table(aux_num integer, aux_word varchar2(20));
Copy
Snowflake
CREATE OR REPLACE TABLE numbers_table (num integer,
word VARCHAR(20))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;

INSERT INTO numbers_table
VALUES (1, 'one');

CREATE OR REPLACE TABLE aux_numbers_table (aux_num integer,
aux_word VARCHAR(20))
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
;
Copy

Usando RESULTSET e Cursores em vez de Registros

Oracle
CREATE OR REPLACE PROCEDURE proc_insert_select_resultset
AS
TYPE number_record_definition IS RECORD(
	rec_num numbers_table.num%type,
	rec_word numbers_table.word%type
);
number_record number_record_definition;
BEGIN 
	SELECT * INTO number_record FROM numbers_table;	
	INSERT INTO aux_numbers_table VALUES number_record;
END;

CALL proc_insert_select_resultset();
SELECT * FROM aux_numbers_table;
Copy
Resultado

AUX_NUM

AUX_WORD

1

um

Snowflake
CREATE OR REPLACE PROCEDURE proc_insert_select_resultset ()
RETURNS VARCHAR
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
EXECUTE AS CALLER
AS
$$
	DECLARE
		!!!RESOLVE EWI!!! /*** SSC-EWI-0056 - CUSTOM TYPES ARE NOT SUPPORTED IN SNOWFLAKE BUT REFERENCES TO THIS CUSTOM TYPE WERE CHANGED TO OBJECT ***/!!!
		TYPE number_record_definition IS RECORD(
			rec_num numbers_table.num%type,
			rec_word numbers_table.word%type
		);
		number_record OBJECT !!!RESOLVE EWI!!! /*** SSC-EWI-0036 - number_record_definition DATA TYPE CONVERTED TO OBJECT ***/!!! := OBJECT_CONSTRUCT();
	BEGIN
		SELECT
			OBJECT_CONSTRUCT( *) INTO
			:number_record
		FROM
			numbers_table;
		INSERT INTO aux_numbers_table
		SELECT
			:number_record:REC_NUM,
			:number_record:REC_WORD;
	END;
$$;

CALL proc_insert_select_resultset();

SELECT * FROM
	aux_numbers_table;
Copy

using cursor

CREATE OR REPLACE PROCEDURE PUBLIC.proc_select_into()
RETURNS INTEGER
LANGUAGE SQL
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"oracle"}}'
AS
$$
DECLARE
    NUMBER_VARIABLE INTEGER;
    WORD_VARIABLE VARCHAR;
    NUMBER_RECORD RESULTSET;
BEGIN
    LET c2 CURSOR FOR NUMBER_RECORD;
    FOR row_variable IN c2 DO
        let var1 integer := row_variable.num;
        let var2 varchar := row_variable.word;
        INSERT INTO PUBLIC.aux_numbers_table VALUES(:var1, :var2);
    END FOR;
end;
$$;
Copy
Resultado

AUX_NUM

AUX_WORD

1

um

Problemas conhecidos

1. Limitation in the use of RESULTSET

RESULTSET é muito limitado em seu uso. Se a instrução table(result_scan(last_query_id()), deve ser usada logo após a execução da consulta RESULTSET. Para obter mais informações, consulte este link.

EWIs relacionados

  1. SSC-EWI-0036: Tipo de dados convertido em outro tipo de dados.

  2. SSC-EWI-0056: Criar tipo não suportado.