none
Inserir os registros que só existem na tabela de origem RRS feed

  • Pergunta

  • Boa tarde,

    Criei o script abaixo que só faz a inserção somente dos registros que não existem na tabela teste_tb_planos_acoes, porém quero colocar mais algumas condições:

    Caso o valor da coluna designacao exista na tabela teste_tb_planos_acoes e a coluna status_fim  = encerrado, verifique se  a coluna prazo é maior que >=30 dias e faça update no registro atualizando as colunas:

    status_fim = aberto  

    Prazo = getdate()+2

    Caso contrario inserir o registro

    -- #Código 2:  Inserir os registros que só existem na tabela de origem
    
    INSERT INTO teste_tb_planos_acoes
    (
        designacao,
        cliente,
    	area,
    	qtde_log,
    	data_cad,
    	data_email_env,
    	login_cadastro,
    	rec_num,
    	status_fim,
    	prazo
    )
    SELECT distinct
        A.designacao, 
        A.Cliente,
    	desc_uds,
    	A.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	A.rec_ano,
    	'aberto',
    	GETDATE()+2
    FROM
        tb_calcula_hist_log A
       LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao 
       WHERE
        B.designacao IS NULL;

    quarta-feira, 19 de junho de 2019 17:55

Respostas

  • Experimente dessa forma:

    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            O.data_fim,
            O.dif_dias
        FROM tb_calcula_hist_log A
        OUTER APPLY
        (
            SELECT TOP(1)
                B.data_fim,
                B.status_fim,
                DATEDIFF(DAY, B.data_fim, GETDATE()) as dif_dias
            FROM teste_tb_planos_acoes B 
            WHERE 
                B.designacao = A.designacao
            ORDER BY
                B.data_fim DESC
        ) O    
        WHERE
            (O.status_fim IS NULL) OR
            ((O.status_fim = 'encerrado') and
             (O.dif_dias between 10 and 30 or O.dif_dias > 45) and
             (not exists
                 (select 1 from teste_tb_planos_acoes E
                  where
                      E.designacao = A.designacao and
                      E.status_fim = 'aberto')))
    ) AS U
        ON 
            U.designacao = T.designacao AND
            U.data_fim = T.data_fim AND
            U.dif_dias between 10 and 30

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br


    • Editado gapimex sexta-feira, 21 de junho de 2019 20:00
    • Marcado como Resposta Edvaldo A sexta-feira, 21 de junho de 2019 20:14
    sexta-feira, 21 de junho de 2019 19:59
  • Edvaldo, experimente deixar o Where de dentro do Using dessa forma:

        WHERE
            (B.designacao IS NULL) OR
            ((B.status_fim = 'encerrado') and
             ( B.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date)) or
               B.data_fim < dateadd(day, -45, cast( current_timestamp as date)) ) and
             (not exists
                 (select 1 from teste_tb_planos_acoes E
                  where
                      E.designacao = B.designacao and
                      E.status_fim = 'aberto')) )
    

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    sexta-feira, 21 de junho de 2019 18:39
  • Boa tarde,

    Segue uma sugestão para testes utilizando o comando Merge:

    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and DATEDIFF(DAY, b.prazo, GETDATE()) >= 30)
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2
    WHEN NOT MATCHED THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
            U.designacao, 
            U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        )

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br


    • Editado gapimex quarta-feira, 19 de junho de 2019 18:35
    • Sugerido como Resposta Junior Galvão - MVPMVP quarta-feira, 19 de junho de 2019 18:40
    • Marcado como Resposta Edvaldo A quarta-feira, 19 de junho de 2019 19:29
    quarta-feira, 19 de junho de 2019 18:24

Todas as Respostas

  • Boa tarde,

    Segue uma sugestão para testes utilizando o comando Merge:

    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and DATEDIFF(DAY, b.prazo, GETDATE()) >= 30)
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2
    WHEN NOT MATCHED THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
            U.designacao, 
            U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        )

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br


    • Editado gapimex quarta-feira, 19 de junho de 2019 18:35
    • Sugerido como Resposta Junior Galvão - MVPMVP quarta-feira, 19 de junho de 2019 18:40
    • Marcado como Resposta Edvaldo A quarta-feira, 19 de junho de 2019 19:29
    quarta-feira, 19 de junho de 2019 18:24
  • Edvaldo,

    Vamos lá, você deseja aplicar estas condições diretamente no momento que esta sendo processo do Insert....Select?

    Como eu não conheço o seu ambiente, muito menos a volumetria de dados, vou inicialmente sugerir que esta análise seja feito de uma forma mais aplicável pensando nas questões de performance após os dados estarem inseridos.

    Em qual momento você esta planejando fazer estas demais análises? Talvez o uso de um Trigger (mas com cuidados),  até mesmo uma Stored Procedure ou o comando Merge podem ser possibilidades.




    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    quarta-feira, 19 de junho de 2019 18:26
  • gapimex,

    Está dando erro no campo:

    Mensagem 207, Nível 16, Estado 1, Linha 111
    Nome de coluna 'designacao_B' inválido.

    quarta-feira, 19 de junho de 2019 18:32
  • Olá Junior,

    No momento do Insert.

    quarta-feira, 19 de junho de 2019 18:33
  • Edvaldo, fiz a correção dentro do Using no post anterior, experimente fazer alguns testes novamente.

    Assinatura: http://www.imoveisemexposicao.com.br



    • Editado gapimex quarta-feira, 19 de junho de 2019 18:37
    quarta-feira, 19 de junho de 2019 18:36
  • Edvaldo,

    Neste caso, o uso do comando Merge com base na solução do Gapimex vai te ajudar.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    quarta-feira, 19 de junho de 2019 18:40
  • Blz, rodou sem erros !

    O SQL disse que uma 1 linha foi afetado, como tenho alguns registros de testes, é possível saber qual foi o registro ? a titulo de validar os critérios utilizados no MERGE.



    • Editado Edvaldo A quarta-feira, 19 de junho de 2019 18:48 Correção no texto
    quarta-feira, 19 de junho de 2019 18:40
  • Experimente acrescentar a clausula Output no final:

    output $action, inserted.*
    

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 19 de junho de 2019 18:50
  • Edvaldo, 

    Sim, o que você pode fazer é adicionar a cláusula Output no bloco de Código exemplicado pelo Gapimex, como elemento de saída para você validar o posição anterior e posterior.

    Veja o exemplo:

    -- Bloco de Código - criado pelo Gapimex - Diretos Autorais pertencem a ele --
    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and DATEDIFF(DAY, b.prazo, GETDATE()) >= 30)
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2 
    WHEN NOT MATCHED THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
            U.designacao, 
            U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        )
    OUTPUT deleted.status_fim, deleted_prazo, inserted.status_fim, inserted.prazo;

    Além disso, se você quiser, pode direcionar o resultado do Merge em conjunto com o Output para uma outra tabela, veja o exemplo:

    -- Bloco de Código - criado pelo Gapimex - Diretos Autorais pertencem a ele --
    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and DATEDIFF(DAY, b.prazo, GETDATE()) >= 30)
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET 
    	 status_fim = 'aberto', prazo = GETDATE() + 2 
    WHEN NOT MATCHED THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
            U.designacao, 
            U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        )
    OUTPUT
       $action AS Acao, deleted.*, inserted.* INTO Resultado;
    
    Select  * FROM  Resultado
    Go


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    quarta-feira, 19 de junho de 2019 18:54
  • Obrigado a todos !!
    quarta-feira, 19 de junho de 2019 19:30
  • Pessoal,

    Estou testando o comando, porém esqueci de mais um critério, quando não há o MATCHED, mesmo existindo o valor na tabela teste_tb_planos_acoes verifique se DATEDIFF(DAY, b.data_fim, GETDATE()) > 45), se for maior, permitir inserir o registro, caso contrário não inserir. observação fiz algumas alterações no comando :

    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and  b.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date)))
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2, qtde_log = U.qtde_log, reaberto = 'sim'
    WHEN NOT MATCHED THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
        U.designacao, 
        U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        );



    • Editado Edvaldo A sexta-feira, 21 de junho de 2019 13:33 .
    sexta-feira, 21 de junho de 2019 13:30
  • Edvaldo,

    Você pode utilizar a condição WHEN NOT MATCHED By Target também a WHEN NOT MATCHED By Source.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sexta-feira, 21 de junho de 2019 13:41
  • Olá Junior,

    Pode exemplificar ?

    sexta-feira, 21 de junho de 2019 13:42
  • Edvaldo,

    Sim, veja este exemplo:

    CREATE TABLE sales.category (
        category_id INT PRIMARY KEY,
        category_name VARCHAR(255) NOT NULL,
        amount DECIMAL(10 , 2 )
    );
     
    INSERT INTO sales.category(category_id, category_name, amount)
    VALUES(1,'Children Bicycles',15000),
        (2,'Comfort Bicycles',25000),
        (3,'Cruisers Bicycles',13000),
        (4,'Cyclocross Bicycles',10000);
     
     
    CREATE TABLE sales.category_staging (
        category_id INT PRIMARY KEY,
        category_name VARCHAR(255) NOT NULL,
        amount DECIMAL(10 , 2 )
    );
     
     
    INSERT INTO sales.category_staging(category_id, category_name, amount)
    VALUES(1,'Children Bicycles',15000),
        (3,'Cruisers Bicycles',13000),
        (4,'Cyclocross Bicycles',20000),
        (5,'Electric Bikes',10000),
        (6,'Mountain Bikes',10000);


    MERGE sales.category t 
        USING sales.category_staging s
    ON (s.category_id = t.category_id)
    WHEN MATCHED
        THEN UPDATE SET 
            t.category_name = s.category_name,
            t.amount = s.amount
    WHEN NOT MATCHED BY TARGET 
        THEN INSERT (category_id, category_name, amount)
             VALUES (s.category_id, s.category_name, s.amount)
    WHEN NOT MATCHED BY SOURCE 
        THEN DELETE;

    Agora no seu cenário:

    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and  b.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date)))
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2, qtde_log = U.qtde_log, reaberto = 'sim'
    WHEN NOT MATCHED BY TARGET THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
        U.designacao, 
        U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        )
    WHEN NOT MATCHED BY SOURCE 
        THEN DELETE;

    Esta é somente uma adaptação, nenhum teste foi realizado ao código, veja se isso poderá lhe ajudar, sabendo que você poderá criar mais de uma instrução When Matched, veja este exemplo:

    MERGE Production.ProductInventory AS target  
    USING (SELECT ProductID, SUM(OrderQty) FROM Sales.SalesOrderDetail AS sod  
        JOIN Sales.SalesOrderHeader AS soh  
        ON sod.SalesOrderID = soh.SalesOrderID  
        AND soh.OrderDate = @OrderDate  
        GROUP BY ProductID) AS source (ProductID, OrderQty)  
    ON (target.ProductID = source.ProductID)  
    WHEN MATCHED AND target.Quantity - source.OrderQty <= 0  
        THEN DELETE  
    WHEN MATCHED   
        THEN UPDATE SET target.Quantity = target.Quantity - source.OrderQty,   
                        target.ModifiedDate = GETDATE()  
    OUTPUT $action, Inserted.ProductID, Inserted.Quantity, 
        Inserted.ModifiedDate, Deleted.ProductID,  
        Deleted.Quantity, Deleted.ModifiedDate;  
    GO  
    

    Referências: https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-2017

    http://www.sqlservertutorial.net/sql-server-basics/sql-server-merge/


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sexta-feira, 21 de junho de 2019 13:50
  • MERGE sales.category t 
        USING sales.category_staging s
    ON (s.category_id = t.category_id)
    WHEN MATCHED
        THEN UPDATE SET 
            t.category_name = s.category_name,
            t.amount = s.amount
    WHEN NOT MATCHED BY TARGET 
        THEN INSERT (category_id, category_name, amount)
             VALUES (s.category_id, s.category_name, s.amount)
    WHEN NOT MATCHED BY SOURCE 
        THEN DELETE;

    Agora no seu cenário:

    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and  b.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date)))
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2, qtde_log = U.qtde_log, reaberto = 'sim'
    WHEN NOT MATCHED BY TARGET THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
        U.designacao, 
        U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        )
    WHEN NOT MATCHED BY SOURCE 
        THEN DELETE;

    Esta é somente uma adaptação, nenhum teste foi realizado ao código, veja se isso poderá lhe ajudar, sabendo que você poderá criar mais de uma instrução When Matched, veja este exemplo:

    Interessante ! confesso que nunca tinha utilizado o comando MERGE.

    Uma dúvida em que momento no código está sendo feito a checagem que eu mencionei :

    quando não há o MATCHED, mesmo existindo o valor na tabela teste_tb_planos_acoes verifique se DATEDIFF(DAY, b.data_fim, GETDATE()) > 45), se for maior, permitir inserir o registro, caso contrário não inserir

    sexta-feira, 21 de junho de 2019 13:57
  • Edvaldo,

    A checagem é feita com base nas condições aplicadas no When Matched e When Not Matched, é justamente nestes trechos que você tem que analisar e ver a maneira que vai declarar e aplicar as referidas condições.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sexta-feira, 21 de junho de 2019 14:02
  • Tentei da maneira abaixo, mas sem sucesso:

    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.designacao AS designacao_B
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and  b.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date)))
    ) AS U
        ON U.designacao = T.designacao AND U.designacao_B IS NOT NULL
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2, qtde_log = U.qtde_log, reaberto = 'sim'
    WHEN NOT MATCHED THEN
    	case when DATEDIFF(DAY, b.prazo, GETDATE()) > 45) then
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
        U.designacao, 
        U.Cliente,
    	U.desc_uds,
    	U.qtde_log,
    	GETDATE(),
    	GETDATE(),
    	'w7spo082851\GEO',
    	U.rec_ano,
    	'aberto',
    	GETDATE() + 2
        )
    	end	;

    sexta-feira, 21 de junho de 2019 14:25
  • Edvaldo, essa condição dos 45 dias vai ser combinada com outra(s) condição(ões)?

    Desconfio que se ela for adicionada isoladamente sempre será inserida uma nova linha pois essa condição dos 45 dias vai continuar ocorrendo.


    Assinatura: http://www.imoveisemexposicao.com.br

    sexta-feira, 21 de junho de 2019 15:00
  • Tem sim :

    No momento da inserção, o valor da coluna designacao exista na tabela teste_tb_planos_acoes, verifique se status_fim = encerrado e data_fim > 45 dias, faça a inserção


    • Editado Edvaldo A sexta-feira, 21 de junho de 2019 16:34 correção no texto
    sexta-feira, 21 de junho de 2019 16:27
  • Experimente fazer uns testes dessa forma:

    MERGE teste_tb_planos_acoes AS T
    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            B.data_fim
        FROM tb_calcula_hist_log A
        LEFT JOIN teste_tb_planos_acoes B ON A.designacao = B.designacao
        WHERE
            (B.designacao IS NULL) OR
            (B.status_fim = 'encerrado' and
             ( B.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date)) or
               B.data_fim < dateadd(day, -45, cast( current_timestamp as date)) ))
    ) AS U
        ON 
            U.designacao = T.designacao AND 
            U.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date))
    WHEN MATCHED THEN
        UPDATE SET status_fim = 'aberto', prazo = GETDATE() + 2, qtde_log = U.qtde_log, reaberto = 'sim'
    WHEN NOT MATCHED THEN
        INSERT
        (
            designacao,
            cliente,
            area,
            qtde_log,
            data_cad,
            data_email_env,
            login_cadastro,
            rec_num,
            status_fim,
            prazo
        )
        VALUES
        (
            U.designacao, 
            U.Cliente,
            U.desc_uds,
            U.qtde_log,
            GETDATE(),
            GETDATE(),
            'w7spo082851\GEO',
            U.rec_ano,
            'aberto',
            GETDATE() + 2
        )

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br


    • Editado gapimex sexta-feira, 21 de junho de 2019 17:03
    sexta-feira, 21 de junho de 2019 17:03
  • gapimex,

    Funcionou em parte, simulei uma situação para testar a condição dos 45 dias e ele realmente fez a inserção de acordo como os critérios, porém ao executar pela 2x o comando ele permitiu inserir, ficando 3 registro com o mesmo valor, deveria não ter inserido o 3 registro, quando há 2 registros (um com status_fim = encerrado e outro = aberto), não permitir inserir novamente.


    • Editado Edvaldo A sexta-feira, 21 de junho de 2019 18:14 correção texto.
    sexta-feira, 21 de junho de 2019 18:13
  • Edvaldo,

    Então, neste caso, talvez esta condições de análises e condições que você deseja, o uso do Merge poderá não atender totalmente, uma possibilidade mantendo o Merge, seria utilizar um comando If antes da execução do próprio Merge verificando e validando esta ocorrência dos 45 dias.

    Mas se você declarar cada condição como sendo um When Matched, não seria uma possibilidade?

    Neste caso a operação desejada só deverá ocorrer caso a condição seja satisfatória.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    sexta-feira, 21 de junho de 2019 18:18
  • Edvaldo, experimente deixar o Where de dentro do Using dessa forma:

        WHERE
            (B.designacao IS NULL) OR
            ((B.status_fim = 'encerrado') and
             ( B.data_fim between dateadd(day, -30, cast( current_timestamp as date)) and dateadd(day, -10, cast( current_timestamp as date)) or
               B.data_fim < dateadd(day, -45, cast( current_timestamp as date)) ) and
             (not exists
                 (select 1 from teste_tb_planos_acoes E
                  where
                      E.designacao = B.designacao and
                      E.status_fim = 'aberto')) )
    

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    sexta-feira, 21 de junho de 2019 18:39
  • Matou a pau !!! 

    Vcs devem estar querendo me matar rsrs

    Percebi uma outra situação que poderá ocorrer, posso ter dois registros encerrados com a data_fim diferentes, posso pedir para checar a data mais atual (coluna data_fim), na linha update ? 

    Mais ou menos assim, coloquei um TOP e pedi para ordenar, mas deu erro 

    UPDATE TOP(1) SET status_fim = 'aberto', prazo = GETDATE() + 2, qtde_log = U.qtde_log, reaberto = 'sim' order by B.data_fim desc

    sexta-feira, 21 de junho de 2019 19:04
  • Para a condição dos 45 dias também deve ser utilizada somente a data_fim mais atual?

    Assinatura: http://www.imoveisemexposicao.com.br

    sexta-feira, 21 de junho de 2019 19:19
  • Sim.
    sexta-feira, 21 de junho de 2019 19:21
  • Experimente dessa forma:

    USING
    (
        SELECT distinct
            A.designacao, 
            A.Cliente,
            desc_uds,
            A.qtde_log,
            A.rec_ano,
            O.data_fim,
            O.dif_dias
        FROM tb_calcula_hist_log A
        OUTER APPLY
        (
            SELECT TOP(1)
                B.data_fim,
                B.status_fim,
                DATEDIFF(DAY, B.data_fim, GETDATE()) as dif_dias
            FROM teste_tb_planos_acoes B 
            WHERE 
                B.designacao = A.designacao
            ORDER BY
                B.data_fim DESC
        ) O    
        WHERE
            (O.status_fim IS NULL) OR
            ((O.status_fim = 'encerrado') and
             (O.dif_dias between 10 and 30 or O.dif_dias > 45) and
             (not exists
                 (select 1 from teste_tb_planos_acoes E
                  where
                      E.designacao = A.designacao and
                      E.status_fim = 'aberto')))
    ) AS U
        ON 
            U.designacao = T.designacao AND
            U.data_fim = T.data_fim AND
            U.dif_dias between 10 and 30

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br


    • Editado gapimex sexta-feira, 21 de junho de 2019 20:00
    • Marcado como Resposta Edvaldo A sexta-feira, 21 de junho de 2019 20:14
    sexta-feira, 21 de junho de 2019 19:59
  • MUITOOO Obrigado !!! Seu código ficou perfeito !!!
    sexta-feira, 21 de junho de 2019 20:14