Не удалось преобразовать строку в Int32 - PullRequest
0 голосов
/ 01 марта 2019

Я разработчик asp.net.Я выполнял хранимую процедуру и получал счетчик столбцов с помощью метода ExecuteScaler.но безуспешно, это дает ошибку приведения типа, как это:

у меня есть этот код:

 protected int isValidUser()
        {
            try
            {
                return Convert.ToInt32(Mysql.ExecuteScalar("Support_UserLogin", AppGlobal.UserName, AppGlobal.Password));
            }
            catch (Exception ex)
            {
                AppGlobal.QLog.Enqueue(new clsLogType() { Message = System.Reflection.MethodBase.GetCurrentMethod().Name, ex = ex, logType = LogType.Error });
                return 0 ;
            }
        }

это мой сохраненный код процедуры:

USE [NEWBULKSMS]
GO
/****** Object:  StoredProcedure [dbo].[Support_UserLogin]    Script Date: 01/03/2019 2:12:10 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[Support_UserLogin] 

    @Username   varchar(100),
    @Password varchar(100)

AS
BEGIN

    BEGIN TRY

    SET NOCOUNT ON;

    -- Insert statements for procedure here
    select count(*) from users  where strUserName = @Username and strPassword = @password;

    END TRY
    BEGIN CATCH
        EXEC [dbo].[usp_LogErrorHistory];

        DECLARE @err VARCHAR(MAX)
        SELECT @err = ERROR_MESSAGE()

        RAISERROR('Error while getting : [dbo].[Support_UserLogin]', 16, 1, @err)
    END CATCH

END

после того, как это сделаноя получаю сообщение об ошибке типа Failed to convert string to Int32

что не так с этим ....

--------------------------------- Обновлено -------------------------------------

Когда запускается этот сохраненный процесс в SSMS, возвращается значение 1 в столбце без имени.

USE [NEWBULKSMS]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[Support_UserLogin]
        @Username = N'shalingajjar',
        @Password = N'shalsoft$3433'

SELECT  'Return Value' = @return_value

GO

------------------------------------ Обновлено ------------------------------------

здесь я включаю код ExecuteScaler подробнее

#region ExecuteScalar

    public static object ExecuteScalar(CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    {
        using (SqlConnection cn = new SqlConnection(ConString))
        {
            cn.Open();
            return ExecuteScalar(cn, commandType, commandText, commandParameters);
        }
    }
    public static object ExecuteScalar(string spName, params object[] parameterValues)
    {
        if ((parameterValues != null) && (parameterValues.Length > 0))
        {
            SqlParameter[] commandParameters = GetSpParameterSet(spName);
            AssignParameterValues(commandParameters, parameterValues);
            return ExecuteScalar(CommandType.StoredProcedure, spName, commandParameters);
        }
        else
        {
            return ExecuteScalar(CommandType.StoredProcedure, spName);
        }
    }
    public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    {
        SqlCommand cmd = new SqlCommand();
        PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);
        object retval = cmd.ExecuteScalar();
        cmd.Parameters.Clear();
        return retval;

    }

    private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters)
    {
        if(connection.State != ConnectionState.Open)
        {
            connection.Open();
        }

        command.Connection = connection;

        command.CommandText = commandText;
        if (transaction != null)
        {
            command.Transaction = transaction;
        }
        command.CommandType = commandType;

        if (commandParameters != null)
        {
            AttachParameters(command, commandParameters);
        }

        return;
    }
    private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters)
    {
        foreach (SqlParameter p in commandParameters)
        {
            if ((p.Direction == ParameterDirection.InputOutput) && (p.Value == null))
            {
                p.Value = DBNull.Value;
            }
            command.Parameters.Add(p);
        }
    }
    private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
    {
        if ((commandParameters == null) || (parameterValues == null))
        {
            return;
        }
        if (commandParameters.Length < parameterValues.Length)
        {
            throw new ArgumentException("Parameter count does not match Parameter Value count.");
        }

        for (int i = 0, j = commandParameters.Length; i < j; i++)
        {
            if (i < parameterValues.Length)
            {
                if (commandParameters[i].DbType.ToString() == "String")
                    commandParameters[i].Value = (parameterValues[i] == null ? "" : parameterValues[i]);
                else
                    commandParameters[i].Value = parameterValues[i];
            }
            else
            {
                break;
            }

        }
    }

    #endregion

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

ExecuteScalar возвращает первый столбец первой строки в первом наборе результатов.https://dev.mysql.com/doc/dev/connector-net/8.0/html/M_MySql_Data_MySqlClient_MySqlCommand_ExecuteScalar.htm

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

Способ выполнения хранимого процесса в SSMS вернет нечто отличное от того, что вы ожидаете от своего кода .Net.Я ожидал увидеть 1, возвращенное без имени столбца (то есть ваш счетчик выбора (*) ...), и 0, возвращенное с именем Возвращаемое значение.

Наконец, если сохраненный процесс делает именно то, что выотправил

  1. Будет ли разумнее использовать функцию вместо этого?Вы можете вернуть свой счет (*) там.
  2. Вас действительно волнует количество записей там?будет ли больше смысла делать что-то вроде «если существует (выберите 1 из пользователей, где strUserName = @Username и strPassword = @password) вернет 1», это будет более эффективным.
0 голосов
/ 01 марта 2019

Недостаточно репутации, чтобы комментировать.

Попробуйте изменить свой код на что-то вроде этого:

protected int isValidUser()
{
    try
    {
        var returnedValue = Mysql.ExecuteScalar("Support_UserLogin", AppGlobal.UserName, AppGlobal.Password);
        Console.Writeline(returnedValue);//this line is to view what was actually returned.
        return Convert.ToInt32(returnedValue );
    }
    catch (Exception ex)
    {
        AppGlobal.QLog.Enqueue(new clsLogType() { Message = System.Reflection.MethodBase.GetCurrentMethod().Name, ex = ex, logType = LogType.Error });
        return 0 ;
    }
}

Если вы отладите это, вы можете увидеть более ясно, почему значение не являетсядопустимое целое число (это может быть long или что-то еще)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...