C# 潜在的日期格式问题 - System.Data.SqlClient.SqlException : 'Incorrect syntax near ' x'. '

标签 c# sql

该应用程序的目的是将Sql数据库中的数据选择到Windows窗体数据网格中。我实现了日期时间选择器的自定义格式,但仍然收到此错误。这是应用程序的属性和以下代码

Date Time Picker Properties

        private void startTimePicker1_MouseDown(object sender, MouseEventArgs e)
    {
        startTimePicker1.CustomFormat = "yyyy-MM-dd hh:mm:ss";
        startTimePicker1.Format = DateTimePickerFormat.Custom;
    }

    private void endTimePicker1_MouseDown(object sender, MouseEventArgs e)
    {
        endTimePicker1.CustomFormat = "yyyy-MM-dd hh:mm:ss";
        endTimePicker1.Format = DateTimePickerFormat.Custom;
    }

    private void loadBtn_Click(object sender, EventArgs e)
    {
        startTimePicker1.CustomFormat = "yyyy-MM-dd hh:mm:ss";
        startTimePicker1.Format = DateTimePickerFormat.Custom;

        endTimePicker1.CustomFormat = "yyyy-MM-dd hh:mm:ss";
        endTimePicker1.Format = DateTimePickerFormat.Custom;

        using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["DBName"].ConnectionString))
        {
            if(db.State==ConnectionState.Closed)
            {
                db.Open();
                string query = "select z.ItemName, x.Quantity, x.CreateDate" +
                                 " from Invoice_Itemized x inner join Inventory z on x.ItemNum = z.ItemNum inner join Departments d on z.Dept_ID = d.Dept_ID" +
                                $"where x.CreateDate BETWEEN '{ startTimePicker1 }' and '{ endTimePicker1 }' and d.SubType = 'TYPE'";

                liquorBindingSource.DataSource = db.Query<Liquor>(query, commandType: CommandType.Text);
            }
        }

查询在运行时输出以下值

select z.ItemName, x.Quantity, x.CreateDate from Invoice_Itemized x inner join Inventory z on x.ItemNum = z.ItemNum inner join Departments d on z.Dept_ID = d.Dept_IDwhere x.CreateDate BETWEEN 'System.Windows.Forms.DateTimePicker, Value: 7/18/2018 2:44:00 AM' and 'System.Windows.Forms.DateTimePicker, Value: 7/18/2018 4:19:01 AM' and d.SubType = 'TYPE'

这个查询在 SSMS 中成功执行,在调试这个困惑的几个小时后我遇到了巨大的障碍。

最佳答案

string query = "select z.ItemName, x.Quantity, x.CreateDate" +
      " from Invoice_Itemized x inner join Inventory z on x.ItemNum = z.ItemNum inner join Departments d on z.Dept_ID = d.Dept_ID" +
      $"where x.CreateDate BETWEEN '{ startTimePicker1 }' and '{ endTimePicker1 }' and d.SubType = 'TYPE'";

liquorBindingSource.DataSource = db.Query<Liquor>(query, commandType: CommandType.Text);

这是非常有害的,并且可能导致多种问题,包括格式/文化问题(它可以在某些机器上运行,但不能在其他机器上运行,具体取决于区域设置) - 以及(更重要的是)SQL注入(inject)风险。它还不允许重复使用查询计划缓存。

由于您在这里使用的是“dapper”,因此 dapper 的设计是为了方便参数化:

liquorBindingSource.DataSource = db.Query<Liquor>(@"
        select z.ItemName, x.Quantity, x.CreateDate
        from Invoice_Itemized x
        inner join Inventory z on x.ItemNum = z.ItemNum
        inner join Departments d on z.Dept_ID = d.Dept_ID
        where x.CreateDate BETWEEN @start and @end and d.SubType = 'TYPE'",
    new { start = startTimePicker1.Value, end = endTimePicker1.Value });

这会将值作为类型参数传递(假设此处的 .ValueDateTime),避免了所有本地问题消除了风险SQL注入(inject)。如果.Value不是DateTime,而只是字符串,那么我会使用:

new { start = DateTime.Parse(startTimePicker1.Value),
        end = DateTime.Parse(endTimePicker1.Value) }

作为第二个参数。

关于C# 潜在的日期格式问题 - System.Data.SqlClient.SqlException : 'Incorrect syntax near ' x'. ',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51398303/

相关文章:

c# - 人们要求我修复 N+1 错误?

php - 从具有相同列的两个表中选择

XAMPP : password for phpMyAdmin and mysql_connect different? 上的 php/mySQL

mysql - 在 SELECT 期间确定另一个表中相关行的数量 (0 - n)

sql - 在 Postgres 中查找 min + 1

c# - 在 Unity 中存储只读数据的良好实践

c# - 如何在 UWP 应用程序上播放原始 pcm 音频字节?

sql - 在SQL中查找重复项

c# - ASP.NET MVC ViewModel 属性为空

c# - 德语特殊字符 Ää、Öö、Üü、ß 在 LiveLink 或 opentext 中显示不正确