![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как узнать если селект в процедуре нашел запись или нет ? [D7, IB6.x]
john © (2005-10-02 18:47:00)например
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
Deniz (2005-10-06 07:14:00) [1]> Desdechado ©
Я конечно согласен, но мне просто не понравилось выражение
Desdechado © (03.10.05 11:03) [3]
> SUSPEND тутлишний ...
Как уже меня поправили, все это ИМХО.
Для автора: нужно бы детальнее описывать проблему в будущем, что бы люди могли помочь нормально, а не догадываться об условиях задачи.
Deniz (2005-10-06 07:06:00) [2]> Sergey13 © (05.10.05 13:25) [15]
Desdechado © (05.10.05 15:34) [18]
+
вполне может быть что-то более чем двух-звенное, например какой-нибудь web-форум с авторизацией.
Desdechado (2005-10-05 15:34:00) [3]> SYSDBA masterkey в прогу зашиты что ли?
варианты разные бывают :)
На юзерской машине может какой-нибудь ини хранится, откуда считывается зашифрованный логин-пароль спецюзера с правами на запуск только этой процедуры. Программа запускается, подключается, спрашивает юзера его идентиф. данные и процедурой их проверяет, после чего переконнектится к БД с уже нормальными, но неизвестными юзеру логином-паролем.
Sergey13 (2005-10-05 13:57:00) [4]2 [16] Desdechado © (05.10.05 13:53)
>в недоступном ему подключении автоматически
SYSDBA masterkey в прогу зашиты что ли?
Desdechado (2005-10-05 13:53:00) [5]Sergey13 © (05.10.05 13:25) [15]
автор вопрос закрыл, так что мы уже не совсем по сабжу толчемся :)
а про логины-пароли: может, у него 2-уровневая проверка, где юзер не знает своего реального логина-пароля к БД, а только некий виртуальный, проверяемый в недоступном ему подключении автоматически программой через процедуру
Sergey13 (2005-10-05 13:25:00) [6]А я опять повторю свой вопрос - нафига переписывать стандартный логин и как это исполнить до подключения к БД?
Desdechado (2005-10-05 13:12:00) [7]это может быть непечатный символ или даже группа таких
если бы пароль не был возможен NULL (что за глупость?), то еще проще
Seg (2005-10-05 13:02:00) [8]1. присваиваю переменной заведомо отсутствующее в таблице значение
Так ведь данные в таблице меняются и не факт, что кто-то из пользователей не сделает себе пароль, совпадающий с этим значением.
Desdechado (2005-10-05 12:47:00) [9]по поводу NO_DATA_FOUND я поступаю так:
1. присваиваю переменной заведомо отсутствующее в таблице значение
2. делаю выборку в переменную
3. если значение не изменилось, то данных не выбрано
Seg (2005-10-05 12:24:00) [10]В оракле это просто:
BEGIN
SELECT ...
EXCEPTION
WHEN no_data_found THEN
...
END;
Думал, что в Firebird можно сделать что-то аналогичное.
Речь вроде шла об IB6.
Хотя в Оракле действительно многое делается проще.
Desdechado (2005-10-05 11:37:00) [11]кричать не стоит...
А стоит посмотреть на таблицу на стр. 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х.
Deniz (2005-10-05 08:46:00) [12]> 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-04 10:31:00) [13]> Вредность зависит от варианта вызова.
Не вижу смысла вызывать процедуру через SELECT, если она ВСЕГДА возвращает только 2 значения в одной "строке".
А про "execute procedure login(...) особых проблем не будет" - рекомендую еще раз перечитать Language Reference. Там черным по белому написано - ВРЕДНО. Хотя работать будет.
john (2005-10-04 09:41:00) [14]Deniz © (04.10.05 07:03) [6]
> но если ты не хочешь сам подумать, то ... сожалею.
стараюсь по мере возможности :)
к сожалению не все так просто. Это всего лишь укороченный вариант процедуры, на самом деле там еще много проверок, паролей несколько, еще история паролей и др.
Но, во всяком случае, теперь понятно как работает single row SELECT в FB.
Так что вопрос закрывается.
С уважением.
Deniz (2005-10-04 07:03:00) [15]> 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-03 22:49:00) [16]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 можно сделать что-то аналогичное.
Sergey13 (2005-10-03 11:16:00) [17]А зачем вообще переписывать ЛОГИН? И как отработает эта процедура, если юзер еще не законнектился?
Desdechado (2005-10-03 11:03:00) [18]2 Deniz
SUSPEND тут лишний (а по LangRef - вредный), т.к. возвращается не набор данных, а 2 значения в параметрах.
Автору
Я бы поднимал EXCEPTION
Deniz (2005-10-03 06:11:00) [19]
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;
msguns (2005-10-02 19:14:00) [20]хм.. А зачем вообще это надо серверу ? Пусть прога-"клиент" сама определяет, что делать, если нд пуст. Ведь не исключено, что в некоторых случаях такой результат (нет записей) вполне имеет смысл