Укажите пары хостов пользователей, которые будут исключены из результатов MySQL. - PullRequest
1 голос
/ 06 октября 2019

Данные для работы:

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

Iхотите иметь возможность предоставлять несколько пар пользователь: хост (известные допустимые учетные данные) и возвращать результаты, которые не совпадают, поэтому возвращайте только подозрительные / незаконные учетные данные в результатах запроса.

Я создал скрипку https://www.db -fiddle.com / f / xb7dWXbkokHGbcPdzR7BUa / 4 Надеюсь, вы увидите, куда я иду с этим.

Ответы [ 2 ]

1 голос
/ 07 октября 2019

Исходя из того, что я мог понять из вашего постановления проблемы, вам нужно будет использовать несколько строковых операций для удовлетворения ваших условий (пояснение в комментариях ниже):

Запрос

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    |

Посмотреть на БД Fiddle

Предупреждение: Запрос выше не будет работать, если в списке @Usernames нет пользователя. Для краткости я избегал усложнять условия, чтобы справиться с этим. Более того, я сомневаюсь, что в вашем практическом случае вы бы столкнулись с ситуацией, когда в списке нет пользователя.

0 голосов
/ 14 октября 2019

Эта конструкция работает (но неэффективно для больших таблиц):

WHERE (user, host) NOT IN ( ('u1', 'h1'), ('u2', 'h2), ... )

Для дальнейшего обсуждения см. "Конструктор строки".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...