Rozważ następujące kwestie:
drop table if exists variousRights;
create table variousRights
( -- whitelist table of various privileges
id int auto_increment primary key,
rightType varchar(100) not null,
username varchar(100) not null
);
-- sample data below. For this exercise, all we care about is 'seeNullBirthDateRows'
-- but other data is inserted to ferret out troubles with strategy (too many rows returned)
insert variousRights (rightType,userName) values
('seeNullBirthDateRows','[email protected]'),
('seeNullBirthDateRows','[email protected]'),
('seeSecretIDs','[email protected]'),
('insertThing101','[email protected]');
drop table if exists employees;
create table employees
( id int auto_increment primary key,
empName varchar(100) not null,
birthDate date null
);
-- sample data inserted. One has a null for birthDate (empty as you say in the question)
insert employees(empName,birthDate) values
('John Smith',null),
('Sally Higgins','2016-02-07'),
('John Smith','2010-01-27');
Zapytanie:
select id,empName,birthDate
from employees
where birthDate is not null
union
select e.id,e.empName,e.birthDate
from employees e
cross join (select id from variousRights where rightType='seeNullBirthDateRows' and userName=current_user()) vr
where e.birthDate is null;
Zapytanie opiera się na sprzężeniu krzyżowym i Unii. Jeśli chodzi o związek, pierwsza część będzie taka sama dla wszystkich użytkowników:wszystkie wiersze od employees
z niezerowym dniem urodzin. Druga część unii zwróci wartości null dla użytkowników uprzywilejowanych w variousRights
stół, na którym wymyślasz swoje przywileje.
Oczywiście powyższe zapytanie można umieścić w widoku.
Zobacz stronę podręcznika mysql dla CURRENT_USER( ) funkcja.
Co do cross join
pomyśl o tym w ten sposób. Jest to produkt kartezjański. Ale tabela dołączyła (alias vr
) będzie miał 1 wiersz lub 0 z powrotem. To właśnie określa, czy uprzywilejowani użytkownicy widzą puste wiersze daty urodzenia.
Uwaga:Powyższe zostało przetestowane. Wydaje się działać dobrze.