您能告诉我SqlDataReader有什么问题吗,我返回“ System.Data.SqlClient.SqlException:'必须声明标量变量” @idorder”

时间:2020-02-11 11:09:47

标签: c# ado.net sqldatareader sqlconnection sqlcommand

您好,因为我使用了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),

3 个答案:

答案 0 :(得分:2)

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

@idorder之间没有空格。

这就是为什么它认为存在一个名为@idorder

的变量的原因

答案 1 :(得分:1)

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

    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 进行绑定,因此在这里并没有太大的问题(假设名称的匹配程度足以使库知道您的意思)

答案 2 :(得分:-1)

由于@id和order之间没有空格,它认为参数名称为@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";