none
Integracao entre tabelas Trigger com Loop ou SPs. RRS feed

  • Pergunta

  • Olá amigos,

    Estou com um problema: Para conseguir integrar a tabela de dois bancos de dados diferentes estamos utilizando Trigger. Porem estamos com uma situação inusitada: Uma das tabelas que devemos integrar gera somente um registro informando o número de parcelas no qual um registro deverá ser desmembrado. Isso significa algo do tipo:

    Tabela origem:

    Título Financeiro:

    Número  Parcelas Valor

    10                   3               30,00  

    Tabela destino:

    Título Financeiro:

    Número  Parcelas Valor

    10                   1              10,00  

    10                   2              10,00  

    10                   3              10,00  

    Para replicar um para um já conseguimos fazer com a Trigger, agora precisamos fazer um virar 'N'.

    Como fazer isso com Trigger ou Stored Procedure?  O que é melhor?


    sexta-feira, 22 de agosto de 2014 13:15

Respostas

  • Deleted
    sexta-feira, 22 de agosto de 2014 14:16
  • Amigo,

    Concordo com o José, a inclusão da condição de pagamento deve estar um uma única transação (junto com o processo para dividir às parcelas) afim você vai evitar erros e inconsistências de dados.

    Também acredito que você precisa verificar se a trigger realmente é a melhor solução neste caso, afinal um pedido pode ser alterado e caso seu processo não esteja bem definido poderá modificar às condições ou valores de pagamento. Sugiro que você faça alguns testes utilizando parte do processo através da trigger e outro teste em uma stored procedure (a mesma da inclusão do pedido ou outra complementando), analise a performance em condições de stress e a integridade dos dados.

    Segue abaixo outra sugestão para criar a divisão das parcelas:

    --CRIANDO AMBIENTE PARA TESTE

    CREATE TABLE TB_PARCELA ( NUMERO INT, PARCELAS INT, VALOR FLOAT ) GO CREATE TABLE TB_PARCELA_DESTINO ( NUMERO INT, PARCELA INT, VALOR FLOAT ) GO INSERT INTO TB_PARCELA VALUES (1,3,30.00) GO

    -------------
    --EXECUTANDO EXEMPLO PARA SEU AJUSTE DECLARE @NPARCELA INT DECLARE @COUNT INT = 1 DECLARE @NUMERO INT = 1 SELECT @NPARCELA = PARCELAS FROM TB_PARCELA WHERE NUMERO = 1 WHILE (@COUNT <= @NPARCELA) BEGIN INSERT INTO TB_PARCELA_DESTINO (NUMERO,PARCELA,VALOR) SELECT NUMERO, @COUNT, (VALOR / PARCELAS) FROM TB_PARCELA WHERE NUMERO = @NUMERO SET @COUNT = @COUNT + 1 END SELECT * FROM TB_PARCELA_DESTINO WHERE NUMERO = @NUMERO GO


    Se ajudou na sua solução, não esqueça de marcar como resposta !

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"
    sexta-feira, 22 de agosto de 2014 14:52
    Moderador
  • Para transformar uma linha de uma tabela em n linhas em outra tabela, sempre que for incluída uma linha na tabela de origem, isso pode ser feito na rotina trigger, mas tendo em mente que tudo deve ser uma única transação.

    Por exemplo, o seguinte trecho, quando em uma rotina trigger

    -- código 1
    INSERT into TabDestino (Número, Parcelas, Valor)
      SELECT I.Número, N.Num, (I.Valor / I.Parcelas)
        from inserted as I
             cross join TabNum as N
        where N.Num <= I.Parcelas;

    cria n linhas na tabela de destino. O código acima utiliza tabela auxiliar contendo somente números, que é uma técnica simples e eficaz utilizada para casos semelhantes.

    Atento que a divisão direta do valor da parcela pelo número de parcelas nem sempre gera valor submúltiplo. Por exemplo, ao dividir R$ 10,00 por 3 parcelas, teremos R$ 3,3333... Ou seja, é necessário algo mais na codificação, para garantir que a somatória das parcelas seja idêntica ao valor original. Qual é a regra de negócio a ser aplicada, nesses casos?

    Tudo isso é simples de resolver, basta montar o algoritmo e então implementá-lo como rotina trigger.
     


        José Diz     Belo Horizonte, MG - Brasil
    (Se encontrou a solução nesta resposta, ou se o conteúdo foi útil, lembre-se de marcá-la)



    Amigos,

    Só um detalhe quando utilizamos a claúsula Where no Operador Cross Join o mesmo vai ter um comportamento de Junção(Join) similar ou praticamente idêntico ao operador Inner Join.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | SoroCódigos] @JuniorGalvaoMVP | pedrogalvaojunior.wordpress.com

    sexta-feira, 22 de agosto de 2014 15:41

Todas as Respostas

  • Deleted
    sexta-feira, 22 de agosto de 2014 14:01
  • Deleted
    sexta-feira, 22 de agosto de 2014 14:16
  • Amigo,

    Concordo com o José, a inclusão da condição de pagamento deve estar um uma única transação (junto com o processo para dividir às parcelas) afim você vai evitar erros e inconsistências de dados.

    Também acredito que você precisa verificar se a trigger realmente é a melhor solução neste caso, afinal um pedido pode ser alterado e caso seu processo não esteja bem definido poderá modificar às condições ou valores de pagamento. Sugiro que você faça alguns testes utilizando parte do processo através da trigger e outro teste em uma stored procedure (a mesma da inclusão do pedido ou outra complementando), analise a performance em condições de stress e a integridade dos dados.

    Segue abaixo outra sugestão para criar a divisão das parcelas:

    --CRIANDO AMBIENTE PARA TESTE

    CREATE TABLE TB_PARCELA ( NUMERO INT, PARCELAS INT, VALOR FLOAT ) GO CREATE TABLE TB_PARCELA_DESTINO ( NUMERO INT, PARCELA INT, VALOR FLOAT ) GO INSERT INTO TB_PARCELA VALUES (1,3,30.00) GO

    -------------
    --EXECUTANDO EXEMPLO PARA SEU AJUSTE DECLARE @NPARCELA INT DECLARE @COUNT INT = 1 DECLARE @NUMERO INT = 1 SELECT @NPARCELA = PARCELAS FROM TB_PARCELA WHERE NUMERO = 1 WHILE (@COUNT <= @NPARCELA) BEGIN INSERT INTO TB_PARCELA_DESTINO (NUMERO,PARCELA,VALOR) SELECT NUMERO, @COUNT, (VALOR / PARCELAS) FROM TB_PARCELA WHERE NUMERO = @NUMERO SET @COUNT = @COUNT + 1 END SELECT * FROM TB_PARCELA_DESTINO WHERE NUMERO = @NUMERO GO


    Se ajudou na sua solução, não esqueça de marcar como resposta !

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA | MCSA - SQL Server 2012 | MCSE - Data Platform
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"
    sexta-feira, 22 de agosto de 2014 14:52
    Moderador
  • Para transformar uma linha de uma tabela em n linhas em outra tabela, sempre que for incluída uma linha na tabela de origem, isso pode ser feito na rotina trigger, mas tendo em mente que tudo deve ser uma única transação.

    Por exemplo, o seguinte trecho, quando em uma rotina trigger

    -- código 1
    INSERT into TabDestino (Número, Parcelas, Valor)
      SELECT I.Número, N.Num, (I.Valor / I.Parcelas)
        from inserted as I
             cross join TabNum as N
        where N.Num <= I.Parcelas;

    cria n linhas na tabela de destino. O código acima utiliza tabela auxiliar contendo somente números, que é uma técnica simples e eficaz utilizada para casos semelhantes.

    Atento que a divisão direta do valor da parcela pelo número de parcelas nem sempre gera valor submúltiplo. Por exemplo, ao dividir R$ 10,00 por 3 parcelas, teremos R$ 3,3333... Ou seja, é necessário algo mais na codificação, para garantir que a somatória das parcelas seja idêntica ao valor original. Qual é a regra de negócio a ser aplicada, nesses casos?

    Tudo isso é simples de resolver, basta montar o algoritmo e então implementá-lo como rotina trigger.
     


        José Diz     Belo Horizonte, MG - Brasil
    (Se encontrou a solução nesta resposta, ou se o conteúdo foi útil, lembre-se de marcá-la)



    Amigos,

    Só um detalhe quando utilizamos a claúsula Where no Operador Cross Join o mesmo vai ter um comportamento de Junção(Join) similar ou praticamente idêntico ao operador Inner Join.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | SoroCódigos] @JuniorGalvaoMVP | pedrogalvaojunior.wordpress.com

    sexta-feira, 22 de agosto de 2014 15:41