Problema Gerado na Inclusão de Registros no BcLegal
Para incluir um registro no BcLegal utilizamos procedures, que sempre retorna um id gerado na tabela. Essas procedures estão utilizando uma função chamada = IDENT_CURRENT. Com a utilização dessa função foi encontrado um problema no cliente Rodobens conforme especificado abaixo.
“Carlos, bom dia!
Preciso que você registre um chamado na procwork com caracter de urgência para o problema abaixo:
Fiz teste em algumas pastas, e verifiquei que tem andamento feito em uma pasta e salvo em outra.
Exemplo:. O usuário LCIACARELI fez um agendamento na pasta 47874. O agendamento salvou normalmente na pasta porém salvou o mesmo andamento na pasta 45209 (abaixo conforme print) que não tem vinculo nenhum. Na mesma pasta abaixo, ocorreu o problema com o andamento de SZPAULA.”

Realizados testes no ambiente de homologação do cliente, foi verificado que quando dois usuários utilizavam a mesma funcionalidade de “Andamentos” para incluir um registro, apresentava esse problema. O motivo desse problema era a utilização da função IDENT_CURRENT do SQL que sempre retorna o último id da tabela. No caso de estar incluindo dois registros ao mesmo tempo, essa função retorna o mesmo id para as duas transações, eram incluídos dois registros, mas para a aplicação ele retornava o último incluído, fazendo o relacionamento de registros de atividades com caso de forma errada.
Segue abaixo o script que era utilizado na procedure salvarAtividade:
ALTER PROCEDURE [dbo].[salvarAtividade]
(
@cd_atividade int = null output,
@cd_tipo_atividade int,
@cd_workflow int = null,
@dt_atividade datetime,
@ds_comentario varchar(5000)= null,
@dt_conclusao datetime = null,
@cd_atividade_origem int = null,
@cd_atividade_dependencia int = null,
@ic_fluxo_gerado bit = 1,
@cd_etapa int = null,
@dt_ultima_notificacao datetime = null,
@cd_estado_atual varchar(5),
@cd_empresa int,
@in_audiencia bit = null,
@dt_agendada datetime = null,
@cd_funcionario int = null,
@ds_atividade varchar(1000) = null,
@cd_fase int = null,
@ic_alerta_atividade bit = null,
@vl_fatura float = null,
@prazo_fatura int = null,
@alerta_dias int = null,
@cd_link int = null,
@cd_tipo_agenda int = null,
@id_workstation varchar(60) = null,
@alterado_por int = null,
@dt_atualizacao datetime,
@email varchar(255) = null
)
as
if(@cd_atividade is null)
begin
insert into bil_atividade (cd_tipo_atividade
, cd_workflow
, dt_atividade
, ds_comentario
, dt_conclusao
, cd_atividade_origem
, cd_atividade_dependencia
, ic_fluxo_gerado
, cd_etapa
, dt_ultima_notificacao
, cd_estado_atual
, alterado_por
, dt_atualizacao
, cd_empresa
, in_audiencia
, dt_agendada
, cd_funcionario
, ds_atividade
, cd_fase
, ic_alerta_atividade
, alerta_dias
, cd_link
, id_workstation
, prazo_fatura
, vl_fatura
, cd_tipo_agenda
, email)
values
(@cd_tipo_atividade
, @cd_workflow
, @dt_atividade
, @ds_comentario
, @dt_conclusao
, @cd_atividade_origem
, @cd_atividade_dependencia
, @ic_fluxo_gerado
, @cd_etapa
, @dt_ultima_notificacao
, @cd_estado_atual
, @alterado_por
, @dt_atualizacao
, @cd_empresa
, @in_audiencia
, @dt_agendada
, @cd_funcionario
, @ds_atividade
, @cd_fase
, @ic_alerta_atividade
, @alerta_dias
, @cd_link
, @id_workstation
, @prazo_fatura
, @vl_fatura
, @cd_tipo_agenda
, @email)
set @cd_atividade = IDENT_CURRENT('bil_atividade')
end
else
begin
declare @dt_atividade_ant datetime
select @dt_atividade_ant = dt_atividade from bil_atividade where cd_atividade = @cd_atividade
update
bil_atividade
set
cd_tipo_atividade = @cd_tipo_atividade
, cd_workflow = @cd_workflow
, dt_atividade = @dt_atividade
, ds_comentario = @ds_comentario
, dt_conclusao = @dt_conclusao
, cd_atividade_origem = @cd_atividade_origem
, cd_atividade_dependencia = @cd_atividade_dependencia
, ic_fluxo_gerado = @ic_fluxo_gerado
, cd_etapa = @cd_etapa
, dt_ultima_notificacao = @dt_ultima_notificacao
, cd_estado_atual = @cd_estado_atual
, alterado_por = @alterado_por
, dt_atualizacao = @dt_atualizacao
, cd_empresa = @cd_empresa
, in_audiencia = @in_audiencia
, dt_agendada = @dt_agendada
, cd_funcionario = @cd_funcionario
, ds_atividade = @ds_atividade
, cd_fase = @cd_fase
, ic_alerta_atividade = @ic_alerta_atividade
, alerta_dias = @alerta_dias
, vl_fatura = @vl_fatura
, prazo_fatura = @prazo_fatura
, cd_link = @cd_link
, cd_tipo_agenda = @cd_tipo_agenda
, email = @email
where
cd_atividade = @cd_atividade
if(@dt_conclusao is not null and @dt_conclusao > @dt_atividade)
begin
declare @atividade_dependente int
declare atividade_cursor cursor for (select cd_atividade from bil_atividade a where (cd_atividade_dependencia = @cd_atividade) and dt_conclusao is null)
open atividade_cursor
fetch next from atividade_cursor into @atividade_dependente
while @@fetch_status = 0
begin
exec atualizar_data_atividade @atividade_dependente, @dt_conclusao
fetch next from atividade_cursor into @atividade_dependente
end
close atividade_cursor
deallocate atividade_cursor
end
end
return
Para fazer a correção desse problema, passou-se a utilizar a função Scope_identity(), com a execução dela, passa a pegar o identity gerado na transação atual gerado, não o da tabela.
--set @cd_atividade = IDENT_CURRENT('bil_atividade')
set @cd_atividade = Scope_identity()
Essa correção deverá ser feita nas procedures de inclusão de todos os módulos do sistema BcLegal. A alteração foi realizada no projeto da Rodobens, sendo necessário essa verificação e possível alteração no projeto do produto BcLegal.
- No SQL Server possui funções semelhantes porque retornam valores que são inseridos em colunas de uma tabela.
- Ident_Current: função que retorna o valor gerado para uma tabela específica em qualquer sessão e escopo. Sempre retorna o último id que foi gerado independente da transação.
- Scope_Identity e @@Identity: retornam o úlitmo valor de id gerado em qualquer tabela da sessão atual em execução. O Scope_Identity só retorna o id no escopo atual e o @@Identity não é limitado por escopo específico.