Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Marcelo_Ribeiro

Transaction (Delphi 7+SQL Server 2005 + DbExpress)

Recommended Posts

E aí, queria fazer o seguinte:

quando eu vou fazer uma insercao numa tabela, bloquear essa tabela pros outros nao inserirem, e só inserirem dps q eu terminar de inserir o registro.

 

tenho uma transaction bem idiota +ou- assim:

 

begin transaction

 

INSERT INTO tb_teste values(@descricao)

 

commit transaction

 

 

pra executar essa transacao, preciso coloca-la numa SP?

Como executar essa transacao (ou SP) (passando parametros) no delphi7 usando dbexpress?

tem um jeito de executa-la sem cria-la no banco, usando só o delphi (por ex, ClientDataSet.CommandText ou algo do tipo)?

 

espero ter sido claro...

 

Grato

Compartilhar este post


Link para o post
Compartilhar em outros sites

Travar a tabela toda numa aplicação que roda em rede não é uma boa prática, visto que isso impede que outras rotinas que usem esta tabela possam executar quaisquer consulta sql nos registros enquanto a mesma estiver bloqueada... você pode dar um ROWLOCK para bloquear a linha que está sendo gravada/atualizada/deletada sem ter que travar toda a tabela. Agora, se for realmente necessário travar a tabela toda, você pode usar o comando TABLELOCK (se lembro direito agora).

 

Exemplo do ROWLOCK:

 

INSERT INTO TABELA WITH(ROWLOCK) (campoA, campoB,..,campoN) VALUES ('A',0,..,'N')

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

ah, entendi.

 

pq tenho uma tbl q tem um campo rec. ele eh a pk, mas nao eh auto-increment, e tb nao dá pra alterar essa propriedade

 

o q eu precisaria saber, antes d incluir um novo registro, qual o maior numero desse rec, acrescentar 1 nele e incluir no proximo registro.

 

para isso, eu precisaria bloquear td a tabela neh?

 

ta +ou- assim a SP

 

set ANSI_NULLS ON

set QUOTED_IDENTIFIER ON

GO

ALTER PROCEDURE [dbo].[insereDados]

 

@descricao varchar(50),

@identity int output

 

AS

 

begin transaction

INSERT INTO tb_teste values(@descricao)

select * from tb_teste

commit transaction

 

 

tem como eu fazer um select (select max(rec) as rec from tb_teste) antes do insert, pra retornar o rec e incrementar 1 no rec pra inserir o novo registro?

 

e no delphi, como eu pegaria esse numero q eu retornei?

 

eh isso. grato

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você pode criar uma stored procedure no SQL Server e pegar dentro dela o max(rec) antes de dar um insert, jogando o valor numa variável dentro da própria SP e na sequência gravando os dados. Seria mais simples e facilitaria sua vida para o caso de realizar alterações futuras apenas no procedimento de gravação.

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

Estou sem o SQL Server aqui para testar, mas seria +/- isso:

 

CREATE PROCEDURE STP_INSERE_DADOS @CAMPO_A VARCHAR(100), CAMPO_B INT, CAMPO_C DATETIME
AS 
BEGIN
SET NOCOUNT ON
DECLARE @CONTADOR INT

SELECT @CONTADOR = MAX(REC) FROM TB_TESTE WITH(NOLOCK)

INSERT INTO TB_TESTE WITH(ROWLOCK) (CAMPOA, CAMPOB, CAMPOC, CONTADOR)
VALUES (CAMPO_A, CAMPO_B, CAMPO_C, @CONTADOR)

END

Ai no delphi seria só por a linha 'EXEC STP_INSERE_DADOS ' com os valores que vai gravar sendo passados conforme o tipo de dado especificado (montando o sql como se fosse um texto) e dar um EXECSQL ao invés do OPEN na query para gravar.

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

funcionou... vlw msm

 

uma outra duvida:

 

se eu colocar um begin transaction e um commit transaction, isso tb vai bloquear a tabela pra leitura dos outros usuarios e só eu vou conseguir le-la?

 

abs

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você está misturando as coisas... transação é uma coisa, bloqueio de tabela são outra... em uma transação eu posso ter N operações distintas num banco de dados iniciadas depois do Begin Transaction que só serão efetivadas após o commit ou que, em caso de falha, podem ser desfeitas usando o rollback. Esse tipo de operação é usada para manter a consistência dos dados, mas ele não faz bloqueio de tabelas (até onde sei), e sim torna os dados incluídos/alterados indisponíveis até que seja dado o commit de toda a operação.

 

Dê uma pesquisada sobre isto.

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

ah, entendi...

 

desculpe minha leiguice.... rs

 

mas do jeito q você me falou, funfou perfeito... vlw msm

 

outra duvida (+ uma): como eu faço pra retornar esse numero do rec q foi inserido? e pelo delphi, tem alguma funcao pra isso?

 

desculpe tanto incomodo...

 

abs

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você pode tentar usando a propriedade OUTPUT do próprio SQL SERVER (dê uma olhada no help do BD que tem exemplos de como criar, estou sem o SQL Server aqui) ou pode fazer um select deste campo passando os dados que usou para cadastrar para recuperar por exemplo... agora, se estiver usando algum componente DB provavelmente um refresh deve resolver.

 

[]'s

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.