none
Bloco com um controle de transação dando erro - SQL Server RRS feed

  • Pergunta

  • Olá pessoal. 

    Venho mais uma vez, recorrer à ajuda de vocês para uma mensagem de erro ocorrida em uma transação.

    Não sei se estou implementando errado, mas a situação é a seguinte:

    Tenho 2 procedures 1- uspClientePessoaFisicaInserir e 2-uspGerarIDControle e ambas possuem controle de transação com retorno dos erros (não sei se estão implementados corretamente). A ideia é: quando eu insiro um novo cliente, basta que eu passe o nome da tabela e o nome do campo desejados que a procedure 2 consulta no banco se há aquela tabela e se não existir, ele deverá abortar tudo e apenas retornar a mensagem 'A tabela informada não existe no banco de dados!'.... Só que o erro que está me aparecendo é aquele mostrado no print logo abaixo. Será que a minha forma de administrar as msgs de erro + Transações estão errados ou precisam de melhorias?? alguém poderia me dar um help?

    ----------------------------------------->Procedure 1

       

    /*---------------------------------------------------------------------------------------------------------
    Stored Procedure para inserção de ClientePessoaFisicaInserir.

    Arquivo: uspClientePessoaFisicaInserir
    Criado por: Jalber Romano
    Data da Criação: 14/05/2015
    */---------------------------------------------------------------------------------------------------------



    CREATE PROCEDURE uspClientePessoaFisicaInserir

    @NomeTabela VARCHAR(30),
    @NomeCampo VARCHAR (30),

    @NomeCompleto VARCHAR(100),
    @Apelido VARCHAR(20),
    @IDPessoaSituacao VARCHAR(1),
    @IDCidadeRegiao INT,
    @TelefoneFixo VARCHAR(11),
    @TelefoneCelular VARCHAR(11),
    @Email VARCHAR(50),
    @Site VARCHAR(150)
    AS
    BEGIN

    BEGIN TRY
    BEGIN TRAN

    --Consultar IDPessoa no banco e Gerar AutoIncremento
    DECLARE @IDPessoa AS INT;
    EXEC uspGerarIDControle @NomeTabela, @NomeCampo, @IDPessoa OUTPUT

    --Gravar registro na tabela tblPessoa
    INSERT INTO tblPessoa
    (
    IDPessoa,
    IDPessoaTipo,
    IDPessoaSituacao,
    IDCidadeRegiao,
    TelefoneFixo,
    TelefoneCelular,
    Email,
    Site,
    DataInclusao

    VALUES
    (
    @IDPessoa,
    1,
    @IDPessoaSituacao,
    @IDCidadeRegiao,
    @TelefoneFixo,
    @TelefoneCelular,
    @Email,
    @Site,
    GETDATE()
    );


    -- Gravar registro na tabela tblPessoaFisica
    INSERT INTO tblPessoaFisica
    (
    IDPessoaFisica,
    NomeCompleto,
    Apelido

    ) VALUES
    (
    @IDPessoa,
    @NomeCompleto,
    @Apelido
    );

    -- Gravar registro na tabela tblCliente
    INSERT INTO tblCliente
    (
    IDCliente

    ) VALUES
    (
    @IDPessoa
    );

    SELECT @IDPessoa AS Retorno;

    COMMIT TRAN
    END TRY
    BEGIN CATCH
    ROLLBACK TRAN
    SELECT ERROR_MESSAGE() AS Retorno;
    END CATCH

    END

    ----------------------------------------->Procedure 2

    /*---------------------------------------------------------------------------------------------------------
    Stored Procedure para gerar um ID de controle automaticamente quando inserir um registro em uma tabela

    Arquivo: uspGerarIDControle
    Criado por: Jalber Romano
    Data da Criação: 28/04/2015
    */---------------------------------------------------------------------------------------------------------


    CREATE PROCEDURE uspGerarIDControle
    @NomeTabela VARCHAR(30),
    @NomeCampo VARCHAR(30),
    @NumeroControle INT OUTPUT
    AS

    BEGIN

    BEGIN TRY
    BEGIN TRAN
    -- Verifica se existe sequência para tabela/coluna; cria, se não houver
    --1: Verifica se a tabela existe no banco de dados
    IF EXISTS (
    SELECT 
    TOP 1
    T.name AS Tabela, 
    C.name AS Coluna

    FROM 
    sys.sysobjects    AS T (NOLOCK) 
    INNER JOIN sys.all_columns AS C (NOLOCK) ON T.id = C.object_id AND T.XTYPE = 'U' 
    WHERE 
    C.name = @NomeCampo AND
    T.name = @NomeTabela)
    --ORDER BY 
    -- T.name ASC)
    BEGIN
    --2: Verifica se a tabela está cadastrada na tabela tblSequencia. Se não estiver, ela será adicionada.
    IF NOT EXISTS (SELECT * FROM dbo.tblTabelaSequencia WHERE NomeTabela = @NomeTabela AND NomeCampo = @NomeCampo)
    INSERT INTO dbo.tblTabelaSequencia (NomeTabela, NomeCampo, UltSeq) VALUES (@NomeTabela, @NomeCampo, 0);

    --Cria um ID Sequencial com base na tabela tblTabelaSequencia
    UPDATE 
    tblTabelaSequencia
    SET @NumeroControle = UltSeq = UltSeq + 1 
    WHERE NomeTabela = @NomeTabela AND NomeCampo = @NomeCampo;
    END
    ELSE
    BEGIN
    RAISERROR('A tabela informada não existe no banco de dados!', 14, 1);
    END
    COMMIT TRAN
    END TRY
    BEGIN CATCH
    ROLLBACK TRAN
    SELECT ERROR_MESSAGE() AS Retorno;
    END CATCH

    END

    ----------------------------------- Erro

    quinta-feira, 14 de maio de 2015 21:48

Respostas

  • Boa noite.

    Sugiro que reveja a lógica das procedures, o ROLLBACK da procedure uspClientePessoaFisicaInserir está afetando a transação da outra procedure(que está como inner transaction neste caso).

    Tente utilizar apenas um BEGIN TRAN e savepoints...

    https://technet.microsoft.com/en-us/library/ms178157(v=sql.105).aspx

    O link a seguir explica sobre nested transactions.

    https://technet.microsoft.com/en-us/library/ms189336%28v=sql.105%29.aspx

    Para testes...

    BEGIN TRAN TR1
    INSERT INTO TESTE VALUES (1, 'TESTE')

    BEGIN TRAN TR2
    INSERT INTO TESTE VALUES (1, 'TESTE')

    BEGIN TRAN TR3
    INSERT INTO TESTE VALUES (1, 'TESTE')

    select @@trancount -- Informa 3 transações abertas

    ROLLBACK TRAN TR1 --Efetua rollback das transações TR1, TR2 e TR3.

    Se eu substituir por ROLLBACK TRAN T2 ou T3 informa que não existem!

    Att.


    terça-feira, 19 de maio de 2015 04:10