Câu trả lời phụ thuộc vào yêu cầu của bạn về kết quả. Bạn có yêu cầu một kết quả với một tập hợp các cột nhất quán, bất kể giá trị của người dùng không? Nếu vậy, bạn có thể đặt các giá trị không được phép thành null (hoặc một số giá trị đặc biệt khác) bằng cách sử dụng mệnh đề IF, ví dụ:
SELECT IF (p.col1 = 0 THEN NULL ELSE d.col1) AS col1,
IF (p.col2 = 0 THEN NULL ELSE d.col2) AS col2,
IF (p.col3 = 0 THEN NULL ELSE d.col3) AS col3
FROM Data d,
UserPrivileges p
WHERE p.userId = '#'
AND d.DataId = '#'
Tất nhiên, "giá trị đặc biệt" có thể là một vấn đề, vì bạn cần một giá trị sẽ không bao giờ xuất hiện trong dữ liệu. Nếu bạn cần biết sự khác biệt giữa null vì giá trị thực là null so với null vì nó là cột bị cấm thì bạn không thể sử dụng null.
Một cách tiếp cận khác sẽ giúp bạn đơn giản bao gồm chỉ báo đặc quyền cho mỗi cột xuất hiện trong kết quả và cho phép logic nghiệp vụ của bạn sử dụng điều đó để xác định giá trị nào hiển thị cho người dùng.
Một cách tiếp cận rất khác sẽ có tập kết quả chỉ chứa các cột được phép. Trong trường hợp này, bạn sẽ cần phải xây dựng câu lệnh sql của mình một cách động. Tôi không biết bạn đang thực hiện việc này trong một thủ tục được lưu trữ hay bằng ngôn ngữ máy chủ, nhưng ý tưởng cơ bản là như sau:
string sqlCmd = "SELECT "
+ (SELECT (FIELDS_NAME_QUERY(UserID='#')
FROM USER_PRIVILEGES
WHERE userid='#')
+ FROM data d
execute sqlCmd
"thực thi" nghĩa là bất kỳ thứ gì bạn có sẵn để thực thi một chuỗi dưới dạng lệnh sql.
thêm sau khi làm rõ bởi OP:
Được rồi, bạn cần hàm sql trả về một chuỗi giống như "colname1, colname2, ...". Phần sau tương tự như nó sẽ trông như thế nào trong máy chủ sql. cú pháp
create function
FIELDS_NAME_QUERY (@userid int)
begin
select col1, col2, col3... INTO @col1priv, @col2priv, @col3priv FROM userPrivileges WHERE UserId = @UserId
declare @result varhcar(60)
set @result = ''
if (@col1priv = 1) @result = 'col1'
if (@col2priv = 1) @result = @result + ' ,col2'
if (@col3priv = 1) @result = @result + ' ,col3'
return @result
end