Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
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
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
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
e onde eu declararia a variavel e como eu jogaria o valor do rec nessa variavel?
desculpa mas sou meio leigo no uso de SP...
vlw
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
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
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
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
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
Marcelo se sua dúvida principal estiver na Procedure melhor mover seu tópico para a área de Sql Server.
Abraços...
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