USE mysql;
DROP PROCEDURE IF EXISTS ShowUsers;
DELIMITER $
CREATE PROCEDURE `ShowUsers`(IN KnownUsers varchar(500), IN KnownHosts varchar(500))
BEGIN
SELECT
user,host
FROM
user
WHERE
NOT FIND_IN_SET(host, KnownHosts)
AND
NOT FIND_IN_SET(user, KnownUsers)
ORDER BY user, host ASC;
END $
DELIMITER ;
要使用的完整数据示例:
+-------------+-------------+
| user | host |
+-------------+-------------+
| knownuser1 | 192.168.1.5 |
| knownuser2 | 192.168.1.5 |
| unknownuser | 192.168.1.5 | # I want this result to show
| someuser1 | 192.168.1.6 |
| someuser2 | 192.168.1.6 |
| someuser3 | 192.168.1.6 |
| root | localhost |
+-------------+-------------+
我已经标记了要从运行过程中显示的结果,基本上,两个IN参数是已知用户,而已知主机应该是该数据库上有用户记录的主机。
像这样调用函数
# users and hostnames(ips) to match for exclusion from results.
SET @Usernames = 'knownuser1,knownuser2';
SET @Hostnames = '192.168.1.5';
CALL ShowUsers(@Usernames, @Hostnames);
预期结果:
+-------------+-------------+
| user | host |
+-------------+-------------+
| unknownuser | 192.168.1.5 | # I want this result to show
| someuser1 | 192.168.1.6 |
| someuser2 | 192.168.1.6 |
| someuser3 | 192.168.1.6 |
| root | localhost |
+-------------+-------------+
实际结果:
+-------------+-------------+
| user | host |
+-------------+-------------+
| someuser1 | 192.168.1.6 |
| someuser2 | 192.168.1.6 |
| someuser3 | 192.168.1.6 |
| root | localhost |
+-------------+-------------+
说明(关于该主题,但我想我应该澄清一下)我要执行此过程的原因,我有一个具有多个远程从属服务器的主服务器,从属服务器需要访问masters数据库,这意味着他们还必须具有“ root”访问权限,他们可以创建/重新配置自己的访问凭据。这样做的问题是,如果其中一台服务器遭到破坏,则几乎没有机会向基本所有数据库添加具有凭据的新用户。敞开并可以自由携带。
在进行初始配置后,我可以将从站锁定,然后手动打开门,运行更新,然后再次锁定它,这对于应用程序而言非常费力,并且实际上使该应用程序无用。
我现在要使用的想法是通过cron run脚本运行此过程,并检查未知的用户/主机,并将该从属服务器锁定在数据库之外,直到我接受或拒绝主应用程序中的用户为止。 / p>
答案 0 :(得分:1)
WHERE
子句中的条件是:
NOT FIND_IN_SET(host, KnownHosts) AND NOT FIND_IN_SET(user, KnownUsers)
等效于:
NOT (FIND_IN_SET(host, KnownHosts) OR FIND_IN_SET(user, KnownUsers))
这意味着您要排除以下行:
host
包含在KnownHosts
中,或者user
包含在KnownUsers
中。
对于您的示例数据,该行:
unknownuser | 192.168.1.5
将不会返回,因为host = '192.168.1.5'
(= KnownHosts
中包含了'192.168.1.5'
及其 。
如果这是您要应用的逻辑,则可以将逻辑运算符更改为OR
:
NOT FIND_IN_SET(host, KnownHosts) OR NOT FIND_IN_SET(user, KnownUsers)