当我点击"查看账单"按钮时,我试图显示列表账单.但我有个例外

System.Data.SqlClient.SqlException:‘’附近的语法不正确‘,’. 必须声明标量变量"@Checkin".

这是我的代码

SQL

ALTER PROC [dbo].[USP_GetListBillByDate] 
@checkIn date, @checkOut date 
AS 
BEGIN      
      SELECT t.name , b.totalPrice , DateCheckIn,DateCheckOut      
      FROM dbo.Bill AS b, dbo.TableFood AS t      
      WHERE DateCheckIn >= @checkIn AND DateCheckOut <= @checkOut AND b.status = 1      
      AND t.id = b.idTable 
END

BillDAO

public DataTable GetBillListByDate(DateTime checkIn, DateTime checkOut) 
{ 
   return DataProvider.Instance.ExecuteQuery("exec USP_GetListBillByDate @checkIn,@checkOut", new object[] {checkIn, checkOut}); 
}

AdminManager

void LoadDateTimePickerBill() 
{    
  DateTime today = DateTime.Now;    
  dtpFromDate.Value = new DateTime(today.Year, today.Month, 1);    
  dtpToDate.Value = dtpFromDate.Value.AddMonths(1).AddDays(-1); 
}
 void LoadListBillByDate(DateTime checkIn, DateTime checkOut) 
{
   dgvBill.DataSource = BillDAO.Instance.GetBillListByDate(checkIn, checkOut); 
} 
private void  btnViewBill_Click(object sender, EventArgs e) 
{    
   LoadListBillByDate(dtpFromDate.Value, dtpToDate.Value); 
}

DataProvider

public DataTable ExecuteQuery(string query, object[] parameter = null)
        {
            DataTable data = new DataTable();

            using (SqlConnection connection = new SqlConnection(connectionSTR))
            {
                connection.Open();

                SqlCommand command = new SqlCommand(query, connection);

                if (parameter != null)
                {
                    string[] listPara = query.Split(' ');
                    int i = 0;
                    foreach (string item in listPara)
                    {
                        if (item.Contains('@'))
                        {
                            command.Parameters.AddWithValue(item, parameter[i]);
                            i++;
                        }
                    }
                }

                SqlDataAdapter adapter = new SqlDataAdapter(command);

                adapter.Fill(data);

                connection.Close();
            }

            return data;
        }

我试图研究和修复,但这个例外仍然存在.

推荐答案

我不是"通用"数据访问函数的狂热粉丝.理想情况下,您应该根据您正在运行的查询来定制每个查询.这样,您就可以指定正确的参数类型.或者直接使用Dapper或其他ORM.

但你在这里的主要问题是:

  • 您应该使用CommandType.StoredProcedure来调用过程.
  • Even for regular queries, do not attempt to work out what the parameter names are. That's a recipe for disaster.
    Instead just pass them through from the outer function. You can use a string, object tuple.
  • 你还少了大约using
public DataTable ExecuteProcedure(string query, params (string name, object value) parameters = null) =>   // for text queries
    ExecuteQuery(query, CommandType.StoredProcedure, parameters);

public DataTable ExecuteProcedure(string query, params (string name, object value) parameters = null) =>   // for procedures
    ExecuteQuery(query, CommandType.Text, parameters);

public DataTable ExecuteQuery(string query, CommandType commandType,
    params (string name, object value) parameters = null)
{
    DataTable data = new DataTable();

    using SqlConnection connection = new SqlConnection(connectionSTR);
    connection.Open();
    using SqlCommand command = new SqlCommand(query, connection);
    command.CommandType = commandType;

    if (parameters != null)
    {
        foreach (var item in parameters)
        {
            command.Parameters.AddWithValue(item.name, item.value);
        }
    }

    using SqlDataAdapter adapter = new SqlDataAdapter(command);
    adapter.Fill(data);
    return data;
}

然后像这样调用它(注意,字符串中没有使用EXEC,也没有指定参数.这只是程序名称).

return DataProvider.Instance.ExecuteProcedure("dbo.USP_GetListBillByDate",
    ("@checkIn", checkIn),
    ("@checkOut", checkOut));

如果可能的话,考虑使用async个代码.

Csharp相关问答推荐

Blazor:计算值或保留为默认值

使用其可能实现的基类和接口的属性的方法

如何保持主摄像头视角保持一致?

CS0103 dlibdotnet和www.example.com facerect不在上下文中

MudBlazor—MudDataGrid—默认过滤器定义不允许用户修改基本过滤器

REST API端点中异步后台代码执行的类型

(乌龙)1&#比c#中的UL&#慢吗?

如何将不同类型的扩展参数的javascript函数转换成C#风格?

在静态模式下实例化配置

将字节转换为 struct 并返回

Swagger没有显示int?可以为空

具有以接口为其类型的属性的接口;类指定接口的实现,但无效

解决方案:延长ABP框架和ANGING OpenIddict中的令牌生命周期

EF Core:如何对关系属性进行建模?

如何在C#中从MongoDB IPipelineStageDefinition中获取聚合命令的字段/选项?

如何在单击按钮后多次异步更新标签

当要删除的子模型没有父模型的1:多属性时,如何告诉实体框架设置1:1 FK条目?

项目参考和方法签名问题

如何使ExecuteAsync异步运行

为什么我的UserControl没有加载到我的主窗口中?