要使用的数据:
+-------------+-------------+
| user | host |
+-------------+-------------+
| user1 | host1 | -
| user1 | ip1 | -
| user1 | host2 | *
| user2 | host2 | -
| user2 | ip2 | -
| unknown | unknown | +
| user1 | unknown | +
| unknown | host | +
+-------------+-------------+
表格右侧的符号为: - 不显示 |+ 显示未知 |* 因为用户只能连接到一台主机,除非我授权,在这种情况下,我也会向呼叫提供用户主机对,并且它不会显示。
无论如何,这就是我希望事情如何运作的方式。
这就是我在问题的帮助下所处的位置,由于现在有进一步的条件,需要提出一个新问题。
现行程序
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 ;
像这样调用过程
# known users and known hostnames or ips to match and exclude from results.
SET @Usernames = 'user1,user2';
SET @Hostnames = 'host1,host2,ip1,ip2'
CALL ShowUsers(@Usernames, @Hostnames);
预期结果:
+-------------+-------------+
| user | host |
+-------------+-------------+
| user1 | host2 | *
| unknown | unknown | +
| user1 | unknown | +
| unknown | host | +
+-------------+-------------+
我希望能够提供多个用户:主机对(已知的合法凭据(并返回不匹配的结果,因此在查询结果中仅返回可疑/非法凭据。
我创建了一个小提琴 https://www.db-fiddle.com/f/xb7dWXbkokHGbcPdzR7BUa/4 希望你能看到我要去哪里。
根据我从您的问题陈述中可以理解的任何内容,您将需要使用多个字符串操作来满足条件(在下面的内联注释中解释(:
查询
SELECT
`user`,`host`
FROM
tbl
WHERE
-- NOT condition to avoid returning one-to-one mapping between `user` and `host`
-- If `user` exist in the @Usernames, and the position of the
-- `user` matches with the position of the `host` in the @Hostnames
NOT (
FIND_IN_SET(`user`, @Usernames) > 0
-- Host and User are at same position in the lists
AND FIND_IN_SET(`user`, @Usernames) = FIND_IN_SET(`host`, @Hostnames)
)
AND
-- NOT condition to handle `host` at the end of @Hostnames list, where
-- there is no corresponding `user` mapped
NOT (
FIND_IN_SET(`host`, @Hostnames) > CHAR_LENGTH(@Usernames)
- CHAR_LENGTH(REPLACE(@Usernames, ',', ''))
+ 1
);
结果
| user | host |
| ------- | ------- |
| user1 | host2 |
| unknown | unknown |
| user1 | unknown |
| unknown | host |
在DB Fiddle上查看
警告:当@Usernames
列表中没有用户时,上述查询将不起作用。为了简洁起见,我避免使处理条件更复杂。此外,我怀疑在您的实际用例中,您是否会遇到列表中没有用户的情况。
此结构有效(但对于大型表效率不高(:
WHERE (user, host) NOT IN ( ('u1', 'h1'), ('u2', 'h2), ... )
有关进一步讨论,请参阅"行构造函数"。