MySqlCommand.ExecuteNonQuery()未填充MySqlParameter(s)

3npbholx  于 2023-02-18  发布在  Mysql
关注(0)|答案(2)|浏览(152)

背景:我正在重写我的ASP.NET应用程序-目前它使用MSSQL数据库,但我也需要支持MySQL(两者同时!)
大部分工作已经完成-我使用MySQL Connector/Net从C#(Visual Studio 2010)处理MySQL数据库-但我在某些SQL查询方面遇到了麻烦。

"SELECT @username=username FROM t_Users WHERE id=@id"

下面是我的代码:

public static int ExecuteSqlNonQuery(string i_szQuery)
{
    bool bConnectionWasOpen = false;
    AbstractConnection dbConnection = CMSSQLInstanceCreator.CreateConnection();            

    if(dbConnection.IsMySQL())
    {
        MySqlConnection aSqlConnection = dbConnection.GetMysConnection();
        try
        {
            if (aSqlConnection.State == System.Data.ConnectionState.Closed)
                aSqlConnection.Open();
            else
                if (aSqlConnection.State == System.Data.ConnectionState.Open)
                    bConnectionWasOpen = true;
                else
                    throw new ApplicationException("Connection not available!");

            List<MySqlParameter> aParameters1 = new List<MySqlParameter>();
            aParameters1.Add(new MySqlParameter("@username", MySqlDbType.VarString, 128));
            aParameters1.Add(new MySqlParameter("@id", MySqlDbType.Int32));
            aParameters1[0].Direction = System.Data.ParameterDirection.Output;                
            aParameters1[1].Direction = System.Data.ParameterDirection.Input;
            aParameters1[1].Value = (int)1;

            MySqlCommand aSqlCommand = new MySqlCommand(i_szQuery, aSqlConnection);
            aSqlCommand.CommandType = System.Data.CommandType.Text;
            aSqlCommand.CommandTimeout = 0;
            aSqlCommand.Parameters.Clear();
            aSqlCommand.Parameters.AddRange(aParameters1.ToArray());

            int iResult = aSqlCommand.ExecuteNonQuery();
            if(iResult <= 0)
                Debug.WriteLine("aResult <= 0: " + i_szQuery);
            return iResult;
        }
        catch (Exception ex)
        {
            throw new ApplicationException("Cannot execute query!\nReason: '" + ex.Message + "'", ex);
        }
        finally
        {
            if (!bConnectionWasOpen && aSqlConnection.State == System.Data.ConnectionState.Open)
                aSqlConnection.Close();
        }
    }
    else
    {
      //... almost the same for MS SQL
    }
}

问题是输出参数**@用户名**(系统.数据.参数方向.输出;)未使用查询中的值填充。
如果我使用其他查询-例如

UPDATE t_Users SET password=@new_password WHERE (password=@old_password AND id=@user)

一切都很好。
我不能返回标量,因为还有许多其他查询,如

SELECT @username=username, @is_blocked=is_blocked, @full_name=full_name, @must_change_pwd=must_change_pwd ...

返回很多值,我不想重写大部分代码。
看起来只有MySQL有问题,因为同样的代码可以很好地与MS SQL一起工作。
我应该使用什么来强制MySqlParameter从查询加载值?

4xrmg8kj

4xrmg8kj1#

您应该能够像这样读取输出的值

aSqlCommand.Parameters["@username"].Value
qaxu7uf2

qaxu7uf22#

这显然是MySql .Net连接器的一个缺点,请参见#75267。用连接器v6. 9. 7和MySql server 5. 5. 45测试了它。它仍然是坏的,错误报告-2014年12月-仍然开放。输出参数适用于存储过程,命令类型为StoredProcedure,和不适用于将输出参数作为选择的一部分进行赋值的SELECT语句;命令类型文本。
2023-02-16更新。几周前它在版本8.0.32中得到了修复。我通过将Connector/NET更新到8.0.32并使用NuGet包MySql.Data 8.0.32进行了测试。
文本类型的命令、输出参数和ExecuteNonQuery现在适用于以下情况:

SET @valNum:=(SELECT ValueNumber FROM `sky.application` WHERE Name='Agents')

然后可以通过输出参数检索值@valNum。
请注意,检索两个值并不像下面这样工作,尽管它在工作台中执行了这项工作:

SELECT @valNum:=ValueNumber, @instNum:=InstanceNumber FROM `sky.application` WHERE Name='Agents'

错误:在集合中找不到参数“valNum:=ValueNumber”。如果检索一个值,也会出现相同的错误。
幸运的是,以下语法有效:

SELECT ValueNumber, InstanceNumber INTO @valNum, @instNum FROM `sky.application` WHERE Name='Agents'

相关问题