Como inserir registros de uma tabela dentro de outra quando esta tem uma chave primária com autoincremento?
A necessidade aqui é de incluir numa determinada tabela com um select de outra, mas não se esquecendo de tratar o R_E_C_N_O_, para evitar que ocorrar erro de duplicidade.
Ambiente: MSSQL, ORACLE
Lembrando que quando inserimos registro de uma tabela em outros os campos a serem inseridos devem ser iguais.
Exemplo:
Tabela 1
Campo1 int auto_increment
Campo2 Varchar(10)
Campo3 Decimal(9,2)
Campo4 Varchar(30)
Tabela 2
Campo1 int auto_increment
Campo2 Varchar(10)
Campo3 Decimal(9,2)
Campo4 Varchar(40)
Usando um INSERT com SELECT, as duas tabelas devem está identicas, para inserir, terá que informar apenas os campos que são iguais.
Errado:
INSERT INTO TABELA1 SELECT * FROM TABELA2
Certo:
INSERT INTO TABELA1 (TABELA1.CAMPO1,TABELA1.CAMPO2,TABELA1.CAMPO3) SELECT (TABELA2.CAMPO1,TABELA2.CAMPO2,TABELA2.CAMPO3) FROM TABELA2
Agora, como inserir os registros da tabela 2 na tabela 1, se o Campo 1 da tabela 1 é autoincrementável e na tabela 2, o campo 1 pode ter o mesmo sequencial, e considerando que a chave é apenas o campo auto-incrementável.
1 2 3 4 5 6 7 8 9 10 |
--Declaramos uma variavel do tipo inteira DECLARE @MAX_ID INT --Armazenos na variavel o ultimo registro da tabela de destino SELECT @MAX_ID = MAX(CAMPO1) FROM TABELA1 --Inserimos os registros da tabela2 na tabela1, respeitando o auto-incremento INSERT INTO TABELA1(CAMPO1,CAMPO2,CAMPO3) SELECT @MAX_ID + ROW_NUMBER() OVER(ORDER BY CAMPO1),TABELA2.CAMPO2,TABELA2.CAMPO3 FROM TABELA2 |
Simples assim.
Na prática, considerando que os registros a serem inclusos não existem, para não ocorrer erro de chave duplicada.
Iremos usar os campos que são identicos
1 2 3 4 5 6 7 |
DECLARE @MAX_ID INT SELECT @MAX_ID = MAX(R_E_C_N_O_) FROM CT9010 INSERT INTO CT9010 (R_E_C_N_O_,CT9_RAT_ON,CT9_SEQUEN,CT9_DESC,CT9_DEBITO,CT9_CREDIT,CT9_PERCEN,CT9_HIST,CT9_CCD,CT9_CCC,CT9_CLVLCR,CT9_CLVLDB,CT9_MOEDLC,CT9_TPSALD,CT9_VLR01) SELECT @MAX_ID + ROW_NUMBER() OVER(ORDER BY R_E_C_N_O_), CTJ_RATEIO,CTJ_SEQUEN,CTJ_DESC,CTJ_DEBITO,CTJ_CREDIT,CTJ_PERCEN,CTJ_HIST,CTJ_CCD,CTJ_CCC,CTJ_CLVLCR,CTJ_CLVLDB,CTJ_MOEDLC,CTJ_TPSALD,CTJ_VALOR FROM CTJ010 WHERE D_E_L_E_T_=' ' |
A função ROW_NUMBER(), retorna o número sequencial de uma linha dentro de uma partição de um conjunto de resultados, a partir de 1 para a primeira linha em cada partição.
A vantagem da sintaxe acima é não precisar criar uma tabela temporária.