Saya punya pertanyaan tentang sepotong dokumentasi tentang Tabel Temp yang baru-baru ini saya baca di TechNet . Paragraf keempat bagian Tabel Sementara pada halaman itu berbunyi sebagai berikut:
Jika tabel sementara dibuat dengan batasan bernama dan tabel sementara dibuat dalam lingkup transaksi yang ditentukan pengguna, hanya satu pengguna pada satu waktu yang dapat menjalankan pernyataan yang membuat tabel temp. Misalnya, jika prosedur tersimpan membuat tabel sementara dengan batasan kunci primer bernama, prosedur tersimpan tidak dapat dijalankan secara bersamaan oleh beberapa pengguna.
Saya bekerja di lingkungan di mana kami menggunakan secara signifikan beberapa prosedur tersimpan yang menggunakan tabel temp diindeks, dan kami tidak pernah mengalami masalah di mana pengguna harus menunggu satu eksekusi untuk menyelesaikan sebelum yang berikutnya dimulai. Saya harap itu akan terus menjadi masalah, tetapi saya khawatir hal itu bisa menjadi masalah jika peringatan ini tidak dipahami dengan baik.
Secara khusus, saya tidak jelas tentang hal-hal berikut:
- Apakah ini hanya berlaku untuk tabel temp global, atau yang temporer juga? Tampaknya aneh bahwa tabel yang tidak terlihat di luar sesi (seperti dalam kasus yang terakhir) akan mencegah sesi lain dari eksekusi secara bersamaan.
- Apa yang memenuhi syarat sebagai "batasan nama"? Tidak semua kendala memiliki nama (bahkan jika itu dihasilkan oleh sistem)? Apakah ini merujuk pada kendala dengan alias yang ditentukan pengguna? Ini sepertinya ungkapan yang buruk bagiku.
- Apakah "banyak pengguna" sebenarnya berarti beberapa sesi? Prosedur ini dipanggil melalui aplikasi kami menggunakan akun layanan tunggal, sehingga 99,9% panggilan ke skrip kami dilakukan ke DB oleh akun tunggal itu (dan saya tidak peduli tentang panggilan sesekali yang mungkin dilakukan admin di backend). Jika akun layanan dapat menjalankan sproc dalam beberapa sesi secara bersamaan, maka masalah ini diperdebatkan untuk tujuan saya.
sumber
Jawaban:
Saya menganggapnya karena Anda tidak dapat memiliki nama duplikat di dalamnya
tempdb.sys.key_constraints
. Inilah yang ada di tampilan metadata di salah satu server saya:Semua nama aneh yang diakhiri dengan
_6E...
adalah nama yang dihasilkan secara otomatis oleh SQL Server. Mereka tidak bernama kendala karena saya tidak secara eksplisit memberi mereka nama saat membuat mereka. SQL Server menghasilkan nama kendala di belakang layar yang secara teori menghindari tabrakan nama.Jika saya mencoba membuat tabel berikut dalam dua sesi berbeda:
Yang berjalan kedua melempar kesalahan:
Lihat lagi tampilan:
Jika saya mencoba membuat tabel berikut dalam dua sesi tidak ada masalah:
Berikut tampilan metadata:
Hanya untuk menjawab pertanyaan Anda secara langsung: bagian yang Anda kutip berlaku untuk tabel sementara lokal dan global, batasan bernama adalah batasan yang Anda berikan nama secara sengaja, dan banyak pengguna berarti beberapa sesi.
sumber
Ini berlaku untuk tabel temp lokal.
Perbedaan antara kendala bernama dan tidak bernama adalah ini:
Membiarkan kendala nama sistem membuatnya sangat tidak mungkin terjadi tabrakan. Dalam contoh ini, jika Anda membuka dua jendela di SSMS, Anda bisa membuatnya
#t1
di keduanya, tetapi tidak#t2
.Tabel sementara global dibagikan oleh semua pengguna, jadi Anda harus menangani berbagai hal secara berbeda. Mereka tidak 'dihancurkan' sampai sesi terakhir selesai menggunakannya, jadi Anda perlu memastikan bahwa ketika pengguna mengaksesnya, mereka hanya dapat mengakses data mereka. Ini kadang-kadang dilakukan oleh SPID, kali lain dengan nilai hash. Itu tergantung pada bagaimana tabel temp global digunakan.
Biasanya untuk tabel temp global, prosedur tersimpan akan memeriksa untuk melihat apakah ada, dan kemudian hanya membuatnya jika
OBJECT_ID()
adaNULL
.Banyak pengguna berarti banyak sesi. Nama login tidak ada hubungannya dengan itu. Jika George berjalan
sp_something @i = 1
dan Gina berjalansp_something @i = 2
, tidak masalah jika keduanya masukUser1
, mereka akan memiliki SPID yang berbeda.sumber