Usuário com melhor resposta
Bloco com um controle de transação dando erro - SQL Server

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
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.
- Editado André Renato Furtado terça-feira, 19 de maio de 2015 04:14
- Marcado como Resposta Matheus L. M. C. Campos sexta-feira, 22 de maio de 2015 19:44