Форум: "Базы";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];
ВнизКак узнать если селект в процедуре нашел запись или нет ? Найти похожие ветки
← →
john (2005-10-02 18:47) [0]например
CREATE PROCEDURE LOGIN (
I_LOGIN VARCHAR(25),
I_PASSWORD VARCHAR(255))
RETURNS (
RESULT INTEGER,
O_ERR VARCHAR(255))
AS
DECLARE VARIABLE V_PSWD VARCHAR(255);
BEGIN
result = 0;
SELECT password FROM users
WHERE login = :i_login
INTO v_pswd;
IF (i_password = v_pswd) THEN
result = 1;
ELSE
o_err = "Invalid password.";
END
если селект не нашел запись то я хочу возвратить ошибку что нету такого узера.
база - Firebird 1.5
← →
msguns © (2005-10-02 19:14) [1]хм.. А зачем вообще это надо серверу ? Пусть прога-"клиент" сама определяет, что делать, если нд пуст. Ведь не исключено, что в некоторых случаях такой результат (нет записей) вполне имеет смысл
← →
Deniz © (2005-10-03 06:11) [2]
result = 0;
o_err = "";
if (exists(select 1 from users where login=:i_login and password=:i_password)) then
result = 1;
else
o_err = "Invalid password or user name.";
suspend;
или
result = 0;
SELECT password FROM users WHERE login = :i_login INTO v_pswd;
IF (v_pswd is null) THEN
o_err = "Нету такого юзера.";
else
IF (i_password = v_pswd) THEN
result = 1;
ELSE
o_err = "Invalid password.";
END
END
suspend;
← →
Desdechado © (2005-10-03 11:03) [3]2 Deniz
SUSPEND тут лишний (а по LangRef - вредный), т.к. возвращается не набор данных, а 2 значения в параметрах.
Автору
Я бы поднимал EXCEPTION
← →
Sergey13 © (2005-10-03 11:16) [4]А зачем вообще переписывать ЛОГИН? И как отработает эта процедура, если юзер еще не законнектился?
← →
john (2005-10-03 22:49) [5]Deniz © (03.10.05 06:11) [2]
CREATE PROCEDURE LOGIN (
I_LOGIN VARCHAR(25),
I_PASSWORD VARCHAR(255))
RETURNS (
RESULT INTEGER,
O_ERR VARCHAR(255))
AS
DECLARE VARIABLE V_PSWD VARCHAR(255);
BEGIN
result = 0;
SELECT password FROM users
WHERE login = :i_login
INTO v_pswd;
IF (v_pswd IS NULL) THEN
o_err = "Invalid user name";
ELSE
IF (i_password = v_pswd) THEN
result = 1;
ELSE
o_err = "Invalid password.";
SUSPEND;
END
однако не исключено что поле password действительно равно NULL и тогда процедура работает не совсем корректно.
То есть, чтобы сделать это корректно нужно еще сделать запрос на предмет существования такой записи, как вы и предложили...
В оракле это просто:
BEGIN
SELECT ...
EXCEPTION
WHEN no_data_found THEN
...
END;
Думал, что в Firebird можно сделать что-то аналогичное.
← →
Deniz © (2005-10-04 07:03) [6]> Desdechado © (03.10.05 11:03) [3]
>
> 2 Deniz
> SUSPEND тут лишний (а по LangRef - вредный), т.к. возвращается не набор данных, а 2 значения в параметрах.
Вредность зависит от варианта вызова.
Если вызывать как select * from login(...) то suspend как раз необходим.
Да и при execute procedure login(...) особых проблем в данном случае не будет.
> john (03.10.05 22:49) [5]
>однако не исключено что поле password действительно равно NULL и тогда ...
Про это в условии ничего не было(обычно пароли null-ами не бывают). Доработать код не сложно, но если ты не хочешь сам подумать, то ... сожалею. Вариантов может быть много.
DECLARE VARIABLE V_PSWD VARCHAR(255);
declare variable cnt integer;
BEGIN
result = 0;
SELECT password, count(*) FROM users
WHERE login = :i_login
group by password
INTO :v_pswd, :cnt;
IF (cnt is null) THEN
o_err = "Invalid user name";
ELSE
IF (i_password = v_pswd) THEN
result = 1;
ELSE
o_err = "Invalid password.";
SUSPEND;
END
← →
john (2005-10-04 09:41) [7]Deniz © (04.10.05 07:03) [6]
> но если ты не хочешь сам подумать, то ... сожалею.
стараюсь по мере возможности :)
к сожалению не все так просто. Это всего лишь укороченный вариант процедуры, на самом деле там еще много проверок, паролей несколько, еще история паролей и др.
Но, во всяком случае, теперь понятно как работает single row SELECT в FB.
Так что вопрос закрывается.
С уважением.
← →
Desdechado © (2005-10-04 10:31) [8]> Вредность зависит от варианта вызова.
Не вижу смысла вызывать процедуру через SELECT, если она ВСЕГДА возвращает только 2 значения в одной "строке".
А про "execute procedure login(...) особых проблем не будет" - рекомендую еще раз перечитать Language Reference. Там черным по белому написано - ВРЕДНО. Хотя работать будет.
← →
Deniz © (2005-10-05 08:46) [9]> Desdechado © (04.10.05 10:31) [8]
> > Вредность зависит от варианта вызова.
> Не вижу смысла вызывать процедуру через SELECT, если она ВСЕГДА возвращает только 2 значения в одной "строке".
Читаем внимательно: http://www.ibase.ru/devinfo/ibstp.htm особенно резюме.
стр. 179 (SUSPEND)
...
If the procedure is used as an executable procedure in isql, for example,
EXECUTE PROCEDURE P;
then it will return 1, since the SUSPEND statement will terminate the procedure and return
the current value of r to the calling application. Since SUSPEND should not be used in
executable procedures, EXIT would be used instead, indicating that when the statement
is encountered, the procedure is exited.
Ну перечитал, и что там такого страшного, если мы понимаем как работает suspend? Тем более он (suspend) стоит в конце процедуры.
> Хотя работать будет.
Вот на этом хотелось бы поставить жирную точку в нашем диалоге.
← →
Desdechado © (2005-10-05 11:37) [10]кричать не стоит...
А стоит посмотреть на таблицу на стр. 178. И корректно перевести на русский слова "NOT RECOMMENDED" и "SUSPEND should not used". "Should not" - это смягченная форма запрещения.
А оговорки "если мы понимаем как работает suspend" и "если он стоит в конце" весьма кстати. Многие не понимают этого, а просто лепят suspend везде. Вот их и хотелось бы предостеречь.
А приведенная ссылка касается работы отдельных компонентов с отдельными версиями сервера, которые не у автора. И рекомендации обычно пишутся со словом ИМХО.
Добавлю еще от себя: сколько я ни использовать безSUSPENDных процедур, никогда на описанное в статье не нарывался. Хотя работал с IB5.6, IB.6.0, FB1.0, FB1.02, FB1.03, FB1.5х.
← →
Seg (2005-10-05 12:24) [11]В оракле это просто:
BEGIN
SELECT ...
EXCEPTION
WHEN no_data_found THEN
...
END;
Думал, что в Firebird можно сделать что-то аналогичное.
Речь вроде шла об IB6.
Хотя в Оракле действительно многое делается проще.
← →
Desdechado © (2005-10-05 12:47) [12]по поводу NO_DATA_FOUND я поступаю так:
1. присваиваю переменной заведомо отсутствующее в таблице значение
2. делаю выборку в переменную
3. если значение не изменилось, то данных не выбрано
← →
Seg (2005-10-05 13:02) [13]1. присваиваю переменной заведомо отсутствующее в таблице значение
Так ведь данные в таблице меняются и не факт, что кто-то из пользователей не сделает себе пароль, совпадающий с этим значением.
← →
Desdechado © (2005-10-05 13:12) [14]это может быть непечатный символ или даже группа таких
если бы пароль не был возможен NULL (что за глупость?), то еще проще
← →
Sergey13 © (2005-10-05 13:25) [15]А я опять повторю свой вопрос - нафига переписывать стандартный логин и как это исполнить до подключения к БД?
← →
Desdechado © (2005-10-05 13:53) [16]Sergey13 © (05.10.05 13:25) [15]
автор вопрос закрыл, так что мы уже не совсем по сабжу толчемся :)
а про логины-пароли: может, у него 2-уровневая проверка, где юзер не знает своего реального логина-пароля к БД, а только некий виртуальный, проверяемый в недоступном ему подключении автоматически программой через процедуру
← →
Sergey13 © (2005-10-05 13:57) [17]2 [16] Desdechado © (05.10.05 13:53)
>в недоступном ему подключении автоматически
SYSDBA masterkey в прогу зашиты что ли?
← →
Desdechado © (2005-10-05 15:34) [18]> SYSDBA masterkey в прогу зашиты что ли?
варианты разные бывают :)
На юзерской машине может какой-нибудь ини хранится, откуда считывается зашифрованный логин-пароль спецюзера с правами на запуск только этой процедуры. Программа запускается, подключается, спрашивает юзера его идентиф. данные и процедурой их проверяет, после чего переконнектится к БД с уже нормальными, но неизвестными юзеру логином-паролем.
← →
Deniz © (2005-10-06 07:06) [19]> Sergey13 © (05.10.05 13:25) [15]
Desdechado © (05.10.05 15:34) [18]
+
вполне может быть что-то более чем двух-звенное, например какой-нибудь web-форум с авторизацией.
← →
Deniz © (2005-10-06 07:14) [20]> Desdechado ©
Я конечно согласен, но мне просто не понравилось выражение
Desdechado © (03.10.05 11:03) [3]
> SUSPEND тут лишний ...
Как уже меня поправили, все это ИМХО.
Для автора: нужно бы детальнее описывать проблему в будущем, что бы люди могли помочь нормально, а не догадываться об условиях задачи.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.051 c