In my MariaDB database, I have three tables, Users
, Workers
and Admins
, where the Users
table has the column ID
as primary key. Workers
and Admins
use a Users.ID
as foreign (and primary) key. Users can either be Workers or Admins, not both. How can I find out, using a Users.ID
, whether they are Workers or Admins?
I've tried this function:
CREATE FUNCTION workeroradmin(id INT)
RETURNS VARCHAR(20)
BEGIN
DECLARE type VARCHAR(20)
IF (SELECT COUNT(*) FROM Workers WHERE ID = id) = 1
THEN
SET type='Worker'
ELSEIF (SELECT COUNT(*) FROM Admins WHERE ID = id) = 1
THEN
SET type='Admin'
RETURN type;
END;
But this would just give me SQL syntax errors. Is a function the way to go here or is a simple IF clause enough?
Are you sure that one user cannot be Worker AND Admin simultaneously?
I'd do something like this instead:
SELECT
Users.Id
, IF(Workers.Id IS NOT NULL, 1, 0) AS IsWorker
, IF(Admins.Id IS NOT NULL, 1, 0) AS IsAdmin
FROM
Users
LEFT JOIN Workers ON (Workers.Id = Users.Id)
LEFT JOIN Admins ON (Admins.Id = Users.Id)
WHERE
...
;
You can do the same using sub-query instead of LEFT JOIN.
If you realy would like to use your way, you can do something like this:
DELIMITER $$
CREATE FUNCTION `workeroradmin`(`_id` INT)
RETURNS varchar(20)
LANGUAGE SQL
BEGIN
IF((SELECT `Id` FROM `Workers` WHERE `Id` = _id) IS NOT NULL) THEN
SET @result = 'Worker';
ELSEIF((SELECT `Id` FROM `Admins` WHERE `Id` = _id) IS NOT NULL) THEN
SET @result = 'Admin';
END IF;
RETURN @result;
END$$
DELIMITER ;
I would not use COUNT just to check existence as this is sub-optimal, Id would to the same.
I don't know if this solution is overkill to you but you can actually enforce a user to be either a worker "xor" an admin. This solution works starting on MariaDB 10.2.1.
You can use composite primary keys and CHECK
constraints (that actually work in MariaDB 10.2.1 and newer).
For example:
create table users (
id int not null,
type int not null check (type in (1, 2)),
name varchar(20),
primary key (id, type)
);
create table workers (
id int not null,
type int not null check (type = 1),
position varchar(20),
primary key (id, type),
foreign key (id, type) references users (id, type)
);
create table admins (
id int not null,
type int not null check (type = 2),
server varchar(20),
primary key (id, type),
foreign key (id, type) references users (id, type)
);
insert into users (id, type, name) values (100, 1, 'Anne'); -- worker
insert into workers (id, type, position) values (100, 1, 'Manager');
insert into users (id, type, name) values (105, 2, 'Tom'); -- admin
insert into admins (id, type, server) values (105, 2, 'server1');
insert into workers (id, type, position) values (105, 2, 'Programmer'); -- fails!
See? The last insert fails, so Tom cannot be an admin and a worker at the same time, and this is enforced at the database level, not your code.
Then, how do you know if it's an admin or a worker? Just look at the column type
in the table users
. Much simpler and cheap.
Cheers!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.