Inquiridor
Insert em massa para dentro de uma tabela

Pergunta
-
Tenho duas proc's que o meu sistema em VB já utiliza. Uma para Insert e outra para Update. Preciso usá-la agora, direto no banco. A tabela de destino possui uma chave composta, da seguinte forma. Um campo chamado ID_OIT_LET e outro campo chamado ID_OIT. O ID_OIT ele é único, nunca se repete. O campo ID_OIT_LET, ele só recebe 1, 2 ou 3. Quando ele recebe os três valores, aí eu tenho 3 vezes o mesmo valor em ID_OIT, assim:
ID_OIT_LET ID_OIT
1 ------------------ 39510
1 ------------------ 39511
1 ------------------ 39517
2 ------------------ 39517
3 ------------------ 39517
Na tabela origem, eu tenho o ID_OIT e os campos a serem populados, que é um campo data e um varchar. Quanto ao ID_OIT_LET posso fazer o insert três vezes para gerar os valores 1,2 e 3. A minha dúvida é fazer uma espécie loop na tabela origem, para que ela vá pegando o valor e inserindo. E tem mais um problema. caso já exista aquela chave no banco, então deve-se chamar a PROC de Update e não a de Insert. Gostaria de uma ajuda, para me mostrarem qual caminho tomar. Tô meio sem idéia de como fazer. espero ter sido claro.
Todas as Respostas
-
-
Eu vim fazer um trampo de cinco dias. Como foi feito, não sei. mas se repete sim, informei errado. Ele repete, quando insiro 2 ou 3 registros para mesmo paciente nessa tabela, vide imagem. Mas como foi feito no passado, realmente não sei. Só quero gerar esse insert, terminei as outras tarefas, apontar minhas horas e esperar o grande e glorioso dia do depósito em minha conta, ehehehehehe.
Desculpe-me pela informação equivocada, o ID_OIT pode sim, se repetir. Não muitas vezes, mas acontece sim. Valeu cara.
-
José Diz, só me ajuda no seguinte. Vi que na tabela origem(Planilha_Origem), não tenho o campo ID_OIT. A tabela ID_OIT se relaciona com a tabela EXAME_REALIZADO pelo campo ID_EXM_REA. A tabela EXAME_REALIZADO se relaciona com a tabela planilha_leitura(origem) pelo campo ID_XFC. Criei a coluna ID_OIT na tabela origem(planilha_leitura ) e agora preciso popular essa tabela com os ID_OIT, algo parecido com isso, só que esse select não é possível:
update t_cmo_planilha_leitura set id_oit = (select oit.id_oit from oit1980 oit
inner join Exame_Realizado er on oit.id_exm_rea = er.id_exm_rea
inner join planilha_leitura ef on er.id_xfc = ef.id_xfc)Preiso fazer um UPD que atualize todos os registros de uma vez. Como faço isso?
-
-
-
Fiz esse insert, conforme o colega José Diz me orientou:
declare @UDT table (Num int); INSERT into @UDT values (1), (2), (3); SELECT T2.Num, T1.ID_OIT, T1.DT_RX, T1.RX_NUM from t_cmo_planilha_leitura as T1 cross join @UDT as T2; with cteComb as ( SELECT T2.Num, T1.ID_OIT, T1.DT_RX, T1.RX_NUM from t_cmo_planilha_leitura as T1 cross join (values (1), (2), (3)) as T2 (Num) ) MERGE into #t_cmo_oit1980_leitura_temp1 as D using cteComb as O on D.ID_OIT_LET = O.Num and D.ID_OIT = O.ID_OIT when matched then UPDATE set DT_RX= O.DT_RX, RX_NUM= O.RX_NUM when not matched by target then INSERT (ID_OIT_LET, ID_OIT, DT_RX, RX_NUM) values (O.Num, O.ID_OIT, O.DT_RX, O.RX_NUM) ;
O que passa é que, se a tabela está vazia, ele insere normalmente(fiz com uma temp para testes), mas se a tabela tem informação, que no caso tem 8068 registros, não acrescenta nada e me dá essa mensagem:
(3 linha(s) afetadas)
(3027 linha(s) afetadas) Mensagem 8672, Nível 16, Estado 1, Linha 104 The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.
Como proceder?
-
Porque você não gera o Cursor preenchendo as 3 linhas?
Tente fazer um teste com esse exemplo de cursor.
SET NOCOUNT ON DECLARE @tp_data VARCHAR(10), @tp_cliente INT, @tp_nickname CHAR(12), @tp_nome VARCHAR(7), @tp_hora DATETIME, @tp_teste1 VARCHAR(80), @tp_teste2 INT, @Contador INT DECLARE C1 CURSOR FOR SELECT * FROM TESTE_TB WITH (NOLOCK) WHERE teste2 = 0 OPEN C1 FETCH C1 INTO @tp_data,@tp_cliente,@tp_nickname,@tp_nome,@tp_hora,@tp_teste1,@tp_teste2 WHILE @@FETCH_STATUS = 0 BEGIN SELECT @Contador = @Contador + 1 PRINT 'Execucao ' + Convert(Varchar(5), @Contador) + ' - ' + @tp_nickname /* CONTROLE PARA INSERIR AS 3 LINHAS */ FETCH C1 INTO @tp_data,@tp_cliente,@tp_nickname,@tp_nome,@tp_hora,@tp_teste1,@tp_teste2 END CLOSE C1 DEALLOCATE C1
- Sugerido como Resposta Junior Galvão - MVPMVP quinta-feira, 20 de abril de 2017 22:59
- Marcado como Resposta Robson William Silva segunda-feira, 24 de abril de 2017 12:06
- Não Marcado como Resposta pnet segunda-feira, 24 de abril de 2017 15:14
-
Você está certo. É isso mesmo, as relações diretas. Vi que a tabela OIT1980 funciona como uma tabela associativa entre a EXAME_REALIZADO e a OIT1980_LEITURA. Preciso gerar primeiro a chave ID_OIT na tabela OIT1980, e a chave eu preciso relacionar o ID_EXM_REA baseado no ID_XFC(Paciente) e no campo ID_OIT eu dou um MAX(ID_OIT_ + 1. Preciso fazer isso, mas que a query vai percorrendo as tabelas Exame_Realizado e comparando com a Planilha_Leitura(pegando os ID_XFC) e ir adicionando na tabela OIT1980 conforme regra acima. O colega José Carvalheira citou fazer um cursor, é o melhor caminho?
-
set nocount on declare @id_xfc int, @id_exm_rea int, @id_oit int declare exame_cur cursor for select distinct er.id_exm_rea from t_cmo_Exame_Realizado er inner join t_cmo_planilha_leitura pl on er.ID_XFC = pl.ID_XFC inner join t_cmo_exame ex on er.id_exm = ex.ID_EXM where er.id_exm = 3936 and pl.NO_EXM = 'TÓRAX: P.A.' and er.NO_RX in(select pl.RX_NUM from t_cmo_planilha_leitura pl) order by er.id_exm_rea open exame_cur fetch next from exame_cur into @id_exm_rea select max(id_oit) as id_oit into t_id_oit_1 from t_cmo_oit1980 --insert into t_cmo_oit1980_temp1(id_oit) select id_oit from t_id_oit_1 while @@fetch_status = 0 begin insert into t_cmo_oit1980_temp1 select (select id_oit + 1 from t_cmo_oit1980_temp1), (@id_exm_rea) end CLOSE exame_cur DEALLOCATE exame_cur select * from t_cmo_oit1980_temp1 go
Meu código acima está correto?
Atualizei o código para o acima, e ao executar está demorando bastante. Postei essas linhas e ainda não terminou. Já vai mais de 2 minutos
-
Está demorando demais e não carrega nada. O que eu quero é só gerar registros na tabela oit1980, gerando o id_oit(PK) que é max + 1 e inserir para cada id o id_exm_rea, que é o que vem do cursor. Agora se houvesse outra forma de inserir, sem a necessidade do cursor, ficaria feliz.
-