2011-12-30 28 views
6

Tengo las siguientes tablas:SQL: Selección de columnas basadas en el valor de la columna de otra tabla

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 | 
+--------+------+------+------+ 

Mi cuestión en su forma más simple ¿no tiene nada que ver con la tabla Data pero acabo de explicar que de todos modos para que pueda estar haciendo lo contrario.

¿Cómo seleccionaría los nombres de columna de UserPrivileges según el valor? Para que pueda usar el resultado en otra consulta para seleccionar solo esas columnas.

Algo a lo largo de estas líneas:

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

O no me importa una mejor manera de administrar privilegios de usuario de columnas específicas.

Respuesta

6

La respuesta depende de sus requisitos para el resultado. ¿Necesita un resultado con un conjunto coherente de columnas, independientemente de los privilegios del usuario? Si es así, podría establecer los valores permitidos en nulo (o algún otro valor especial) utilizando una cláusula IF, por ejemplo,

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

Por supuesto, el "valor especial" podría ser un problema, ya que se necesita un valor eso nunca aparecería en los datos. Si necesita saber la diferencia entre un valor nulo porque el valor real es nulo vs. nulo porque es una columna prohibida, entonces no puede usar nulo.

Otro enfoque es que incluya simplemente el indicador de privilegio para cada columna que aparezca en el resultado, y permita que su lógica de negocio lo use para determinar qué valores son visibles para el usuario.

Un enfoque muy diferente tendría el resultado configurado para contener solo las columnas permitidas. En este caso, deberá construir su declaración SQL de forma dinámica. No sé si usted está haciendo esto en un procedimiento almacenado o en una lengua de acogida, pero la idea básica es algo como esto:

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

"ejecutar" significa todo lo que tiene disponible para ejecutar una cadena como una comando sql.


más después de la clarificación por OP:

Ok, es necesario función SQL que devuelve una cadena que se parece a "colname1, colname2, ...". Lo siguiente se asemeja a lo que se vería en el servidor sql. sintaxis
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

+0

El primero no es lo que estoy buscando, y el segundo. mi pregunta es ¿cómo escribirías 'FIELDS_NAME_QUERY()'? –

+0

¿Como un procedimiento/función almacenada, o en algún lenguaje de programación? –

+0

En SQL, ya sea como S.P o Func. –

0

no lo han intentado, pero algo como esto debería funcionar

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

Comprobar este post para más detalles - How can I get column names from a table in Oracle?

Háganos saber cómo resolver este ...

+0

Esto debería resolver su problema - [obtener los nombres de columna de la tabla que tiene un valor particular] (http://stackoverflow.com/questions/5631822/to-get-column-names-from-table-having-a-particular-value) –

+0

¿Alguien ha intentado esto, al menos en concepto? No uso mysql, pero me sorprendería mucho si funciona. Significaría que el resultado de mostrar columnas es polimórfico, y no creo que mysql tenga ese tipo de comportamiento OO. –

Cuestiones relacionadas