c# - 为什么我的更新查询在 c# 和 sql server 中不起作用?

标签 c# sql ssms

当我尝试更新我的数据库时,它在到达日期时间列时崩溃。

这是我要执行的函数(pub Date 是它崩溃的地方):

        public void UpdateDatabase(List<Title> titleList, List<Author> authorList, List<Publisher> publisherList)
        {
            using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(Helper.CnnVal("CsharpMD3")))
            {
                foreach (var item in titleList)
                {

                    connection.Execute($"update titles Set title='{item.title}', titleType='{item.TitleType}', price='{item.Price}' , pubdate=cast({item.PubDate.Year}{item.PubDate.Month}{item.PubDate.Day} as datetime2) , pubID='{item.PubID}' where ID={item.ID}");                    
                }
            }
        }

我试过将它转换为 datetime2/datetime,我试过使用转换函数

CONVERT(datetime, mydate, 112)

我试图只输入整个日期,但是当它开始读取时间时它也会崩溃。 我试过这个:

connection.Execute($"update titles Set title='{item.title}', titleType='{item.TitleType}', price='{item.Price}' , pubdate='{item.PubDate.Year}{item.PubDate.Month}{item.PubDate.Day}' , pubID='{item.PubID}' where ID={item.ID}");                    

我还尝试添加和删除撇号。

我得到的大部分错误是:算术溢出错误将表达式转换为数据类型日期时间。 and : 从字符串转换日期和/或时间时转换失败。

奇怪的是,当我尝试创建(插入)一个新项目到数据库中时它起作用了 如果我将命令键入 sql 本身并将变量名更改为数字,它也可以工作:

        public void InsertTitle(Title toInsert)
        {
            using (IDbConnection connection = new System.Data.SqlClient.SqlConnection(Helper.CnnVal("CsharpMD3")))
            {
                connection.Execute($"insert into dbo.titles (title, titleType, price, pubdate, pubID) VALUES ('{toInsert.title}' , '{toInsert.TitleType}', '{toInsert.Price}', '{toInsert.PubDate.Year}{toInsert.PubDate.Month}{toInsert.PubDate.Day}', '{toInsert.PubID}')");
            }
        }

我也尝试过参数化的 sql 命令,但对我来说没有用,所以我只想弄清楚为什么更新功能不起作用。

如果我只更改年而不是月或日,它也有效!

最佳答案

这将解决问题,并修复原始版本中的巨大安全漏洞:

public void UpdateDatabase(IEnumerable<Title> titleList)
{
    string sql = "update titles Set title= @title, titleType= @titleType, price= @price , pubdate= @pubDate , pubID= @pubID where ID= @ID";

    using (var connection = new SqlConnection(Helper.CnnVal("CsharpMD3")))
    using (var command = new SqlCommand(sql, connection))
    {
        //Use actual column types and lengths from the DB here.
        // I had to guess, but you can look them up.
        command.Parameters.Add("@title", SqlDbType.NVarChar, 100);
        command.Parameters.Add("@titleType", SqlDbType.NVarChar, 20);
        command.Parameters.Add("@price", SqlDbType.Decimal, 6, 2);
        command.Parameters.Add("@pubDate", SqlDbType.DateTime2);
        command.Parameters.Add("@pubID", SqlDbType.Int);
        command.Parameters.Add("@ID", SqlDbType.Int);

        connection.Open();
        foreach (var item in titleList)
        {
            command.Parameters["@title"].Value = item.title;
            command.Parameters["@titleType"].Value = item.TitleType;
            command.Parameters["@price"].Value = item.Price;
            command.Parameters["@pubDate"].Value = item.PubDate;
            command.Parameters["@pubID"].Value = item.PubID;
            command.Parameters["@ID"].Value = item.ID;
            command.ExecuteNonQuery();                
        }
    }
}

和插入函数:

public int InsertTitle(Title toInsert)
{
    string sql = "insert into dbo.titles (title, titleType, price, pubdate, pubID) VALUES (@title, @titleType, @price, @pubDate, @pubID);select scope_identity();";

    using (var connection = new SqlConnection(Helper.CnnVal("CsharpMD3")))
    using (var command = new SqlCommand(sql, connection))
    {
        command.Parameters.Add("@title", SqlDbType.NVarChar, 100).Value = toInsert.title;
        command.Parameters.Add("@titleType", SqlDbType.NVarChar, 20).Value = toInsert.titleType;
        command.Parameters.Add("@price", SqlDbType.Decimal, 6, 2).Value = toInsert.Price;
        command.Parameters.Add("@pubDate", SqlDbType.DateTime2).Value = toInsert.PubDate;
        command.Parameters.Add("@pubID", SqlDbType.Int).Value = toInsert.PubID;

        connection.Open();
        toInsert.ID = (int)command.ExecuteScalar();
        return toInsert.ID;
    }
}

这是一个很好的经验法则,如果您发现自己试图格式化日期值以便在来自任何客户端语言平台的 SQL 字符串中使用,那么您就在做一些可怕的错误.

至于最初的问题...我希望您在最终创建无意义的日期字符串的地方有个位数的值,例如 2019123。那可能是 1 月 23 日或 12 月 3 日,而且无法知道是哪一天。

关于c# - 为什么我的更新查询在 c# 和 sql server 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58956683/

相关文章:

c# - 不使用数据集的N层体系结构(数据集听起来对性能不利)

c# - 反射(reflect)属性以获取属性。当它们在别处定义时怎么办?

php - 如何通过 php/mysqli 获取行号

sql - 后端版本不支持设计数据库图或表

SQL Server Management Studio 网络相关或特定于实例的错误

sql-server - SSMS - 无法使用本地计算机上的 SSMS 连接到 Azure VM 上的 SQL Server 2017 Express

c# - 无法在 Windows 10 上安装 dotnet-ef 工具

c# - 在 C# 中从资源/程序集加载 excel 文件

MySQL:可选择构建 Group Concat 字段

MySQL 左连接与存在子查询返回的行数超出应有的行数