Se você quisesse gerar uma string alfanumérica pseudo-aleatória usando T-SQL, como faria isso? Como você excluiria caracteres como cifrões, travessões e barras dele?
Ao gerar dados aleatórios, especialmente para teste, é muito útil tornar os dados aleatórios, mas reproduzíveis. O segredo é usar sementes explícitas para a função aleatória, de modo que, quando o teste for executado novamente com a mesma semente, ele produza novamente exatamente as mesmas strings. Aqui está um exemplo simplificado de uma função que gera nomes de objetos de maneira reproduzível:
alter procedure usp_generateIdentifier
@minLen int = 1
, @maxLen int = 256
, @seed int output
, @string varchar(8000) output
as
begin
set nocount on;
declare @length int;
declare @alpha varchar(8000)
, @digit varchar(8000)
, @specials varchar(8000)
, @first varchar(8000)
declare @step bigint = rand(@seed) * 2147483647;
select @alpha = 'qwertyuiopasdfghjklzxcvbnm'
, @digit = '1234567890'
, @specials = '_@# '
select @first = @alpha + '_@';
set @seed = (rand((@seed+@step)%2147483647)*2147483647);
select @length = @minLen + rand(@seed) * (@maxLen-@minLen)
, @seed = (rand((@seed+@step)%2147483647)*2147483647);
declare @dice int;
select @dice = rand(@seed) * len(@first),
@seed = (rand((@seed+@step)%2147483647)*2147483647);
select @string = substring(@first, @dice, 1);
while 0 < @length
begin
select @dice = rand(@seed) * 100
, @seed = (rand((@seed+@step)%2147483647)*2147483647);
if (@dice < 10) -- 10% special chars
begin
select @dice = rand(@seed) * len(@specials)+1
, @seed = (rand((@seed+@step)%2147483647)*2147483647);
select @string = @string + substring(@specials, @dice, 1);
end
else if (@dice < 10+10) -- 10% digits
begin
select @dice = rand(@seed) * len(@digit)+1
, @seed = (rand((@seed+@step)%2147483647)*2147483647);
select @string = @string + substring(@digit, @dice, 1);
end
else -- rest 80% alpha
begin
declare @preseed int = @seed;
select @dice = rand(@seed) * len(@alpha)+1
, @seed = (rand((@seed+@step)%2147483647)*2147483647);
select @string = @string + substring(@alpha, @dice, 1);
end
select @length = @length - 1;
end
end
go
Ao executar os testes, o chamador gera uma semente aleatória que associa à execução do teste (salva na tabela de resultados) e, em seguida, repassa a semente, semelhante a este:
declare @seed int;
declare @string varchar(256);
select @seed = 1234; -- saved start seed
exec usp_generateIdentifier
@seed = @seed output
, @string = @string output;
print @string;
exec usp_generateIdentifier
@seed = @seed output
, @string = @string output;
print @string;
exec usp_generateIdentifier
@seed = @seed output
, @string = @string output;
print @string;
Atualização 2016-02-17: Veja os comentários abaixo, o procedimento original teve um problema na forma como avançou a semente aleatória. Eu atualizei o código e também corrigi o problema mencionado por defeito.
@seed = rand(@seed+1)*2147483647
. Para o valor 529126, o próximo valor é 1230039262 e o próximo valor é 192804. a sequência continua de forma idêntica depois disso. A saída deve diferir pelo primeiro caractere, mas não é devido a um erro off-by-one:SUBSTRING(..., 0, ...)
retorna uma string vazia para o índice 0 e para 529126 isso 'oculta' o primeiro caractere gerado. A correção é calcular@dice = rand(@seed) * len(@specials)+1
para tornar os índices baseados em 1.+1
in norand(@seed+1)
ser aleatório e determinado apenas a partir da semente inicial. Dessa forma, mesmo que as séries atinjam o mesmo valor, elas divergem imediatamente.Usando um guid
muito curto ...
fonte
Semelhante ao primeiro exemplo, mas com mais flexibilidade:
Esqueci de mencionar um dos outros recursos que tornam isso mais flexível. Repetindo blocos de personagens em @CharPool, você pode aumentar o peso de certos personagens para que sejam mais propensos a serem escolhidos.
fonte
CONVERT(int, RAND() * @PoolLength) + 1
(observe o +1 adicionado). SUBSTRING no T-SQL começa com o índice 1, portanto, do jeito que está, essa função às vezes adiciona uma string vazia (quando o índice é 0) e nunca adiciona o último caractere do@CharPool
.Use o seguinte código para retornar uma string curta:
fonte
Se você estiver executando o SQL Server 2008 ou superior, poderá usar a nova função criptográfica crypt_gen_random () e, em seguida, usar a codificação base64 para torná-la uma string. Isso funcionará para até 8.000 caracteres.
fonte
Não sou especialista em T-SQL, mas a maneira mais simples que já usei é assim:
Isso gera dois caracteres (AZ, em ascii 65-90).
fonte
Isso retornará os 5 caracteres mais à esquerda da string guia
fonte
Aqui está um gerador alfa numérico aleatório
fonte
Para uma letra aleatória, você pode usar:
Uma diferença importante entre usar
newid()
versusrand()
é que se você retornar várias linhas,newid()
é calculado separadamente para cada linha, enquantorand()
é calculado uma vez para a consulta inteira.fonte
Isso funcionou para mim: eu precisava gerar apenas três caracteres alfanuméricos aleatórios para um ID, mas poderia funcionar para qualquer comprimento de até 15 ou mais.
fonte
Existem muitas respostas boas, mas até agora nenhuma delas permite um conjunto de caracteres personalizável e funciona como um valor padrão para uma coluna. Eu queria ser capaz de fazer algo assim:
Então eu vim com isso. Cuidado com o número 32 embutido no código se você modificá-lo.
fonte
Sei que essa é uma pergunta antiga com muitas respostas boas. No entanto, quando descobri isso, também encontrei um artigo mais recente no TechNet de Saeid Hasani
T-SQL: como gerar senhas aleatórias
Embora a solução se concentre em senhas, ela se aplica ao caso geral. Saeid trabalha com várias considerações para chegar a uma solução. É muito instrutivo.
Um script que contém todos os blocos de código do artigo está disponível separadamente na TechNet Gallery , mas eu definitivamente começaria pelo artigo.
fonte
Eu utilizo este procedimento que desenvolvi simplesmente estipulando os caracteres que você deseja exibir nas variáveis de entrada, você pode definir o comprimento também. Espero que este formato seja bom, sou novo no estouro de pilha.
fonte
Às vezes, precisamos de muitas coisas aleatórias: amor, gentileza, férias, etc. Eu colecionei alguns geradores aleatórios ao longo dos anos, e estes são de Pinal Dave e uma resposta stackoverflow que encontrei uma vez. Refs abaixo.
fonte
Aqui está uma que pensei hoje (porque não gostei de nenhuma das respostas existentes o suficiente).
Este gera uma tabela temporária de strings aleatórias, baseada em
newid()
, mas também suporta um conjunto de caracteres personalizados (então mais do que apenas 0-9 e AF), comprimento personalizado (até 255, o limite é codificado, mas pode ser alterado) e um número personalizado de registros aleatórios.Aqui está o código-fonte (espero que os comentários ajudem):
Não é um procedimento armazenado, mas não seria tão difícil transformá-lo em um. Também não é terrivelmente lento (levou cerca de 0,3 segundos para gerar 1.000 resultados de comprimento 60, o que é mais do que eu vou precisar pessoalmente), que foi uma das minhas preocupações iniciais de todas as mutações de string que estou fazendo.
A principal lição aqui é que não estou tentando criar meu próprio gerador de números aleatórios e meu conjunto de caracteres não é limitado. Estou simplesmente usando o gerador aleatório que o SQL tem (eu sei que existe
rand()
, mas isso não é ótimo para resultados de tabela). Esperançosamente, esta abordagem combina os dois tipos de respostas aqui, de simples demais (ou seja, apenasnewid()
) e excessivamente complexa (ou seja, algoritmo de número aleatório personalizado).Também é curto (sem os comentários) e fácil de entender (pelo menos para mim), o que é sempre um ponto positivo no meu livro.
No entanto, esse método não pode ser propagado, então ele será realmente aleatório todas as vezes e você não poderá replicar o mesmo conjunto de dados com qualquer meio de confiabilidade. O OP não listou isso como um requisito, mas sei que algumas pessoas procuram esse tipo de coisa.
Sei que estou atrasado para a festa aqui, mas espero que alguém ache isso útil.
fonte
Eu encontrei esta postagem do blog primeiro, então vim com o seguinte procedimento armazenado para isso que estou usando em um projeto atual (desculpe pela formatação estranha):
fonte
Fiz isso no SQL 2000 criando uma tabela que tinha os caracteres que eu queria usar, criando uma visualização que seleciona os caracteres dessa tabela ordenados por newid () e, em seguida, selecionando o primeiro personagem dessa visualização.
Em seguida, você pode simplesmente puxar os caracteres da visualização e concatená-los conforme necessário.
EDITAR: Inspirado na resposta de Stephan ...
Não há necessidade de uma visão (na verdade, não sei por que fiz isso - o código é de vários anos atrás). Você ainda pode especificar os caracteres que deseja usar na tabela.
fonte
Aqui está algo baseado em New Id.
fonte
Pensei em compartilhar ou retribuir à comunidade ... É baseado em ASCII, e a solução não é perfeita, mas funciona muito bem. Aproveite, Goran B.
fonte
Isso usa rand com uma semente como uma das outras respostas, mas não é necessário fornecer uma semente em cada chamada. Fornecê-lo na primeira chamada é suficiente.
Este é o meu código modificado.
fonte
No SQL Server 2012+ , poderíamos concatenar os binários de alguns (G) UIDs e, em seguida, fazer uma conversão de base64 no resultado.
Se você precisar de strings mais longas (ou se vir
=
caracteres no resultado), será necessário adicionar mais+ CAST(newid() as varbinary(max))
na sub seleção.fonte
Então, gostei muito das respostas acima, mas estava procurando por algo que fosse um pouco mais aleatório por natureza. Eu também queria uma maneira de chamar explicitamente os personagens excluídos. Abaixo está minha solução usando um modo de exibição que chama o
CRYPT_GEN_RANDOM
para obter um número aleatório criptográfico. No meu exemplo, escolhi apenas um número aleatório de 8 bytes. Observe que você pode aumentar esse tamanho e também utilizar o parâmetro semente da função, se desejar. Aqui está o link para a documentação: https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sqlA razão para criar a visualização é porque
CRYPT_GEN_RANDOM
não pode ser chamada diretamente de uma função.A partir daí, criei uma função escalar que aceita um comprimento e um parâmetro de string que pode conter uma string delimitada por vírgulas de caracteres excluídos.
Abaixo está um exemplo de como chamar a função.
~ Saúde
fonte
é muito simples. use-o e aproveite.
fonte
Isso produzirá uma string de 96 caracteres de comprimento, do intervalo Base64 (superiores, inferiores, números, + e /). Adicionar 3 "NEWID ()" aumentará o comprimento em 32, sem preenchimento Base64 (=).
Se você estiver aplicando isso a um conjunto, certifique-se de introduzir algo desse conjunto para que o NEWID () seja recalculado, caso contrário, você obterá o mesmo valor a cada vez:
fonte
Para SQL Server 2016 e posterior, aqui está uma expressão realmente simples e relativamente eficiente para gerar strings criptograficamente aleatórias de um determinado comprimento de byte:
Observe que o comprimento do byte não é igual ao tamanho codificado; use o seguinte deste artigo para converter:
fonte
Com base em várias respostas úteis neste artigo, cheguei a uma combinação de algumas opções de que gostei.
fonte