你能告诉我 SqlDataReader i returns "System.Data.SqlClient.SqlException: 'Must declare the scalar variable "@idorder 有什么问题吗?

Can you tell whats wrong with the SqlDataReader i returns "System.Data.SqlClient.SqlException: 'Must declare the scalar variable "@idorder"

您好,因为我使用的是 using 语句,一旦它离开该语句,我的一次性连接就应该被处理,但是我的代码在我轮询数据库或获取信息的程序中的其他方法中是硬耦合的。因此,我决定添加 conn.Open() 和 conn.Close() 以避免超时错误或让多个数据库连接同时打开。我一直收到一个我不熟悉的错误,那就是:

System.Data.SqlClient.SqlException: '必须声明标量变量“@idorder”

与我的参数相关吗? 我做错了什么?

希望这对其他开发者有帮助 ADO.NET

public List<LogModel> GetLatestLogsOnEachSystemId(
       {
            List<string> _systemIds = new List<string>();
            _systemIds.Add("MA");
            _systemIds.Add("MB");
            _systemIds.Add("DY");
            _systemIds.Add("FA");

            using (SqlConnection conn = new SqlConnection(connString))
            {

                for (int i = 0; i < _systemIds.Count; i++)
                {
                    string systemId = _systemIds[i];

                    var querystring = "select top 1 * " +
                                        "from dbo.RadarMF30_log " +
                                            "where SYSTEM_ID = @id" +
                                                "order by Log_writing_time desc";


                    SqlCommand cmd = new SqlCommand(querystring, conn);
                    conn.Open();
                    cmd.Parameters.AddWithValue("@id", systemId);
                    SqlDataReader reader = cmd.ExecuteReader();
                    conn.Close();

                    var model = new LogModel
                    {
                        errorCode = reader.GetString(0),
                        errorMsg = reader.GetString(1),
 "select top 1 * " +
    "from dbo.RadarMF30_log " +
    "where SYSTEM_ID = @id" +
    "order by Log_writing_time desc";

@idorder之间没有space。

这就是为什么它认为有一个变量叫做 @idorder

因为@id和order之间没有space,所以认为参数名是@idorder,没有提供

var querystring = "select top 1 * " +
                                        "from dbo.RadarMF30_log " +
                                            "where SYSTEM_ID = @id " +
                                                "order by Log_writing_time desc";

var querystring = "select top 1 * " +
                                        "from dbo.RadarMF30_log " +
                                            "where SYSTEM_ID = @id" +
                                                " order by Log_writing_time desc";

JamesS 和 Yaman 已经解决了基本问题,但是:作为一般提示,如果您要在 C# 中使用 SQL,逐字字符串文字 (@"...") 避免几乎所有的白-space问题:

    const string query = @"
select top 1 *
from dbo.RadarMF30_log
where SYSTEM_ID = @id
order by Log_writing_time desc";

(注意:它不一定是 const - 只是......这里也不需要它是变量)

附带说明:这种场景也可以很好地与 "Dapper" 等工具一起使用,以避免与 ADO.NET 混淆:

    var model = conn.QuerySingle<LogModel>(@"
select top 1 *
from dbo.RadarMF30_log
where SYSTEM_ID = @id
order by Log_writing_time desc", new { id = systemId });

不再纠结于命令和参数的细微差别,或者担心您是否过早关闭了连接(仔细观察:您已经过早关闭了连接)。


附带说明:您可能还想避免 select * - 它可能导致两种不同类型的问题:

  • 带回大量不需要的大列(CLOB/BLOB 等),影响性能
  • 有时,只是有时,列的顺序不符合您的预期;如果您按 ordinal(代码中的 GetString(0) 等)进行绑定,这会产生巨大的影响;请注意 "Dapper" 由 name 绑定,所以这在这里不是什么大问题(假设名称匹配得很好,图书馆可以弄清楚你的意思)