2009-07-14 1 views
2

Im имея эту функцию, чтобы определить погоду пользователь существует в базе данных или незначения SQL Возвращенные в Delphi через ADO

DM мой DataModule

AQ_LOGIN в ADOQuery

Бену мой стол, наполненный Пользователи и их Пароль

вот код:

function UserCheckExist(Login, pw: string): boolean; 
begin 
    with DM do 
    begin 
     AQ_LOGIN.Close; 
     AQ_LOGIN.SQL.Clear; 
     AQ_LOGIN.SQL.Add('select BLOGIN from BENU where BLOGIN = ''Login'' AND BPW = ''pw'''); 
     AQ_LOGIN.Open; 
    end; 
end; 

Мой вопрос сейчас: Как я могу заставить функцию возвращать истинную или ложную погоду? Пользователь с соответствующим паролем существует?

Заранее спасибо.

ответ

3
function UserCheckExist(Login, pw: string): boolean; 
begin 
    with DM do 
    begin 
     AQ_LOGIN.Close; 
     AQ_LOGIN.SQL.Clear; 
     AQ_LOGIN.SQL.Add('select BLOGIN from BENU where BLOGIN = ''Login'' AND BPW = ''pw'''); 
     AQ_LOGIN.Open; 
     Result := (AQ_LOGIN.RecordCount > 0); 
     AQ_LOGIN.Close; 
    end; 
end; 
3

Использование:

function UserCheckExist(Login, pw: string): boolean; 
begin 
    with DM do 
    begin 
    AQ_LOGIN.Close; 
    AQ_LOGIN.SQL.Clear; 
    {Use COUNT in select to determine if user exists} 
    AQ_LOGIN.SQL.Add('select count(BLOGIN) from BENU where BLOGIN = ''Login'' AND BPW 'pw'''); 
    AQ_LOGIN.Open; 
    Result:= (AQ_LOGIN.Fields[0].AsInteger = 1); 
    AQ_LOGIN.Close; 
end; 

конец;

Два изменения: во-первых, не выбирайте имя пользователя, вы должны скорее считать значения - COUNT всегда возвращает что-то, если пользователь не существует - он будет равен нулю. Во-вторых: Вычислить результат, используя сравнение, если count (Поля [0], так как больше не существует) равна единице. Если количество таких записей будет отличаться от одного, эта функция вернет false.

+1

+1 от меня, как вы разместили довольно-очень то, что я собирался поставить. Тем не менее, я бы использовал параметры вместо конкатенации строковых вводов - а также, поскольку размещенный код стоит (в вопросе и в других ответах) - на самом деле он не работает, конечно? :-) – robsoft

+0

@robsoft: Я думаю, что этот код нуждается в РЕАЛЬНОМ рефакторинге ... – smok1

+0

@ smok1 - действительно, и я думаю, его код просто сбивает с толку, потому что кажется, что он все еще изо всех сил пытается заставить тест работать. :-( – robsoft

8

Я бы пошел с ответом smok1 (я просто публиковал что-то вроде этого), но я бы оценивал ваши входы;

 
AQ_LOGIN.SQL.Add('select count(*) from BENU where BLOGIN=:login and BPW=:pw'); 
AQ_LOGIN.Parameters.ParamByName('login').AsString:=login; 
AQ_LOGIN.Parameters.ParamByName('pw').AsString:=pw; 

then as smok1 - открыть набор данных и посмотреть на значение возвращаемого счета.

NB - не имеют Дельфи ADO компонент под рукой, но 99,9% уверен, что это синтаксис :-)

редактировать: один из преимуществ использования параметров, как это то, что вам не нужно будет дезинфицировать ваш входные строки (для таких вещей, как кавычки) - компонент знает, что делать с вашими строками. Вы не ожидали бы иметь имя пользователя с одной цитатой, но у вас может быть пароль с одним. :-)

+1

+1 Использование параметров также намного безопаснее. Ввод данных, введенных пользователем. ПРЯМО в SQL-запрос допускает злоупотребление. Если это разрешено, то сложный пользователь может изменить поведение запроса за пределами того, что Предположим, например, используя этот пример, можно обойти логин, введя следующее в поле пароля «или bpw>». Используя предлагаемые параметры, теперь разрешите это сделать. – skamradt

1

Вы можете проверить Eof.

function UserCheckExist(Login, pw: string): boolean; 
begin  
    with DM do  
    begin   
    AQ_LOGIN.Close;   
    AQ_LOGIN.SQL.Clear;   
    AQ_LOGIN.SQL.Add('select BLOGIN from BENU where BLOGIN = ' + QuotedStr(Login) + ' AND BPW = ' + QuotedStr(pw));   
    AQ_LOGIN.Open;   
    Result := (not AQ_Login.Eof); 
    AQ_LOGIN.Close;  
    end; 
end; 
+0

Так что это значит? Eof = Конец файла? – Acron

+0

@ pr0wl - от справки: Test Eof (конец файла), чтобы определить, является ли активная запись в наборе данных последней записью. Если Eof истинно, текущая запись однозначно является последней строкой в dataset. Eof верен, когда приложение: Открывает пустой набор данных. (...) – smok1

+0

Да, EOF = Конец файла. В этом случае, если пользователь существует, вы хотите вернуть True, поэтому, когда EOF является ложным, запись (записи) была возвращена и пользователь существует. Если EOF True, пользователь не существует. –

0

Я добавил еще одну проверку, погода активна. Но он не работает нормально.

function UserCheck(Login, pw: string): boolean; 
    begin 
    with DM do 
    begin 
     AQ_LOGIN.Close; 
     AQ_LOGIN.SQL.Clear; 
     AQ_LOGIN.SQL.Add('select COUNT(*) from BENU where BLOGIN = ''Login'' AND BPW = ''pw'' AND AKTIV = 1'); 
     AQ_LOGIN.Open; 
     Result := (AQ_LOGIN.RecordCount > 0); 
     AQ_LOGIN.Close; 
    end; 
end; 

Здесь я использую функцию:

procedure TBenu_Login_Form.btnLoginClick(Sender: TObject); 
    var pwhashed: string; 
    begin 
    pwhashed := MD5Print(MD5String(edtBPass.Text)); 
    if UserCheck(meBLogin.Text, pwhashed) then 
     ShowMessage('User exists, Password is fine and active!') 
    else 
     ShowMessage('User does not exist, Password is wrong or not active!'); 
    end; 

хотел бы знать, почему это не работает, как intendet. Он всегда возвращает значение UserCheck true, а не false, когда я вхожу в не существующее имя пользователя.

+0

Beacause select COUNT (*) будет ВСЕГДА возвращать одну запись - одну запись с количеством записей в datatable. Используйте либо шахтное решение, либо не используйте их. – smok1

+1

Recordcount всегда будет возвращать 1 в этом запросе - вы должны тестировать значение результата, а не количество возвращаемых строк. Измените свой тест на Result: = (AQ_LOGIN.Fields [0] .AsInteger> 0); и все должно быть в порядке. И сделайте что-нибудь в этих строках - вы однажды поймаете, просто соедините свой вклад в SQL! :-) – robsoft

+0

Я использовал AQ_LOGIN.SQL.Add ('select count (BLOGIN) из BENU, где BLOGIN =' 'Login' 'AND BPW =' 'pw' ''); все еще, это не работает – Acron

0

Поскольку вы используете компонент adoquery без подключения, я предполагаю, что база данных находится в системе или в связанной сети. Адотируемый компонент так же безопасен, хотя люди всегда думают, что только sql будет работать .... используйте либо функцию adotable.locate, либо adoquery.locate, хотя поля таблиц нужно будет извлечь, а затем до того, как вы сделаете ее небезопасной.Функция locate уже предотвращает инъекцию с ее параметрами и возвращает только логическое значение, основанное на том, если оно найдено. Может быть, небезопасно, некоторые скажут, я не знаю вашего приложения, но его гораздо быстрее.