Karena Anda tampaknya menggunakan SQL Server 2016, saya ingin membuang opsi ' mungkin ' lainnya - SESSION_CONTEXT
.
Artikel Leonard Lobel, Berbagi Negara di SQL Server 2016 denganSESSION_CONTEXT
memiliki beberapa informasi yang sangat baik tentang fungsi baru ini di SQL Server 2016.
Meringkas beberapa poin utama:
Jika Anda pernah ingin berbagi status sesi di semua prosedur dan kumpulan yang tersimpan sepanjang masa koneksi database, Anda akan menyukainya SESSION_CONTEXT
. Ketika Anda tersambung ke SQL Server 2016, Anda mendapatkan kamus stateful, atau apa yang sering disebut sebagai tas negara, tempat di mana Anda dapat menyimpan nilai, seperti string dan angka, dan kemudian mengambilnya dengan kunci yang Anda tetapkan. Dalam kasus SESSION_CONTEXT
, kuncinya adalah string apa pun, dan nilainya adalah sql_variant, artinya dapat mengakomodasi berbagai jenis.
Setelah Anda menyimpan sesuatu SESSION_CONTEXT
, itu tetap di sana sampai koneksi ditutup. Itu tidak disimpan dalam tabel apa pun di database, itu hanya tinggal di memori selama koneksi tetap hidup. Dan setiap dan semua kode T-SQL yang berjalan di dalam prosedur tersimpan, pemicu, fungsi, atau apa pun, dapat membagikan apa pun yang Anda dorong
SESSION_CONTEXT
.
Hal terdekat yang kami miliki hingga saat ini adalah CONTEXT_INFO
, yang memungkinkan Anda untuk menyimpan dan berbagi nilai biner tunggal hingga 128 byte, yang jauh lebih fleksibel daripada kamus yang Anda dapatkan SESSION_CONTEXT
, yang mendukung banyak nilai dari data yang berbeda jenis.
SESSION_CONTEXT
mudah digunakan, cukup panggil sp_set_session_context untuk menyimpan nilai dengan kunci yang diinginkan. Ketika Anda melakukannya, Anda memberikan kunci dan nilai tentu saja, tetapi Anda juga dapat mengatur parameter read_only menjadi true. Ini mengunci nilai dalam konteks sesi, sehingga tidak dapat diubah selama sisa koneksi. Jadi, misalnya, mudah bagi aplikasi klien untuk memanggil prosedur tersimpan ini untuk menetapkan beberapa nilai konteks sesi setelah membuat koneksi database. Jika aplikasi menetapkan parameter read_only ketika melakukan ini, maka prosedur tersimpan dan kode T-SQL lain yang kemudian dieksekusi di server hanya dapat membaca nilai, mereka tidak dapat mengubah apa yang ditetapkan oleh aplikasi yang berjalan pada klien.
Sebagai ujian, saya membuat pemicu masuk server yang menetapkan beberapa CONTEXT_SESSION
informasi - salah SESSION_CONTEXT
satunya ditetapkan @read_only
.
DROP TRIGGER IF EXISTS [InitializeSessionContext] ON ALL SERVER
GO
CREATE TRIGGER InitializeSessionContext ON ALL SERVER
FOR LOGON AS
BEGIN
--Initialize context information that can be altered in the session
EXEC sp_set_session_context @key = N'UsRegion'
,@value = N'Southeast'
--Initialize context information that cannot be altered in the session
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
,@read_only = 1
END;
Saya masuk sebagai pengguna yang sama sekali baru dan dapat mengekstraksi SESSION_CONTEXT
informasi:
DECLARE @UsRegion varchar(20)
SET @UsRegion = CONVERT(varchar(20), SESSION_CONTEXT(N'UsRegion'))
SELECT DoThat = @UsRegion
DECLARE @CannotChange varchar(20)
SET @CannotChange = CONVERT(varchar(20), SESSION_CONTEXT(N'CannotChange'))
SELECT DoThat = @CannotChange
Saya bahkan berusaha mengubah informasi konteks 'read_only':
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
dan menerima kesalahan:
Msg 15664, Level 16, Status 1, Prosedur sp_set_session_context, Line 1 [Batch Start Line 8] Tidak dapat mengatur kunci 'CannotChange' dalam konteks sesi. Kunci telah ditetapkan sebagai read_only untuk sesi ini.
Catatan penting tentang pemicu masuk ( dari pos ini )!
Pemicu masuk secara efektif dapat mencegah koneksi yang berhasil ke Mesin Database untuk semua pengguna, termasuk anggota peran server tetap sysadmin. Ketika pemicu masuk mencegah koneksi, anggota peran server tetap sysadmin dapat terhubung dengan menggunakan koneksi administrator khusus, atau dengan memulai Mesin Database dalam mode konfigurasi minimal (-f)
Salah satu kelemahan potensial adalah bahwa ini mengisi konteks konteks sesi luas (tidak per database). Pada titik ini, satu-satunya pilihan yang dapat saya pikirkan adalah:
- Namai
Session_Context
pasangan nama-nilai Anda dengan mengawalinya dengan nama basis data agar tidak menyebabkan tabrakan untuk nama jenis yang sama di basis data lain. Ini tidak memecahkan masalah pra-mendefinisikan SEMUA Session_Context
nilai-nama untuk semua pengguna.
- Ketika pemicu login menyala, Anda memiliki akses ke
EventData
(xml) yang bisa Anda gunakan untuk mengekstrak pengguna login dan berdasarkan itu, Anda bisa membuat Session_Context
pasangan nilai-nama tertentu .