Considerações sobre a migração de dados¶
Nota
Considere que este é um trabalho em andamento.
Ao migrar dados do Teradata para o Snowflake, é fundamental considerar as diferenças funcionais entre os bancos de dados. Esta página apresenta as melhores sugestões para a migração de dados.
Analise as informações a seguir:
Migração de dados UNION ALL¶
UNION ALL é um operador SQL que permite a combinação de vários conjuntos de resultados. A sintaxe é a seguinte:
query_expression_1 UNION [ ALL ] query_expression_2
Para obter mais informações, consulte a seguinte documentação do Teradata.
Diferenças no tamanho da coluna¶
Mesmo que o operador seja convertido para o mesmo operador no Snowflake, pode haver diferenças detalhadas na equivalência funcional. Por exemplo, a união de colunas diferentes que têm tamanhos de coluna diferentes. O Teradata trunca os valores quando a primeira instrução SELECT contém menos espaço nas colunas.
Comportamento do Teradata¶
Nota
O mesmo comportamento nos modos de sessão ANSI e TERA.
Para este exemplo, a entrada a seguir mostrará o comportamento do Teradata.
CREATE TABLE table1
(
col1 VARCHAR(20)
);
INSERT INTO table1 VALUES('value 1 abcdefghijk');
INSERT INTO table1 VALUES('value 2 abcdefghijk');
CREATE TABLE table2
(
col1 VARCHAR(10)
);
INSERT INTO table2 VALUES('t2 row 1 a');
INSERT INTO table2 VALUES('t2 row 2 a');
INSERT INTO table2 VALUES('t2 row 3 a');
CREATE OR REPLACE TABLE table1
(
col1 VARCHAR(20)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "10/14/2024" }}'
;
INSERT INTO table1
VALUES ('value 1 abcdefghijk');
INSERT INTO table1
VALUES ('value 2 abcdefghijk');
CREATE OR REPLACE TABLE table2
(
col1 VARCHAR(10)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "10/14/2024" }}'
;
INSERT INTO table2
VALUES ('t2 row 1 a');
INSERT INTO table2
VALUES ('t2 row 2 a');
INSERT INTO table2
VALUES ('t2 row 3 a');
Caso 1 - uma única coluna: UNION ALL para uma coluna varchar (20) em vez de uma coluna varchar (10)¶
Para esse caso, a equivalência funcional é a mesma
SELECT col1 FROM table1
UNION ALL
SELECT col1 FROM table2;
value 1 abcdefghijk
t2 row 3 a
value 2 abcdefghijk
t2 row 1 a
t2 row 2 a
SELECT
col1 FROM
table1
UNION ALL
SELECT
col1 FROM
table2;
value 1 abcdefghijk
t2 row 3 a
value 2 abcdefghijk
t2 row 1 a
t2 row 2 a
Caso 2 - uma única coluna: UNION ALL para uma coluna varchar (10) em vez de uma coluna varchar (20)
Nesse caso, a equivalência de funções não é a mesma.
O caso a seguir não mostra equivalência funcional no Snowflake. Os valores das colunas devem ser truncados como na amostra do Teradata.
SELECT col1 FROM table2
UNION ALL
SELECT col1 FROM table1;
t2 row 3 a
value 1 ab --> truncated
t2 row 1 a
t2 row 2 a
value 2 ab --> truncated
SELECT
col1 FROM
table2
UNION ALL
SELECT
col1 FROM
table1;
t2 row 3 a
value 1 abcdefghijk --> NOT truncated
t2 row 1 a
t2 row 2 a
value 2 abcdefghijk --> NOT truncated
Solução alternativa para obter a mesma funcionalidade
Nesse caso, o tamanho da coluna de table2
é 10 e o de table1
é 20. Portanto, o tamanho da primeira coluna na consulta deve ser o elemento para completar a função LEFT()
usada aqui. Veja mais informações sobre a função do Snowflake LEFT HERE.
SELECT col1 FROM table2 -- size (10)
UNION ALL
SELECT LEFT(col1, 10) AS col1 FROM table1;
t2 row 1 a
t2 row 2 a
t2 row 3 a
value 1 ab
value 2 ab
Caso 3 - várias colunas - mesmo tamanho por tabela: UNION ALL para colunas varchar (20) em vez de colunas varchar (10)¶
Para esse caso, é necessário configurar novos dados da seguinte forma:
CREATE TABLE table3
(
col1 VARCHAR(20),
col2 VARCHAR(20)
);
INSERT INTO table3 VALUES('value 1 abcdefghijk', 'value 1 abcdefghijk');
INSERT INTO table3 VALUES('value 2 abcdefghijk', 'value 2 abcdefghijk');
CREATE TABLE table4
(
col1 VARCHAR(10),
col2 VARCHAR(10)
);
INSERT INTO table4 VALUES('t2 row 1 a', 't2 row 1 b');
INSERT INTO table4 VALUES('t2 row 2 a', 't2 row 2 b');
INSERT INTO table4 VALUES('t2 row 3 a', 't2 row 3 b');
CREATE OR REPLACE TABLE table3
(
col1 VARCHAR(20),
col2 VARCHAR(20)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "10/14/2024" }}'
;
INSERT INTO table3
VALUES ('value 1 abcdefghijk', 'value 1 abcdefghijk');
INSERT INTO table3
VALUES ('value 2 abcdefghijk', 'value 2 abcdefghijk');
CREATE OR REPLACE TABLE table4
(
col1 VARCHAR(10),
col2 VARCHAR(10)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "10/14/2024" }}'
;
INSERT INTO table4
VALUES ('t2 row 1 a', 't2 row 1 b');
INSERT INTO table4
VALUES ('t2 row 2 a', 't2 row 2 b');
INSERT INTO table4
VALUES ('t2 row 3 a', 't2 row 3 b');
Depois que as novas tabelas e dados forem criados, a seguinte consulta poderá ser avaliada.
Nota
Para esse caso, a equivalência funcional é a mesma
select col1, col2 from table3
union all
select col1, col2 from table4;
| col1 | col2 |
| ------------------- | ------------------- |
| value 1 abcdefghijk | value 1 abcdefghijk |
| t2 row 3 a | t2 row 3 b |
| value 2 abcdefghijk | value 2 abcdefghijk |
| t2 row 1 a | t2 row 1 b |
| t2 row 2 a | t2 row 2 b |
SELECT
col1, col2 FROM
table3
UNION ALL
SELECT
col1, col2 FROM
table4;
| col1 | col2 |
| ------------------- | ------------------- |
| value 1 abcdefghijk | value 1 abcdefghijk |
| value 2 abcdefghijk | value 2 abcdefghijk |
| t2 row 1 a | t2 row 1 b |
| t2 row 2 a | t2 row 2 b |
| t2 row 3 a | t2 row 3 b |
Caso 4 - várias colunas - mesmo tamanho por tabela: UNION ALL para colunas varchar (10) em vez de colunas varchar (20)¶
Aviso
Nesse caso, a equivalência de funções não é a mesma.
select col1, col2 from table4
union all
select col1, col2 from table3;
| col1 | col2 |
| ---------- | ---------- |
| t2 row 3 a | t2 row 3 b |
| value 1 ab | value 1 ab |
| t2 row 1 a | t2 row 1 b |
| t2 row 2 a | t2 row 2 b |
| value 2 ab | value 2 ab |
SELECT
col1, col2 FROM
table4
UNION ALL
SELECT
col1, col2 FROM
table3;
| col1 | col2 |
| ------------------- | ------------------- |
| t2 row 1 a | t2 row 1 b |
| t2 row 2 a | t2 row 2 b |
| t2 row 3 a | t2 row 3 b |
| value 1 abcdefghijk | value 1 abcdefghijk |
| value 2 abcdefghijk | value 2 abcdefghijk |
Solução alternativa para obter a mesma funcionalidade
Aplique o tamanho da coluna ao segundo SELECT
nas colunas para obter a mesma funcionalidade.
SELECT col1, col2 FROM table4 -- size (10)
UNION ALL
SELECT LEFT(col1, 10) AS col1, LEFT(col2, 10) AS col2 FROM table3;
| col1 | col2 |
| ---------- | ---------- |
| t2 row 1 a | t2 row 1 b |
| t2 row 2 a | t2 row 2 b |
| t2 row 3 a | t2 row 3 b |
| value 1 ab | value 1 ab |
| value 2 ab | value 2 ab |
Caso 5 - várias colunas - tamanhos diferentes por tabela: UNION ALL para colunas varchar (10) em vez de colunas varchar (20)¶
Para esse caso, é necessário configurar novos dados da seguinte forma:
CREATE TABLE table5
(
col1 VARCHAR(20),
col2 VARCHAR(12)
);
INSERT INTO table5 VALUES('value 1 abcdefghijk', 'value 1 abcdefghijk');
INSERT INTO table5 VALUES('value 2 abcdefghijk', 'value 2 abcdefghijk');
CREATE TABLE table6
(
col1 VARCHAR(10),
col2 VARCHAR(5)
);
INSERT INTO table6 VALUES('t2 row 1 a', 't2 row 1 b');
INSERT INTO table6 VALUES('t2 row 2 a', 't2 row 2 b');
INSERT INTO table6 VALUES('t2 row 3 a', 't2 row 3 b');
CREATE OR REPLACE TABLE table5
(
col1 VARCHAR(20),
col2 VARCHAR(12)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "10/14/2024" }}'
;
INSERT INTO table5
VALUES ('value 1 abcdefghijk', 'value 1 abcd');
INSERT INTO table5
VALUES ('value 2 abcdefghijk', 'value 2 abcd');
CREATE OR REPLACE TABLE table6
(
col1 VARCHAR(10),
col2 VARCHAR(5)
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": { "major": 0, "minor": 0, "patch": "0" }, "attributes": { "component": "teradata", "convertedOn": "10/14/2024" }}'
;
INSERT INTO table6
VALUES ('t2 row 1 a', 't2 1b');
INSERT INTO table6
VALUES ('t2 row 2 a', 't2 2b');
INSERT INTO table6
VALUES ('t2 row 3 a', 't2 3b');
Depois que as novas tabelas e dados forem criados, a seguinte consulta poderá ser avaliada.
Nota
Para esse caso, a equivalência funcional é a mesma
select col1, col2 from table5
union all
select col1, col2 from table6;
| col1 | col2 |
| ------------------- | ------------ |
| value 1 abcdefghijk | value 1 abcd |
| t2 row 3 a | t2 3b |
| value 2 abcdefghijk | value 2 abcd |
| t2 row 1 a | t2 1b |
| t2 row 2 a | t2 2b |
SELECT
col1, col2 FROM
table5
UNION ALL
SELECT
col1, col2 FROM
table6;
| col1 | col2 |
| ------------------- | ------------ |
| value 1 abcdefghijk | value 1 abcd |
| value 2 abcdefghijk | value 2 abcd |
| t2 row 1 a | t2 1b |
| t2 row 2 a | t2 2b |
| t2 row 3 a | t2 3b |
Caso 6 - várias colunas - tamanhos diferentes por tabela: UNION ALL para colunas varchar (20), varchar(10) sobre colunas varchar (10), varchar(5)¶
Aviso
Nesse caso, a equivalência de funções não é a mesma.
select col1, col2 from table6
union all
select col1, col2 from table5;
| col1 | col2 |
| -------------- | --------- |
| t2 row 3 a | t2 3b |
| **value 1 ab** | **value** |
| t2 row 1 a | t2 1b |
| t2 row 2 a | t2 2b |
| **value 2 ab** | **value** |
SELECT
col1, col2 FROM
table6
UNION ALL
SELECT
col1, col2 FROM
table5;
| col1 | col2 |
| ----------------------- | ---------------- |
| t2 row 1 a | t2 1b |
| t2 row 2 a | t2 2b |
| t2 row 3 a | t2 3b |
| **value 1 abcdefghijk** | **value 1 abcd** |
| **value 2 abcdefghijk** | **value 2 abcd** |
Solução alternativa para obter a mesma funcionalidade
A coluna com o menor tamanho da primeira SELECT
é usada para determinar o tamanho das colunas da segunda SELECT
.
SELECT
col1, col2 FROM
table6
UNION ALL
SELECT
LEFT(col1, 5) as col1, LEFT(col2, 5) AS col2 FROM
table5;
| col1 | col2 |
| -------------- | --------- |
| t2 row 3 a | t2 3b |
| **value 1 ab** | **value** |
| t2 row 1 a | t2 1b |
| t2 row 2 a | t2 2b |
| **value 2 ab** | **value** |
Caso 7 - expressão de várias colunas - tamanhos diferentes por tabela: UNION ALL para colunas varchar (20), varchar(20) sobre colunas varchar (10), varchar(10)¶
Use a configuração de dados aqui. Depois que as novas tabelas e dados forem criados, a seguinte consulta poderá ser avaliada.
Nota
Para esse caso, a equivalência funcional é a mesma
select col1 || col2 from table3
union all
select col1 || col2 from table4;
| col1 \|\| col2 |
| -------------------------------------- |
| value 1 abcdefghijkvalue 1 abcdefghijk |
| t2 row 3 at2 row 3 b |
| value 2 abcdefghijkvalue 2 abcdefghijk |
| t2 row 1 at2 row 1 b |
| t2 row 2 at2 row 2 b |
SELECT
col1 || col2 FROM
table3
UNION ALL
SELECT
col1 || col2 FROM
table4;
| col1 \|\| col2 |
| -------------------------------------- |
| value 1 abcdefghijkvalue 1 abcdefghijk |
| value 2 abcdefghijkvalue 2 abcdefghijk |
| t2 row 1 at2 row 1 b |
| t2 row 2 at2 row 2 b |
| t2 row 3 at2 row 3 b |
Caso 8 - expressão de várias colunas - tamanhos diferentes por tabela: UNION ALL para colunas varchar (20), varchar(20) sobre colunas varchar (10), varchar(10)¶
Aviso
Esse caso tem diferenças funcionais.
select col1 || col2 from table4
union all
select col1 || col2 from table3;
| col1 \|\| col2 |
| -------------------- |
| t2 row 1 at2 row 1 b |
| t2 row 2 at2 row 2 b |
| t2 row 3 at2 row 3 b |
| value 1 abcdefghijkv |
| value 2 abcdefghijkv |
SELECT
col1 || col2 FROM
table4
UNION ALL
SELECT
col1 || col2 FROM
table3;
| col1 \|\| col2 |
| -------------------------------------- |
| t2 row 1 at2 row 1 b |
| t2 row 2 at2 row 2 b |
| t2 row 3 at2 row 3 b |
| value 1 abcdefghijkvalue 1 abcdefghijk |
| value 2 abcdefghijkvalue 2 abcdefghijk |
Solução alternativa para obter a mesma funcionalidade
A soma dos tamanhos das colunas da coluna menos grande deve ser usada na função LEFT
. Por exemplo, a coluna menos grande é varchar(10), portanto, o limite da função LEFT
deve ser 20 (10 + 10).
Aviso
A soma do primeiro SELECT
se for menos grande, será usada para o truncamento dos valores.
SELECT
col1 || col2 FROM
table4
UNION ALL
SELECT
LEFT(col1 || col2, 20) FROM
table3;
| col1 \|\| col2 |
| -------------------- |
| t2 row 1 at2 row 1 b |
| t2 row 2 at2 row 2 b |
| t2 row 3 at2 row 3 b |
| value 1 abcdefghijkv |
| value 2 abcdefghijkv |
Outras considerações sobre as diferenças de tamanho de coluna¶
CHAR
eVARCHAR
se comportam da mesma forma.As colunas de números podem se comportar de forma diferente. Os números não podem ser truncados, portanto, há um estouro no ambiente Teradata. Portanto, isso não é aplicado a esses tipos de dados. Veja o exemplo a seguir:
CREATE TABLE table11
(
col1 NUMBER(2)
);
INSERT INTO table11 VALUES(10);
INSERT INTO table11 VALUES(10);
CREATE TABLE table12
(
col1 NUMBER(1)
);
INSERT INTO table12 VALUES(1);
INSERT INTO table12 VALUES(1);
INSERT INTO table12 VALUES(1);
-- ERROR! Overflow occurred when computing an expression involving table11.col1
SELECT col1 FROM table12
UNION ALL
SELECT col1 FROM table11;