Предупреждение: Ваши вопросы говорят о том, что вы храните пароли как обычный текст в вашей базе данных.
Это серьезная угроза безопасности . Пароли должны храниться как соленый хеш , без шифрования и никогда не в виде простого текста (Спасибо Себастьяну Броше за то, что обратил на это внимание).
Сказав это, вот ответ на ваш вопрос:
Один из способов сделать это - разбить строку на отдельные символы, а затем просто запросить с помощью count
:
DECLARE @str nvarchar(30) = 'shS46@($8jr4';
With N10 AS
(
SELECT N
FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9))V(N)
), Tally AS
(
SELECT TOP(LEN(@str)) ROW_NUMBER() OVER(ORDER BY @@SPID) As N
FROM N10 ten
CROSS JOIN N10 hundred
-- Passwords are usually 10-20 chars max length.
-- If you need more you can add another cross join to get 1000.
), Chars AS
(
SELECT SUBSTRING(@str, N, 1) As C
FROM Tally
)
SELECT COUNT(*)
FROM Chars
WHERE C NOT LIKE '%[A-Za-z0-9]%'
Конечно, если у вас уже есть таблица подсчета, вам не нужно создавать счет на лету:
With Chars AS
(
SELECT SUBSTRING(@str, N, 1) As C
FROM Tally
WHERE N <= LEN(@str)
)
SELECT COUNT(*)
FROM Chars
WHERE C NOT LIKE '%[A-Za-z0-9]%'
И полная версия, которая использует таблицу входа в систему со столбцом пароля:
(и еще один способ заполнить подсчет на лету)
CREATE TABLE Login
(
Password nvarchar(20)
);
INSERT INTO Login (Password) VALUES
('n9$%^Usj4jjr'),
('Nehj47$%^$'),
('MNAtokay543^A36#$^#%'),
('(*&^#$^dfh$%&'),
('$%^h345nfs54y');
With Tally AS
(
SELECT TOP 20 ROW_NUMBER() OVER(ORDER BY @@SPID) As N
FROM sys.objects
), Chars AS
(
SELECT Password, SUBSTRING(Password, N, 1) As C
FROM Login
CROSS JOIN Tally
WHERE N <= LEN(Password)
)
SELECT Password
FROM Chars
GROUP BY Password
HAVING COUNT(CASE WHEN C NOT LIKE '%[A-Za-z0-9]%' THEN 1 END) > 5
Результаты:
Password
(*&^#$^dfh$%&
MNAtokay543^A36#$^#%