【问题标题】:Failed to convert string to Int32无法将字符串转换为 Int32
【发布时间】:2019-07-23 06:41:14
【问题描述】:

我是 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

【问题讨论】:

  • 从 SSMS 执行过程时会发生什么?
  • @HoneyBadger 请查看我更新的部分。
  • var result = Convert.ToInt32(Mysql.ExecuteScalar("Support_UserLogin", AppGlobal.UserName, AppGlobal.Password)); 并检查result
  • @FortyTwo 由于 Convert.ToInt32 发生异常,没有结果显示任何值..
  • 执行var x = Mysql.ExecuteScalar(...);,然后检查x 的内容。另外,那个函数是什么,给我们看看它的代码。

标签: c# sql asp.net sql-server tsql


【解决方案1】:

没有足够的声望来发表评论。

试着把你的代码改成这样:

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 ;
    }
}

如果您进行调试,您可能会更清楚地看到为什么该值不是有效整数(可能是长整数或其他)

【讨论】:

  • @DavidG 在其中一个 cmets 中已经提到了这一点
  • 我试过你的代码。但是调试器在 var returnedValue 之后跳转到另一个位置,我找不到出现的结果。
【解决方案2】:

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. 您真的关心那里的记录数量吗?像“如果存在(从 strUserName = @Username 和 strPassword = @password 的用户中选择 1)返回 1”之类的事情会更有意义吗?它会更有效。

【讨论】:

  • 我遵循你的推荐代码。但我的 .net 代码仍然出错。
猜你喜欢
  • 1970-01-01
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-19
  • 2014-11-15
  • 1970-01-01
  • 2012-06-20
相关资源
最近更新 更多