Jika Anda ingin membuat string alfanumerik pseudorandom menggunakan T-SQL, bagaimana Anda melakukannya? Bagaimana Anda mengecualikan karakter seperti tanda dolar, tanda hubung, dan garis miring dari itu?
Saat membuat data acak, khususnya untuk pengujian, sangat berguna untuk membuat data acak, tetapi dapat direproduksi. Rahasianya adalah menggunakan seed eksplisit untuk fungsi acak, sehingga ketika pengujian dijalankan lagi dengan seed yang sama, ia menghasilkan lagi string yang persis sama. Berikut adalah contoh sederhana dari sebuah fungsi yang menghasilkan nama objek dengan cara yang dapat direproduksi:
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
Saat menjalankan pengujian, pemanggil menghasilkan seed acak yang dikaitkan dengan uji coba (menyimpannya di tabel hasil), lalu meneruskan seed, mirip dengan ini:
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;
Pembaruan 2016-02-17: Lihat komentar di bawah, prosedur asli memiliki masalah dalam cara memajukan benih acak. Saya memperbarui kode, dan juga memperbaiki masalah off-by-one yang disebutkan.
@seed = rand(@seed+1)*2147483647
. Untuk nilai 529126 nilai berikutnya adalah 1230039262 kemudian nilai berikutnya adalah 192804. urutan berlanjut sama setelah ini. Keluarannya harus berbeda dengan karakter pertama, tetapi bukan karena kesalahan off-by-one:SUBSTRING(..., 0, ...)
mengembalikan string kosong untuk indeks 0, dan untuk 529126 ini 'menyembunyikan' karakter pertama yang dihasilkan. Perbaiki adalah menghitung@dice = rand(@seed) * len(@specials)+1
untuk membuat indeks 1 berbasis.+1
dalamrand(@seed+1)
menjadi dirinya sendiri acak dan ditentukan dari benih awal saja. Dengan cara ini, bahkan jika rangkaian mencapai nilai yang sama, keduanya segera menyimpang.Menggunakan panduan
sangat singkat ...
sumber
Mirip dengan contoh pertama, tetapi dengan lebih banyak fleksibilitas:
Saya lupa menyebutkan salah satu fitur lain yang membuatnya lebih fleksibel. Dengan mengulang blok karakter di @CharPool, Anda dapat meningkatkan pembobotan pada karakter tertentu sehingga lebih mungkin untuk dipilih.
sumber
CONVERT(int, RAND() * @PoolLength) + 1
(perhatikan +1 yang ditambahkan). SUBSTRING di T-SQL dimulai dengan indeks 1, sehingga fungsi ini terkadang menambahkan string kosong (jika indeksnya 0), dan tidak pernah menambahkan karakter terakhir dari@CharPool
.Gunakan kode berikut untuk mengembalikan string pendek:
sumber
Jika Anda menjalankan SQL Server 2008 atau yang lebih baru, Anda dapat menggunakan fungsi kriptografi baru crypt_gen_random () dan kemudian menggunakan pengkodean base64 untuk menjadikannya sebuah string. Ini akan bekerja hingga 8000 karakter.
sumber
Saya tidak ahli dalam T-SQL, tetapi cara paling sederhana yang pernah saya gunakan adalah seperti itu:
Ini menghasilkan dua karakter (AZ, di ascii 65-90).
sumber
Ini akan mengembalikan 5 karakter paling kiri dari string guid
sumber
Berikut adalah generator alfa numerik acak
sumber
Untuk satu huruf acak, Anda dapat menggunakan:
Perbedaan penting antara menggunakan
newid()
versusrand()
adalah jika Anda mengembalikan beberapa baris,newid()
dihitung secara terpisah untuk setiap baris, sementararand()
dihitung sekali untuk seluruh kueri.sumber
Ini berhasil untuk saya: Saya hanya perlu membuat tiga karakter alfanumerik acak untuk sebuah ID, tetapi bisa bekerja untuk panjang apa pun hingga 15 atau lebih.
sumber
Ada banyak jawaban bagus tetapi sejauh ini tidak ada yang mengizinkan kumpulan karakter yang dapat disesuaikan dan berfungsi sebagai nilai default untuk kolom. Saya ingin bisa melakukan sesuatu seperti ini:
Jadi saya datang dengan ini. Waspadalah terhadap kode keras nomor 32 jika Anda memodifikasinya.
sumber
Saya menyadari bahwa ini adalah pertanyaan lama dengan banyak jawaban bagus. Namun ketika saya menemukan ini, saya juga menemukan artikel yang lebih baru di TechNet oleh Saeid Hasani
T-SQL: Cara Menghasilkan Kata Sandi Acak
Sementara solusinya berfokus pada kata sandi, itu berlaku untuk kasus umum. Saeid bekerja melalui berbagai pertimbangan untuk mendapatkan solusi. Ini sangat instruktif.
Skrip yang berisi semua blok kode dari artikel tersedia secara terpisah melalui Galeri TechNet , tetapi saya pasti akan mulai dari artikel tersebut.
sumber
Saya menggunakan prosedur ini yang saya kembangkan hanya dengan menetapkan karakter yang ingin Anda tampilkan di variabel input, Anda juga dapat menentukan panjangnya. Semoga format ini baik, saya baru mengenal stack overflow.
sumber
Terkadang kita membutuhkan banyak hal acak: cinta, kebaikan, liburan, dll. Saya telah mengumpulkan beberapa generator acak selama bertahun-tahun, dan ini berasal dari Pinal Dave dan jawaban stackoverflow yang saya temukan sekali. Referensi di bawah.
sumber
Inilah yang saya dapatkan hari ini (karena saya tidak cukup menyukai jawaban yang ada).
Yang ini menghasilkan tabel temp string acak, berdasarkan
newid()
, tetapi juga mendukung set karakter kustom (jadi lebih dari sekadar 0-9 & AF), panjang kustom (hingga 255, batas hard-coded, tetapi dapat diubah), dan sejumlah custom record acak.Berikut kode sumbernya (semoga komentarnya membantu):
Ini bukan prosedur tersimpan, tetapi tidak akan sulit untuk mengubahnya menjadi satu. Ini juga tidak terlalu lambat (saya membutuhkan ~ 0,3 detik untuk menghasilkan 1.000 hasil dengan panjang 60, yang lebih dari yang saya perlukan secara pribadi), yang merupakan salah satu perhatian awal saya dari semua mutasi string yang saya lakukan.
Kesimpulan utama di sini adalah saya tidak mencoba membuat generator nomor acak saya sendiri, dan rangkaian karakter saya tidak terbatas. Saya hanya menggunakan generator acak yang dimiliki SQL (saya tahu ada
rand()
, tapi itu tidak bagus untuk hasil tabel). Mudah-mudahan pendekatan ini mengawinkan dua jenis jawaban di sini, dari yang terlalu sederhana (yaitu hanyanewid()
) dan terlalu kompleks (yaitu algoritma bilangan acak khusus).Ini juga singkat (minus komentar), dan mudah dimengerti (setidaknya bagi saya), yang selalu menjadi nilai plus di buku saya.
Namun, metode ini tidak dapat diunggulkan, jadi metode ini akan benar-benar acak setiap kali, dan Anda tidak akan dapat mereplikasi kumpulan data yang sama dengan cara apa pun yang dapat diandalkan. OP tidak mencantumkannya sebagai persyaratan, tetapi saya tahu bahwa beberapa orang mencari hal semacam itu.
Saya tahu saya terlambat ke pesta di sini, tapi mudah-mudahan seseorang akan menganggap ini berguna.
sumber
Untuk SQL Server 2016 dan yang lebih baru, berikut adalah ekspresi yang sangat sederhana dan relatif efisien untuk menghasilkan string acak secara kriptografis dengan panjang byte tertentu:
Perhatikan bahwa panjang byte tidak sama dengan ukuran yang dikodekan; gunakan yang berikut dari artikel ini untuk mengonversi:
sumber
Saya menemukan posting blog ini terlebih dahulu, kemudian muncul dengan prosedur tersimpan berikut untuk ini yang saya gunakan pada proyek saat ini (maaf untuk pemformatan yang aneh):
sumber
Saya melakukan ini di SQL 2000 dengan membuat tabel yang memiliki karakter yang ingin saya gunakan, membuat tampilan yang memilih karakter dari tabel yang diurutkan berdasarkan newid (), lalu memilih 1 karakter teratas dari tampilan tersebut.
Kemudian Anda cukup menarik karakter dari tampilan dan menggabungkannya sesuai kebutuhan.
EDIT: Terinspirasi oleh tanggapan Stephan ...
Tidak perlu melihat (sebenarnya saya tidak yakin mengapa saya melakukan itu - kode itu dari beberapa tahun yang lalu). Anda masih dapat menentukan karakter yang ingin Anda gunakan di tabel.
sumber
Inilah sesuatu berdasarkan Id Baru.
sumber
Saya pikir saya akan berbagi, atau memberikan kembali kepada komunitas ... Ini berbasis ASCII, dan solusinya tidak sempurna tetapi bekerja dengan cukup baik. Selamat menikmati, Goran B.
sumber
Ini menggunakan rand dengan benih seperti salah satu jawaban lainnya, tetapi tidak perlu memberikan benih pada setiap panggilan. Memberikannya pada panggilan pertama sudah cukup.
Ini adalah kode saya yang dimodifikasi.
sumber
Di SQL Server 2012+ kami dapat menggabungkan biner dari beberapa (G) UID dan kemudian melakukan konversi base64 pada hasilnya.
Jika Anda membutuhkan string yang lebih panjang (atau Anda melihat
=
karakter di hasil) Anda perlu menambahkan lebih banyak+ CAST(newid() as varbinary(max))
di sub pilih.sumber
Jadi saya menyukai banyak jawaban di atas, tetapi saya mencari sesuatu yang sifatnya sedikit lebih acak. Saya juga menginginkan cara untuk secara eksplisit memanggil karakter yang dikecualikan. Di bawah ini adalah solusi saya menggunakan tampilan yang memanggil
CRYPT_GEN_RANDOM
untuk mendapatkan nomor acak kriptografi. Dalam contoh saya, saya hanya memilih nomor acak yaitu 8 byte. Harap dicatat, Anda dapat meningkatkan ukuran ini dan juga menggunakan parameter seed dari fungsi tersebut jika Anda mau. Berikut ini tautan ke dokumentasinya: https://docs.microsoft.com/en-us/sql/t-sql/functions/crypt-gen-random-transact-sqlAlasan untuk membuat tampilan tersebut adalah karena
CRYPT_GEN_RANDOM
tidak bisa dipanggil langsung dari suatu fungsi.Dari sana, saya membuat fungsi skalar yang menerima panjang dan parameter string yang dapat berisi string yang dipisahkan koma dari karakter yang dikecualikan.
Di bawah ini adalah contoh bagaimana memanggil fungsi tersebut.
~ Cheers
sumber
itu sangat sederhana. gunakan dan nikmati.
sumber
Ini akan menghasilkan string sepanjang 96 karakter, dari rentang Base64 (bagian atas, bawah, angka, + dan /). Menambahkan 3 "NEWID ()" akan menambah panjang 32, tanpa padding Base64 (=).
Jika Anda menerapkan ini ke satu set, pastikan untuk memperkenalkan sesuatu dari set itu sehingga NEWID () dihitung ulang, jika tidak, Anda akan mendapatkan nilai yang sama setiap kali:
sumber
Berdasarkan berbagai tanggapan bermanfaat dalam artikel ini, saya mendapatkan kombinasi dari beberapa opsi yang saya suka.
sumber