#mysql
Вопрос:
Мне нужно написать инструкцию SELECT, которая возвращает:
Если номер карты содержит 16 цифр, он должен отображаться в следующем формате: XXXX-XXXX-XXXX-1234, где 1234-фактические последние четыре цифры номера.
Если номер карты содержит 15 цифр, он должен отображаться в следующем формате: XXXX-XXXXXX-X1234.
Я застрял! Любая помощь будет очень признательна! Я пытаюсь использовать, Если затем Заменить Или В случае, когда
Комментарии:
1. Какова ваша версия MySQL?
2. Если вы находитесь в США и храните номера кредитных карт, я надеюсь, что все ваши процессы соответствуют стандарту PCI. Вероятно, вам было бы лучше делегировать это сторонней службе обработки кредитных карт.
Ответ №1:
Если вы используете версию MySQL, которая поддерживает функцию окна, я предлагаю использовать REGEXP_REPLACE()
с LEFT()
и RIGHT()
. Вот пример:
SELECT cardnumber, CASE LENGTH(cardnumber)
WHEN 19 THEN
CONCAT(LEFT(REGEXP_REPLACE(cardnumber,'[0-9]','X'),15),
RIGHT(cardnumber,4))
WHEN 17 THEN
CONCAT(LEFT(REGEXP_REPLACE(cardnumber,'[0-9]','X'),13),
RIGHT(cardnumber,4))
END AS masked_cardnum
FROM testtable;
На этом примере данных:
CREATE TABLE testtable (
cardnumber VARCHAR(255));
INSERT INTO testtable VALUES
('1234-5678-9999-1234'),
('1234-567899-91234');
приведенный выше запрос вернет следующий результат:
номер карточки | masked_cardnum |
---|---|
1234-5678-9999-1234 | ХХХХ-ХХХХ-ХХХХ-1234 |
1234-567899-91234 | XXXX-XXXXXX-X1234 |
Или, возможно, даже не нужно заменять первые 12 или 11 цифр. Просто непосредственно добавьте последние 4 цифры с XXX..
помощью . Это должно работать на любой версии MySQL:
SELECT cardnumber,
CASE LENGTH(cardnumber)
WHEN 19 THEN CONCAT('XXXX-XXXX-XXXX-', RIGHT(cardnumber,4))
WHEN 17 THEN CONCAT('XXXX-XXXXXX-X', RIGHT(cardnumber,4))
END AS masked_cardnum
FROM testtable;
Комментарии:
1. Это выглядит правильно. Теперь я вижу, что неправильно понял вопрос. Речь идет о маскировке цифр, а не о добавлении дефисов.
Ответ №2:
Используйте LEFT()
, SUBSTR()
, RIGHT()
для извлечения частей строки и CONCAT_WS()
объединения их вместе с -
разделителем.
SELECT CASE LENGTH(cardnumber)
WHEN 16 THEN CONCAT_WS('-', LEFT(cardnumber, 4), SUBSTR(cardnumber, 5, 4), SUBSTR(cardnumber, 9, 4), RIGHT(cardnumber, 4))
WHEN 15 THEN CONCAT_WS('-', LEFT(cardnumber, 4), SUBSTR(cardnumber, 5, 6), RIGHT(cardnumber, 5)
END AS formatted_cardnumber
FROM yourTable
Комментарии:
1. Не
LENGTH(cardnumber)
будет ли это включать и эти тире? ОП сказал 16 цифр, но на самом деле это 19 символов, включая тире, верно? А другой-17 лет.2. Насколько я понимаю, длина не включает тире. Они добавляются для создания желаемых форматов.
3. Ах, я понимаю.. Мне, вероятно, также следует рассмотреть возможность этого.