Vì rõ ràng bạn đang sử dụng SQL Server 2016, tôi muốn loại bỏ tùy chọn ' có thể ' khác - SESSION_CONTEXT
.
Bài viết của Leonard lobel, Sharing State trong SQL Server 2016 vớiSESSION_CONTEXT
một số thông tin rất hay về chức năng mới này trong SQL Server 2016.
Tóm tắt một số điểm chính:
Nếu bạn đã từng muốn chia sẻ trạng thái phiên trên tất cả các quy trình và đợt được lưu trữ trong suốt vòng đời của kết nối cơ sở dữ liệu, bạn sẽ thích SESSION_CONTEXT
. Khi bạn kết nối với SQL Server 2016, bạn sẽ nhận được một từ điển trạng thái hoặc những gì thường được gọi là túi trạng thái, một số nơi bạn có thể lưu trữ các giá trị, như chuỗi và số, sau đó truy xuất nó bằng một khóa mà bạn gán. Trong trường hợp SESSION_CONTEXT
, khóa là bất kỳ chuỗi nào và giá trị là một sql_variant, có nghĩa là nó có thể chứa nhiều loại.
Khi bạn lưu trữ một cái gì đó SESSION_CONTEXT
, nó sẽ ở đó cho đến khi kết nối đóng lại. Nó không được lưu trữ trong bất kỳ bảng nào trong cơ sở dữ liệu, nó chỉ tồn tại trong bộ nhớ miễn là kết nối vẫn còn tồn tại. Và bất kỳ và tất cả các mã T-SQL đang chạy bên trong các thủ tục, trình kích hoạt, hàm hoặc bất cứ thứ gì được lưu trữ có thể chia sẻ bất cứ điều gì bạn chuyển vào
SESSION_CONTEXT
.
Điều gần nhất như thế này chúng ta có từ trước đến nay CONTEXT_INFO
, cho phép bạn lưu trữ và chia sẻ một giá trị nhị phân duy nhất dài tới 128 byte, kém linh hoạt hơn nhiều so với từ điển bạn có SESSION_CONTEXT
, hỗ trợ nhiều giá trị của dữ liệu khác nhau các loại.
SESSION_CONTEXT
rất dễ sử dụng, chỉ cần gọi sp_set_session_context để lưu giá trị theo khóa mong muốn. Khi bạn làm điều đó, bạn cung cấp khóa và giá trị của khóa học, nhưng bạn cũng có thể đặt tham số read_only thành true. Đây là khóa giá trị trong ngữ cảnh phiên, do đó, nó không thể thay đổi trong suốt thời gian còn lại của kết nối. Vì vậy, ví dụ, ứng dụng khách dễ dàng gọi thủ tục được lưu trữ này để đặt một số giá trị ngữ cảnh phiên ngay sau khi thiết lập kết nối cơ sở dữ liệu. Nếu ứng dụng đặt tham số read_only khi thực hiện điều này, thì các thủ tục được lưu trữ và mã T-SQL khác sau đó thực thi trên máy chủ chỉ có thể đọc giá trị, chúng không thể thay đổi những gì được cài đặt bởi ứng dụng đang chạy trên máy khách.
Để thử nghiệm, tôi đã tạo một trình kích hoạt đăng nhập máy chủ để đặt một số CONTEXT_SESSION
thông tin - một trong số SESSION_CONTEXT
đó đã được đặt thành @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;
Tôi đã đăng nhập như một người dùng hoàn toàn mới và có thể trích xuất SESSION_CONTEXT
thông tin:
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
Tôi thậm chí đã cố gắng thay đổi thông tin ngữ cảnh 'read_only':
EXEC sp_set_session_context @key = N'CannotChange'
,@value = N'CannotChangeThisValue'
và đã nhận được một lỗi:
Msg 15664, Cấp 16, Trạng thái 1, Quy trình sp_set_session_context, Dòng 1 [Batch Start Line 8] Không thể đặt khóa 'Không thể thay đổi' trong ngữ cảnh phiên. Khóa đã được đặt là read_only cho phiên này.
Một lưu ý quan trọng về kích hoạt đăng nhập ( từ bài đăng này )!
Trình kích hoạt đăng nhập có thể ngăn chặn hiệu quả các kết nối thành công đến Cơ sở dữ liệu cho tất cả người dùng, bao gồm cả các thành viên của vai trò máy chủ cố định sysadmin. Khi trình kích hoạt đăng nhập ngăn kết nối, các thành viên của vai trò máy chủ cố định sysadmin có thể kết nối bằng cách sử dụng kết nối quản trị viên chuyên dụng hoặc bằng cách khởi động Cơ sở dữ liệu ở chế độ cấu hình tối thiểu (-f)
Một nhược điểm tiềm năng là điều này sẽ lấp đầy phiên bản bối cảnh phiên (không phải trên mỗi cơ sở dữ liệu). Tại thời điểm này, các tùy chọn duy nhất tôi có thể nghĩ đến là:
- Đặt
Session_Context
tên cho các cặp tên-giá trị của bạn bằng cách thêm tiền tố vào tên cơ sở dữ liệu để không gây ra xung đột cho tên cùng loại trong cơ sở dữ liệu khác. Điều này không giải quyết được vấn đề xác định trước TẤT CẢ Session_Context
các giá trị tên cho tất cả người dùng.
- Khi kích hoạt đăng nhập kích hoạt, bạn có quyền truy cập
EventData
(xml) mà bạn có thể sử dụng để trích xuất người dùng đăng nhập và dựa vào đó, bạn có thể tạo các Session_Context
cặp giá trị tên cụ thể .