C#和SQL数据库的区域问题
为什么C#和SQL数据库的区域问题,c#,sql-server,datetime,C#,Sql Server,Datetime,为什么dateTimePicker.Value.Date.ToSortDateString()会出现错误在Windows 7 x64 PL、Windows Vista x32 PL和Windows XP PL上使用我所知的精确区域设置进行不同的操作。我发现,在将其输入到DB之前,我很难进行这种转换 它在Windows7(我的开发机器)和同事的VISTA系统上运行良好,但在WindowsXP上无法运行(整天都是以月换日)。在更高的系统上,我们在ListView上显示了2010-01-13,而在他的
dateTimePicker.Value.Date.ToSortDateString()会出现错误代码>在Windows 7 x64 PL、Windows Vista x32 PL和Windows XP PL上使用我所知的精确区域设置进行不同的操作。我发现,在将其输入到DB之前,我很难进行这种转换
它在Windows7(我的开发机器)和同事的VISTA系统上运行良好,但在WindowsXP上无法运行(整天都是以月换日)。在更高的系统上,我们在ListView
上显示了2010-01-13,而在他的系统上显示了13-01-2010
我想在我的旧代码中,我可能会有更多的类型转换,我将不得不进行检查和验证,但我想知道为什么在相同的区域设置中会出现这种情况。我想我永远不应该做这样的转换,但我已经学习了很长一段时间后,当它工作得很好的艰苦方式
编辑:
我是这样使用它的(注释掉了引起麻烦的代码)。回到过去,我认为ToSortDateString是确保在没有时间的情况下将其放入DB的唯一方法(因为我正在阅读DateTimePicker)。我现在知道我应该用那个日期时间选择器来约会,但现在我更聪明了,因为它确实在我身上爆炸了。代码如下:
private static void sqlWpiszDaneSwieta(DateTime varData, string varDataNazwa) {
//string varDataSwieto = varData.ToShortDateString();
const string preparedCommand = @"INSERT INTO [dbo].[TypyDatySwiat]
([SwietaData]
,[SwietaNazwa])
VALUES
(@varData
,@varDataNazwa)";
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (SqlCommand sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
sqlWrite.Prepare();
sqlWrite.Parameters.AddWithValue("@varData", varData);
sqlWrite.Parameters.AddWithValue("@varDataNazwa", varDataNazwa);
try {
sqlWrite.ExecuteNonQuery();
} catch (SqlException sqlEx) {
if (sqlEx.Message.Contains("Violation of PRIMARY KEY constraint")) {
MessageBox.Show("Dodanie podanego święta jest niemożliwe. Podane święto istnieje już w bazie danych!", "Bład", MessageBoxButtons.OK, MessageBoxIcon.Error);
} else {
MessageBox.Show(sqlEx.ToString(), "Bład SQL", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} catch (Exception ex) {
MessageBox.Show(ex.ToString(), "Bład", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
因此,我并不是特别要求一种方法来做到这一点。我知道如何做,并且我可以使用DateTime将其直接传递给db。我只是想知道为什么它在一台机器上的行为会不同
白天总是和月份切换
这听起来很可疑,你的同事在他的XP机器上使用的是英国地区,因为这是在那里约会的正常方法
但我更关心的是:
在将其输入数据库之前
如果要将其放入数据库,为什么要调用.toSortDateString()
?这闻起来像动态sql,这意味着sql注入漏洞。而不是像这样:
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (" + MyDateVar.ToShortDateString() + ")";
//sql command/connection code omitted from this sample
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (@MyDate)"
using (var cn = new SqlConnection("..connection string.."))
using (var cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@MyDate", SqlDbType.DateTime).Value = MydateVar;
//remain code omitted
您需要这样做:
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (" + MyDateVar.ToShortDateString() + ")";
//sql command/connection code omitted from this sample
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (@MyDate)"
using (var cn = new SqlConnection("..connection string.."))
using (var cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@MyDate", SqlDbType.DateTime).Value = MydateVar;
//remain code omitted
请注意,后一个示例从不将datetime变量转换为字符串。无论用户设置了什么语言环境,它都会工作
白天总是和月份切换
这听起来很可疑,你的同事在他的XP机器上使用的是英国地区,因为这是在那里约会的正常方法
但我更关心的是:
在将其输入数据库之前
如果要将其放入数据库,为什么要调用.toSortDateString()
?这闻起来像动态sql,这意味着sql注入漏洞。而不是像这样:
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (" + MyDateVar.ToShortDateString() + ")";
//sql command/connection code omitted from this sample
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (@MyDate)"
using (var cn = new SqlConnection("..connection string.."))
using (var cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@MyDate", SqlDbType.DateTime).Value = MydateVar;
//remain code omitted
您需要这样做:
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (" + MyDateVar.ToShortDateString() + ")";
//sql command/connection code omitted from this sample
string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (@MyDate)"
using (var cn = new SqlConnection("..connection string.."))
using (var cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@MyDate", SqlDbType.DateTime).Value = MydateVar;
//remain code omitted
请注意,后一个示例从不将datetime变量转换为字符串。无论用户设置了什么语言环境,它都能工作。听起来很像区域设置。我会检查运行应用程序的帐户的区域设置,看看这是否提供了一个解释
至于处理这个问题,在DateTime
上的ToBinary
方法提供了一种导出值的安全方法,以便以后可以重新创建该值。更妙的是,考虑到这将进入数据库,最好像其他人建议的那样将值传递给SQLCommand。听起来很像区域设置。我会检查运行应用程序的帐户的区域设置,看看这是否提供了一个解释
至于处理这个问题,在DateTime
上的ToBinary
方法提供了一种导出值的安全方法,以便以后可以重新创建该值。更好的是,考虑到这将进入数据库,将值传递给SQLCommand,正如其他人所建议的那样。我认为最好使用不变区域性在数据库中存储日期/时间之类的内容。当您将其从数据库中取出并显示给用户时,您应该关注区域设置
您应该使用DateTime.ToString(System.Globalization.CultureInfo.InvariantCulture)
,而不是在数据库中存储ShortDateString
要查看(在代码中)您使用的区域性,只需使用System.Globalization.CultureInfo.CurrentCulture.Name
我认为最好使用不变区域性在数据库中存储日期/时间之类的内容。当您将其从数据库中取出并显示给用户时,您应该关注区域设置
您应该使用DateTime.ToString(System.Globalization.CultureInfo.InvariantCulture)
,而不是在数据库中存储ShortDateString
要查看(在代码中)您正在使用的区域性,只需使用System.Globalization.CultureInfo.CurrentCulture.Name
为什么还要将日期时间转换为字符串?如果使用的是参数,则可以直接传入DateTime
实例。(如果你没有使用参数…为什么不??)就像我说的,这是我的旧代码。在我做很多不该做的事情之前。我现在正在使用参数来正确传递日期时间,因为它工作正常,所以我没有修改它。我计划在清洁月做这件事,我将去那里修复我在学习时做的所有“坏”事情。你为什么还要将你的日期时间转换成字符串呢?如果使用的是参数,则可以直接传入DateTime
实例。(如果你没有使用参数…为什么不??)就像我说的,这是我的旧代码。在我做很多不该做的事情之前。我现在正在使用参数来正确传递日期时间,因为它工作正常,所以我没有修改它。我计划在清洁月做这件事,在那里我将去修复我在学习中做的所有“坏”事情。我编辑了主要帖子来展示我是如何使用它的(注释掉了b