Я создал функцию, которая теоретически должна возвращать true при успешной смене пароля и false - наоборот.
Функция определяется как:
CREATE OR REPLACE FUNCTION database."changePassword"(username character varying, newpassword character varying, oldpassword character varying) RETURNS boolean AS
$BODY$
UPDATE database.users SET hash = MD5($2) WHERE (username = $1 AND hash = MD5($3));
SELECT EXISTS(SELECT 1 FROM datsabase.users WHERE username = $1 AND hash = MD5($2))
$BODY$
LANGUAGE sql VOLATILE NOT LEAKPROOF
COST 100;
Проблема в том, что когда я вызываю такую функцию, как SELECT database."changePassword"('usrNm', 'newPassword', 'oldOne');
, сначала я получаю истинное значение, как и ожидалось, и значение в базе данных изменяется.
Когда я вызываю функцию снова (и снова и снова) с теми же параметрами, она также возвращает true, но этого не должно быть, поскольку сейчас пароль изменен, а старый пароль, отправленный через вызов функции, неверен.
Я делаю что-то неправильно?
Версия PostgreSQL - 9.3.1.
Я вызвал функцию из интерфейса pgAdmin и из PHP-скрипта, та же проблема.
2 ответа
Если вы хотите узнать, был ли изменен какой-либо пароль, вы можете просто вернуть специальную переменную FOUND
в такой функции plpgsql (упрощенная с вводом из @Pavel):
CREATE OR REPLACE FUNCTION database."changePassword"(
username character varying
,newpassword character varying
,oldpassword character varying
) RETURNS boolean AS
$func$
BEGIN
UPDATE database.users
SET hash = MD5($2)
WHERE username = $1
AND hash = MD5($3);
RETURN FOUND;
END
$func$
LANGUAGE plpgsql VOLATILE NOT LEAKPROOF;
Или, что проще, используйте предложение RETURNING
. Это также будет работать с простой функцией sql:
CREATE OR REPLACE FUNCTION database."changePassword"(
username character varying
,newpassword character varying
,oldpassword character varying
) RETURNS boolean AS
$func$
UPDATE database.users
SET hash = MD5($2)
WHERE username = $1
AND hash = MD5($3)
RETURNING TRUE;
$func$
LANGUAGE sql VOLATILE NOT LEAKPROOF;
Если ни одна строка не обновляется, ничего не возвращается. В противном случае вы получите TRUE
.
Возвращаемое значение функции является результатом оператора SELECT
. Результат верен, когда сохраненный хэш пользователя совпадает с хешем второго параметра (newpassword
). Когда пароль изменяется на новый пароль, эта проверка всегда проходит успешно, и функция возвращает истину для того же параметра, несмотря на то, что оператор обновления не обновляет ни одну строку после второго вызова. Вам следует изменить свою логику и вместо того, чтобы запрашивать подходящего пользователя и пароль, проверять, обновляется ли какая-либо строка или нет.
Похожие вопросы
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.