Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Pessoal,
Fiz essa pergunta no Forum de SQL mas lá parece cidade fantasma, num tem ninguém.
Eu tenho um codigo que faz um insert numa tabela que tem os campos ID e CODIGO.
ID é autonumérico e unico, mas CODIGO é um campo inteiro e não é Autonumérico.
eu to fazendo um select na tabela e pegando o ultimo registro inserido no banco, pego o ultimo CODIGO e adiciono 1 nele pra fazer o INSERT
set RS_ALUNO = server.CreateObject("ADODB.Recordset")ALUsql = "SELECT CODIGO FROM ALUNOS ORDER BY CODIGO DESC"RS_ALUNO.Open ALUsql, Conexao, 3, 3
conexao.execute("Insert into alunos (CODIGO) values ('" & RS_ALUNO("CODIGO") + 1 & "')
Minha dúvida é se no meio-tempo em que eu to fazendo o select e em seguida fazendo o insert houver outra requisição ao banco e trocar a numeração que foi guardada neste SELECT. Como posso tratar isso?Saquei jonathandj!!!Mas você nao acha que daria no mesmo? Caso uma conexão mais lenta estivesse realizando um select e achasse o NUMERO 201 e outra rápida tb achasse o mesmo NUMERO 201, ambas realizariam o cadastro com o numero 202, entende o perigo ou eu que to sendo paranóico?
> você pode criar uma tabela auxiliar pra criar o autonumerador, a cada insert você consulta essa tabela, pega o valor dela e guarda numa variavel, pega o valor dessa variavel e adiciona 1 e faz um update nessa tabela auxiliar tipo assim...na tabela auxiliar você tem o campo NUMERO = 201o camarada faz o submit e antes do insert você consulta a tabela auxiliar, vai retornar o valor 201, ai você usa uma variavel e adiciona +1 e ficará 202. Ainda antes do insert você faz um Update na tabela auxiliar enviando o valor 202 para o proximo registro, assim você deixa guardado na variavel o numero 201 e na tabela o 202 para outro insertna verdade essa dica que eu passei ela retorna os dados muito mais rápido do que a atual usada por você, além de mais segura. Bom, paranóico você não está sendo pois a possibilidade existe apesar de ser mínima, por exemplo...um sistema onde duas pessoas estão cadastrando seria raro acontecer de os dados chegarem no mesmo instante, mas se você tiver 100 usuarios cadastrando não seria tão raro assim.De momento só vejo essa solução, se brilhar outra ideia coloco aqui
Ué? Porque não coloca logo o campo indentity na tabela e deixa o SQL controlar isso pra você?
Caso não seja possível porque não coloca isso em uma stored procedure, dai o tempo que o SQL Server vai demorar pra pegar o número do registro e inserir vai ser mínimo, reduzindo assim as chances de inserir o registro duplicado.
Outra dica é, pegando o número do registro dessa forma:
SELECT CODIGO FROM ALUNOS ORDER BY CODIGO DESC
Você esta trazendo muitos registros sem necessidade, se a sua tabela de alunos tiver 1.000.000 de registros você vai trazer 999.999 sem necessidade, quando o que você precisa é de
SELECT (ISNULL(MAX(CODIGO),0) + 1) FROM ALUNOS
Sua consulta vai ficar bem mais rápida e vai consumir menos o servidor na hora de criar o recordset.
Ué? Porque não coloca logo o campo indentity na tabela e deixa o SQL controlar isso pra você?
Já tem um campo com IDENTITY
Caso não seja possível porque não coloca isso em uma stored procedure, dai o tempo que o SQL Server vai demorar pra pegar o número do registro e inserir vai ser mínimo, reduzindo assim as chances de inserir o registro duplicado.
Como que eu faço isso?Nao sei trabalhar com StoredProcedures nem sie por onde começar. Sei por deduçao que o banco cuidar disso seria o mais lógico e mais correto mais nao sei como fazer, pode me ajudar com isso?
>
Outra dica é, pegando o número do registro dessa forma:
SELECT CODIGO FROM ALUNOS ORDER BY CODIGO DESCVocê esta trazendo muitos registros sem necessidade, se a sua tabela de alunos tiver 1.000.000 de registros você vai trazer 999.999 sem necessidade, quando o que você precisa é de SELECT (ISNULL(MAX(CODIGO),0) + 1) FROM ALUNOSSua consulta vai ficar bem mais rápida e vai consumir menos o servidor na hora de criar o recordset.
Nesse caso eu continuo com a mesma sintaxe no insert, correto?
Como que eu faço isso?Nao sei trabalhar com StoredProcedures nem sie por onde começar. Sei por deduçao que o banco cuidar disso seria o mais lógico e mais correto mais nao sei como fazer, pode me ajudar com isso?
Segue mais ou menoscreate procedure inserir_alunos(@Nome varchar(50))as Set NOCOUNT ON Declare @Codigo Int select @Codigo = isnull(max(codigo),0) + 1 from alunos insert into alunos ( Codigo, Nome ) values ( @Codigo, @Nome ) Set NOCOUNT OFF
Nesse caso eu continuo com a mesma sintaxe no insert, correto?
Mais ou menos, já que no select você já incrementa mais um.
você pode criar uma tabela auxiliar pra criar o autonumerador, a cada insert você consulta essa tabela, pega o valor dela e guarda numa variavel, pega o valor dessa variavel e adiciona 1 e faz um update nessa tabela auxiliar tipo assim...na tabela auxiliar você tem o campo NUMERO = 201o camarada faz o submit e antes do insert você consulta a tabela auxiliar, vai retornar o valor 201, ai você usa uma variavel e adiciona +1 e ficará 202. Ainda antes do insert você faz um Update na tabela auxiliar enviando o valor 202 para o proximo registro, assim você deixa guardado na variavel o numero 201 e na tabela o 202 para outro insert