C# 将日期时间保存到SQL Server数据库时出错
我在业余时间做了一点C#Winforms编码,只是要掌握一切。我有一个SQL脚本,它在vs2012上创建一个本地数据库,如下所示:C# 将日期时间保存到SQL Server数据库时出错,c#,sql,sql-server,winforms,C#,Sql,Sql Server,Winforms,我在业余时间做了一点C#Winforms编码,只是要掌握一切。我有一个SQL脚本,它在vs2012上创建一个本地数据库,如下所示: -- Creating table 'Users'-- CREATE TABLE [dbo].[Users] ( [UserID] int IDENTITY(1,1) NOT NULL, [Surname] nvarchar(30) NOT NULL, [Forename] nvarchar(30) NOT NULL, [Comp
-- Creating table 'Users'--
CREATE TABLE [dbo].[Users]
(
[UserID] int IDENTITY(1,1) NOT NULL,
[Surname] nvarchar(30) NOT NULL,
[Forename] nvarchar(30) NOT NULL,
[Company] nvarchar (30) NOT NULL,
[SecurityLevel] int NOT NULL,
[IssueDate] DateTime NOT NULL,
[ExpiryDate] DateTime NOT NULL,
[CardID] int NOT NULL,
);
GO
现在我想将详细信息保存到该表中,因此我创建了一个方法:
private void btnSaveDetails_Click(object sender, EventArgs e)
{
SqlConnection sc = new SqlConnection();
SqlCommand com = new SqlCommand();
sc.ConnectionString = (Properties.Settings.Default.BioEngineering);
sc.Open();
com.Connection = sc;
com.CommandText = ("INSERT INTO Users (Forename, Surname, Company, SecurityLevel, IssueDate, ExpiryDate, CardID) VALUES ('" + this.txtFirstName.Text + "','" + this.txtLastName.Text + "','" + this.txtCompany.Text + "','" + this.cboSecurityLevel.Text + "','" + this.dtpIssueDate.Value + "','" + this.dtpExpiryDate.Value + "','" + this.cboCardID.Text + "');");
com.ExecuteNonQuery();
sc.Close();
}
当我运行代码时,我得到一个错误
将varchar数据类型转换为datetime数据类型导致值超出范围
我知道这与SQL或C#等价物的datetime格式有关,但我不知道如何格式化datetime以符合错误。有什么想法吗?我尝试用命令文本行格式化它,但似乎没有解决问题。首先,您这样做的方式是非常粗糙的sql语句运行方式,容易出现大量错误、内存泄漏、sql注入攻击和安全问题 --您应该使用
using
语句来处理连接和命令对象,从而更好地处理错误
--您应该使用参数化查询或存储的过程或表单,如nhibernate或EF
无论如何,代码中的错误如下
将日期字段转换为此格式.ToString(“MM/dd/YYYY”)
Datepicker.Value返回为
[Your_System_Short_Date_Format] + [Space] + [Your_System_Long_Time_Format]
我不知道为什么会使用这种格式,但在添加DateTimePicker时使用默认的长格式进行检查时才发现
因此,根据您的系统[区域/日历]设置,您正在传递一个值,而SQL引擎希望该值的格式与EBrown所说的相同
yyyy-MM-dd HH:mm:ss.fffffff
因此,如果您确实想要连接,那么可以使用like
command.CommandText =
"INSERT INTO EMPLOYEES(DateOfBirth) VALUES ('" +
dtpDateOfBirth.Value.ToString("yyyy-MM-dd HH:mm:ss") + "')";
但我真诚地建议您从一开始就保持使用参数的习惯。或者,在创建了一个大型应用程序之后,您可能需要返回以将这些连接更改为参数
这很简单,就像
command.CommandText = "INSERT INTO EMPLOYEES(DateOfBirth) VALUES (@dob)";
command.Parameters.Add("@dob", SqlDbType.DateTime).Value = dtpDateOfBirth.Value;
// Or Simply
command.Parameters.AddWithValue("@dob", dtpDateOfBirth.Value);
可以使用参数添加更多具有不同数据类型的参数。SqlCommand类安全地将其转换为SqlCommand,特别是从注入攻击中。您应该使用参数化查询。不仅如此,您的问题的一部分是.Value,SQL希望DateTime的格式为:“yyyy-MM-dd-HH:MM:ss.fffffff”,具体取决于列类型。此外,DateTime2更适合SQL列类型。不应该,必须。您的问题看起来不是代码问题,而是数据问题。您输入的值是什么?日期时间值来自日期选择器box@EBrown关于参数化查询,您是对的,但您本可以到此为止。一旦OP移动到正确的参数用法,字符串强制和预期格式就不相关了。请阅读以下内容:您对DateTimePicker的使用。值将其强制转换为默认的本地化SQL不可表示字符串。正如@DonBoitnott和我所说的,切换到参数化查询不仅可以解决这个问题,而且可以消除任何人都可以在代码上执行的大量SQL注入攻击。另外:我知道man、ORM、存储过程、参数化问题、很多选项……对他来说,一步一个脚印,让他先感受一下:)。你们这些家伙太严肃了,想在101课上教他最佳实践。哇,你们认为学习编码就像治病去看医生一样。我可以发现问题中的每一行代码都有问题,伙计,我们并不是在纠正每一行代码。在命令/连接对象周围使用语句,为所有数据库调用编写单独的服务,并可能通过依赖项注入将其注入表单等。在代码中查找其他缺陷是常见的。一个完整的答案也以清晰简洁的方式充实了这些问题。
command.CommandText = "INSERT INTO EMPLOYEES(DateOfBirth) VALUES (@dob)";
command.Parameters.Add("@dob", SqlDbType.DateTime).Value = dtpDateOfBirth.Value;
// Or Simply
command.Parameters.AddWithValue("@dob", dtpDateOfBirth.Value);