Я использую метод с хранимой процедурой, но он всегда возвращает false - PullRequest
0 голосов
/ 15 сентября 2018

Я использую метод bool с Visual Studio 2015 и SQL Server 2005.

Когда я передаю правильные данные и нажимаю loginButton, код всегда возвращает false из хранимой процедуры.

Это моя хранимая процедура в SQL Server 2005:

ALTER PROCEDURE [dbo].[UserCheckLoginDetails]
    (@IsLoginIdCorrect BIT OUTPUT,
     @IsPasswordCorrect BIT OUTPUT,
     @LoginID NVARCHAR(200),
     @Password NVARCHAR(20)
    )
AS
BEGIN
    SET @IsLoginIdCorrect = 0
    SET @IsPasswordCorrect = 0

    IF EXISTS (SELECT * FROM UserInfo 
               WHERE loginid = @LoginID AND password = @Password)
    BEGIN
        SET @IsLoginIdCorrect = 1
        SET @IsPasswordCorrect = 1
    END
    ELSE
        IF EXISTS (SELECT * FROM UserInfo WHERE loginid = @LoginID)
        BEGIN
            SET @IsLoginIdCorrect = 1
        END
END

Это мой метод, возвращающий True или False:

Private Sub GetIsUserLoginCorrect(IsLoginIdCorrect As Boolean, IsPasswordCorrect As Boolean)
    Using Conn As New SqlConnection(_SqlCon)
        Using cmd As New SqlCommand("UserCheckLoginDetails", Conn)
            cmd.CommandType = CommandType.StoredProcedure
            Conn.Open()

            'OutPut Parameters
            cmd.Parameters.Add("@IsLoginIdCorrect", SqlDbType.Bit).Direction = ParameterDirection.Output
            cmd.Parameters.Add("@IsPasswordCorrect", SqlDbType.Bit).Direction = ParameterDirection.Output

            'InPut Parameters
            cmd.Parameters.AddWithValue("@LoginID", LoginIDTextBox.Text)
            cmd.Parameters.AddWithValue("@Password", PasswordTextBox.Text)
            cmd.ExecuteNonQuery()

            ' Assign Parameters
            IsLoginIdCorrect = Convert.ToBoolean(cmd.Parameters("@IsLoginIdCorrect").Value)
            IsPasswordCorrect = Convert.ToBoolean(cmd.Parameters("@IsPasswordCorrect").Value)

        End Using
    End Using
End Sub

Это кнопка входаобработчик события click, даже когда я предоставляю правильные значения, он всегда возвращает false:

Private Sub LoginButton_Click(sender As Object, e As EventArgs) Handles LoginButton.Click
    Try
        Dim IsLoginIdCorrect, IsPasswordCorrect As Boolean
        GetIsUserLoginCorrect(IsLoginIdCorrect, IsPasswordCorrect)

        If IsLoginIdCorrect And IsPasswordCorrect = True Then
            Me.Hide()
            ' User Information
            DeshBoard.MainUserIdLabel.Text = Me.MainUserIdLabel.Text
            DeshBoard.UserNameLabel.Text = Me.UserNameLabel.Text
            DeshBoard.UserLoginIdLabel.Text = Me.UserLoginIdLabel.Text
            DeshBoard.UserLevelLabel.Text = Me.UserLevelLabel.Text
            'Organanization Information
            DeshBoard.MainOrgIDLabel.Text = Me.MainOrgIDLabel.Text
            DeshBoard.OrgNameLabel.Text = Me.OrgNameLabel.Text
            DeshBoard.OrgTelLabel.Text = Me.OrgTelLabel.Text
            DeshBoard.OrgEmailLabel.Text = Me.OrgEmailLabel.Text
            DeshBoard.OrgAddressLabel.Text = Me.OrgAddressLabel.Text
            DeshBoard.Show()
        Else
            If IsLoginIdCorrect = False Then
                MessageBox.Show("Login ID is not correct...!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                LoginIDTextBox.Clear()
                PasswordTextBox.Clear()
                LoginIDTextBox.Focus()
            Else
                MessageBox.Show("Password ID is not correct...!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
                PasswordTextBox.Clear()
                PasswordTextBox.Focus()
            End If
        End If

    Catch ex As ApplicationException
        MessageBox.Show("Error: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub

Большое спасибо.

Ответы [ 3 ]

0 голосов
/ 15 сентября 2018

Во-первых, метод может ссылаться на подпрограмму или функцию.Sub - это метод, который выполняет действие.Функция - это метод, который вычисляет или извлекает одно или несколько значений.

Подпрограмма не должна называться Getxxx, поскольку ее основное назначение не должно возвращать значение.

Следует использовать функциювернуть значения.Поскольку вы пытаетесь получить несколько значений, если вы используете 2017, я бы предложил вернуть именованный кортеж с двумя значениями, поскольку вы не хотите, я бы создал объект, который имеет значения, и возвратил бы его.

С другой стороны, вы действительно не можете определить разницу между неправильным паролем пользователя и неправильным паролем пользователя и неправильным паролем пользователя, поэтому вы не должны говорить кому-то, что можете.Вы просто говорите, что вход в систему неудачен, или неверная комбинация имени пользователя и пароля.

0 голосов
/ 22 сентября 2018

В вашем коде много неправильного.

Во-первых, почему вы используете так много кода SQL?Поправьте меня, если я ошибаюсь: вы пытаетесь создать систему входа в систему.Столько кода SQL или даже хранимой процедуры здесь бесполезны.Вы можете просто написать операторы SQL в своем коде, используя класс SqlCommand.Даже если вы используете оператор ALTER PROCEDURE, я могу с уверенностью сказать, что здесь все можно упростить.

Вы также используете ключевое слово Me.Это не C #, где использование this (как и Me в VB.Net) становится обязательным.Я предполагаю, что это Windows Forms Application, и если это так, то использование ключевого слова Me для доступа к его дочерним элементам не приведет к какому-либо другому, если он вообще не используется.

Следующее, что стоит упомянуть, это ваши Название Соглашения .Большинство или я должен сказать, что все ваши переменные имеют одинаковое имя.Например: IsLoginIdCorrect - используется как параметр метода, а также как переменная внутри метода.

Следующие проблемы заключаются в этих двух ложях:

Dim IsLoginIdCorrect, IsPasswordCorrect As Boolean
GetIsUserLoginCorrect(IsLoginIdCorrect, IsPasswordCorrect)

Вы передаетебулевы переменные до того, как им было присвоено какое-либо значение.Вам повезло, что это не C #, иначе это даже не скомпилируется.Передав логические переменные без присвоения какого-либо значения, они по умолчанию установят для них значения False.Таким образом, в буквальном смысле вы всегда передаете одно и то же значение, и в этом случае результат всегда будет одинаковым.

Следующая проблема - в вашем операторе If внутри вашего метода LoginButton_Click, известного как обработчик события clickB для LoginButton.Метод:

If IsLoginIdCorrect And IsPasswordCorrect = True Then

Операторы if, если они описаны простыми словами, означают: Если IsLoginIdCorrect и IsPasswordCorrect - истина, тогда продолжить ... .Так что в этом случае IsPasswordCorrect = True не сильно влияет.Однако это тоже не лучшая практика.Вам лучше следовать следующему правилу кодирования при использовании операторов If: операторы

 If (IsLoginIdCorrect = True AndAlso IsPasswordCorrect = True) Then

AndAlso оценивают каждую сторону так же, как оператор And.Разница в том, что он вернет False, если левая сторона (в данном случае IsLoginIdCorrect) вернет False.

. Следующие проблемы связаны с использованием ApplicationException.Я не понимаю, почему в эту эпоху вы используете этот класс!Этот класс обычно используется для создания и создания exception s.Вы можете просто использовать Exception вместо ApplicationException.

Ваш блок Try-Catch также кажется бесполезным.Все ваши коды внутри LoginButton_Click находятся в условиях If и выполняют очень простую операцию.Вряд ли когда-либо вообще возникнет какое-либо исключение.

Ваша логика, по большей части, нелогична (извините, если так выразиться).В вашем методе GetIsUserLoginCorrect вы устанавливаете для IsLoginIdCorrect и IsPasswordCorrect значение true или false, но это не имеет значения, поскольку они являются параметрами самого метода.Поэтому, даже если вы установите их значения, они будут сброшены при повторном вызове метода.Причина, по которой ByRef (согласно ответу Мэри) работает, заключается в том, что ByRef, вкратце, означает, что вы указываете на исходную переменную, которую вы передали (не на ее копию).

И, наконец,, решение, которое вы ищете ....

Хотя я вижу, что вы отметили ответ Мэри как ответ , я хотел бы помочь вам немного как-хорошо.

Во-первых, по возможности избавьтесь от хранимой процедуры, а также, если вы не используете ее где-либо еще.Я вижу, что вы используете условие If Exist внутри ваших SQL-запросов.На самом деле это хороший шаг, поскольку, согласно отчетам о производительности, проверка наличия данных в базе данных / таблице с использованием IF EXISTS дает самый быстрый вывод.Так что браво за это.Но если вы последуете моему совету и хотите отказаться от хранимой процедуры, то вам также нужно избавиться от оператора IF EXISTS.Скорее, вы можете просто использовать сам оператор SELECT, использовать метод ExecuteScalar класса SqlCommand, преобразовать его значение в Integer и проверить, является ли значение Integer 1 или нет.

Пример:

Dim cmd = New SqlCommand("SELECT COUNT(*) FROM UserInfo 
           WHERE loginid = @LoginID AND password = @Password")
Dim Exists = Convert.ToInt32(cmd.ExecuteScalar)
If Exists = 1 Then
''Code if data exists
End if

Обратите внимание, что я использовал Convert.ToInt32 здесь. Это исключит исключение null-reference, так как когда ExecuteScalar возвращает Null, оно будет преобразовано в 0 целочисленное значение.

Кроме того, почему вы используете GetIsUserLoginCorrect в качестве метода? Вы можете просто использовать его как функцию и возвращать необходимые значения. Поскольку вы возвращаете несколько значений, вы можете легко использовать тип Tuple в качестве типа вашей функции:

Private Function GetIsUserLoginCorrect(IsLoginIdCorrect As Boolean, IsPasswordCorrect As Boolean) As Tuple(of Boolean, Boolean)
....
....
return Tuple.Create(IsLoginIdCorrect, IsPasswordCorrect)
End Sub

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

 Dim IsLoginCorrect = GetIsUserLoginCorrect(first_boolean_variable,second_boolean_variable).Item1

  Dim IsPasswordCorrect = GetIsUserLoginCorrect(first_boolean_variable,second_boolean_variable).Item2

И последнее. Поскольку после скрытия основной формы отображается форма DeshBoard, обязательно вызовите MainForm.Close для события Dashboard формы Closing / Closed. Это обеспечит выход из приложения (если, конечно, у вас нет других планов для основной формы).

Надеюсь, этот ответ поможет вам.

0 голосов
/ 15 сентября 2018

Вам необходимо добавить ByRef к обоим аргументам в Sub GetIsUserLoginCorrect(). Чтобы продемонстрировать, попробуйте следующее с и без ByRef.

Private Sub ChangeBoolean(ByRef TorF As Boolean)
    TorF = True
End Sub
Private Sub OPCode2()
    Dim TorF As Boolean
    ChangeBoolean(TorF)
    Debug.Print(TorF.ToString) ' Result False without ByRef in ChangeBoolean
    'When ByRef is added result is True
End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...