SQL: выбор столбцов на основе значения столбца из другой таблицы - PullRequest
6 голосов
/ 30 декабря 2011

У меня есть следующие таблицы:

UserPrivileges: 
+--------+------+------+------+
| UserID | Col1 | Col2 | Col3 |
+--------+------+------+------+
|      1 |    0 |    1 |    1 |
|      2 |    0 |    0 |    1 |
|      3 |    1 |    0 |    0 |
|      4 |    1 |    1 |    0 |
+--------+------+------+------+

Data:
+--------+------+------+------+
| DataID | Col1 | Col2 | Col3 |
+--------+------+------+------+
|      1 | A    | B    | C    |
|      2 | D    | E    | F    |
|      3 | G    | H    | I    |
|      4 | J    | K    | L    |
+--------+------+------+------+

Мой вопрос в его простейшей форме не имеет ничего общего с таблицей Data, но я все равно объясняю это так, чтобы я мог это делатьнеправильный путь.

Как выбрать имена столбцов из UserPrivileges на основе значения?Так что я могу использовать результат в другом запросе, чтобы выбрать только эти столбцы.

Что-то вроде этих строк:

SELECT (COLUMNS_NAME_QUERY_FROM_UserPrivileges(UserID='#')) WHERE DataID = '#' FROM Data

Или я не возражаю против лучшегоспособ управления привилегиями пользователей для определенных столбцов.

Ответы [ 2 ]

6 голосов
/ 30 декабря 2011

Ответ зависит от ваших требований к результату.Требуется ли результат с согласованным набором столбцов, независимо от привилегий пользователя?Если это так, вы можете установить недопустимые значения в null (или другое специальное значение), используя предложение IF, например,

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 = '#'

. Конечно, «специальное значение» может быть проблемой, так как вам нужнозначение, которое никогда не появится в данных.Если вам нужно было узнать разницу между нулем, потому что реальное значение равно нулю, а не пусто, потому что это запрещенный столбец, тогда вы не можете использовать ноль.

Другой подход заключается в том, чтобы вы просто включали индикатор привилегий для каждого столбца, появляющегося в результате, и позволяли вашей бизнес-логике использовать его, чтобы определить, какие значения видны пользователю.

У совсем другого подхода набор результатов должен содержать только разрешенные столбцы.В этом случае вам нужно динамически построить оператор SQL.Я не знаю, делаете ли вы это в хранимой процедуре или на языке хоста, но основная идея заключается в следующем:

string sqlCmd = "SELECT " 
    + (SELECT (FIELDS_NAME_QUERY(UserID='#') 
       FROM USER_PRIVILEGES 
       WHERE userid='#') 
    + FROM data d 
execute sqlCmd

«выполнить», что означает то, что у вас есть для выполнения строкикак команда sql.


еще после уточнения по OP:

Хорошо, вам нужна функция sql, которая возвращает строку, которая выглядит как "colname1, colname2, ...".Следующее напоминает, как это будет выглядеть на сервере SQL.синтаксис
create function<br> FIELDS_NAME_QUERY (@userid int)<br> begin<br> select col1, col2, col3... INTO @col1priv, @col2priv, @col3priv FROM userPrivileges WHERE UserId = @UserId<br> declare @result varhcar(60)<br> set @result = ''<br> if (@col1priv = 1) @result = 'col1'<br> if (@col2priv = 1) @result = @result + ' ,col2'<br> if (@col3priv = 1) @result = @result + ' ,col3'<br> return @result<br> end

0 голосов
/ 30 декабря 2011

еще не пробовал, но что-то вроде этого должно работать

SELECT (SHOW COLUMNS FROM table WHERE expr) FROM data WHERE DataID = '#'

Проверьте этот пост для деталей - Как я могу получить имена столбцов из таблицы в Oracle?

Дайте нам знать, как вы решите это ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...