我正在尝试设置连接到 MySQL 数据库 8.0 的 .NET 4.7.1 程序以使用最低权限运行。
.NET 程序使用 MySql.Data 进行连接。用户执行存储过程的最低权限通常仅为EXECUTE特权。这在 MySQL 工作台或命令行中工作得很好。
运行 .NET 程序时,会返回以下异常:System.Data.SqlTypes.SqlNullValueException:'数据为空。不能对 Null 值调用此方法或属性。
为了简单起见,我创建了一个非常小的演示程序来演示该问题。
数据库的设置:
CREATE DATABASE Spike;
CREATE PROCEDURE TestAccess()
BEGIN
END;
CREATE USER Spike@localhost IDENTIFIED WITH mysql_native_password BY 'sample';
GRANT EXECUTE ON PROCEDURE `TestAccess` TO Spike@localhost;
设置程序代码:
static void Main(string[] args)
{
using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database=Spike;uid=Spike;pwd=sample"))
{
conn.Open();
Console.WriteLine("Connection open");
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = "TestAccess";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
Console.WriteLine("Query executed");
}
Console.ReadKey();
}
事故发生在线路上cmd.ExecuteNonQuery();
崩溃时的堆栈很有趣,因为它似乎表明 information_schema 已被查询。记录所有语句时,我可以看到异常之前的最后一条语句是:
SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess'
我无法在 information_schema 上授予不同的权限,但我可以在存储过程上授予更多权限,以使更多信息在例程表中可见,但这感觉不对。授予 CREATE 和 ALTER 访问权限的简单测试也不起作用。
在不授予太多特权的情况下,我还能做些什么吗?
这似乎是 Connector/NET 中的一个错误,类似于错误 75301但有点不同。当它尝试确定过程的参数元数据时,它首先创建一个MySqlSchemaCollection
named Procedures
with all有关该过程的元数据。 (这是SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess'
您在日志中看到的查询。)
The Spike
用户帐户没有权限读取ROUTINE_DEFINITION
列,所以是这样NULL
。 Connector/NET 期望该字段为非 NULL 并抛出SqlNullValueException
尝试读取它时出现异常。
有两种解决方法:
1)第一个,你已经发现,是设置CheckParameters=False
在你的连接字符串中。这将禁用存储过程元数据的检索(避免崩溃),但如果您没有完全正确地获得参数的顺序和类型,则可能会导致调用其他存储过程时出现难以调试的问题。 (Connector/NET 无法再使用元数据为您映射它们。)
2) 切换到没有此错误的不同 ADO.NET MySQL 库:MySql连接器 on NuGet。它与 Connector/NET 高度兼容,执行速度更快,并且修复了很多问题已知的问题.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)