2016-04-19 98 views
0
Dim SALESINSERT As New SqlCommand("INSERT INTO Tbl_Sales (Sale_id, Transaction_No, Customer_id, Item_id, Amount, Date) VALUES(" _ 
           & SalesIdMax + 1 & "," & Transaction_label.Text & "," & 1 & "," & Label4.Text & "," & TextBox1.Text & _ 
           "," & DateTimePicker1.Value.Date & ")", sqlcon) 

sqlcon.Open() 
SALESINSERT.ExecuteNonQuery() 
sqlcon.Close() 

SALESINSERT = Nothing   

我有这段代码。一切正常,但问题在于日期。出于某种原因,它每次都插入相同的日期:“1/1/1900”。通过vb.net插入日期到SQL Server数据库

当我调试代码来查看SQL命令文本时,它很好,日期很好,我在SQL查询中执行它,它非常好。

但在VB中并没有。

我不知道它为什么不起作用。

请给我建议解决它。

+3

使用参数化查询 - 这将防止sql注入并将解决此问题作为副作用。请注意,如果代码运行日期不同的区域设置,您的代码将会失败 –

+2

首先,我强烈建议您使用[Option Strict On](https://msdn.microsoft.com/zh-cn/library/zcd4xwzs的.aspx)。然后,使用SQL参数查询查询中的值。 –

+0

“一切正常?”这是令人困惑的,因为代码不可能工作 –

回答

1

如果您总是使用参数化查询,那么您将避免将日期表示为字符串的问题。

您可以使用SQL参数(我在数据库中列的数据类型来猜测)您所查询的是这样的:

Dim salesinsert As New SqlCommand("INSERT INTO Tbl_Sales ([Sale_id], [Transaction_No], [Customer_id], [Item_id], [Amount], [Date])" & 
            " VALUES(@SaleId, @TransactionNo, @CustomerId, @ItemId, @Amount, @Date)", sqlcon) 

salesinsert.Parameters.Add(New SqlParameter With {.ParameterName = "@SaleId", .SqlDbType = SqlDbType.Int, .Value = SalesIdMax + 1}) 
salesinsert.Parameters.Add(New SqlParameter With {.ParameterName = "@TransactionNo", .SqlDbType = SqlDbType.NVarChar, .Size = 20, .Value = Transaction_label.Text}) 
salesinsert.Parameters.Add(New SqlParameter With {.ParameterName = "@CustomerId", .SqlDbType = SqlDbType.Int, .Value = 1}) 
salesinsert.Parameters.Add(New SqlParameter With {.ParameterName = "@ItemId", .SqlDbType = SqlDbType.NVarChar, .Size = 20, .Value = Label4.Text}) 
salesinsert.Parameters.Add(New SqlParameter With {.ParameterName = "@Amount", .SqlDbType = SqlDbType.Decimal, .Value = CDec(TextBox1.Text)}) 
salesinsert.Parameters.Add(New SqlParameter With {.ParameterName = "@Date", .SqlDbType = SqlDbType.DateTime, .Value = DateTimePicker1.Value}) 

sqlcon.Open() 
salesinsert.ExecuteNonQuery() 
sqlcon.Close() 

salesinsert.Dispose() 
  • 我逃跑时方括号中的列名 - 这避免了使用问题SQL reserved keywords作为列名。总是转义列名更容易。
  • 您不应设置SALESINSERT = Nothing - 而应使用salesinsert.Dispose(),因为这可以正确清理非托管资源。
  • 您需要更改每个.SqlDbType(和.Size的字符串)以匹配数据库列的数据类型。十进制值应该具有.Scale.Precision
  • 控件可以使用描述性名称 - TextBox1并不暗示它会有数量。
  • 在运行查询之前应验证这些值,例如,可以将文本量转换为十进制值,这是一个合理的值。
+0

以及将做到这一点,但Iam想知道你添加参数的方式,因为我只是用这种方式'SALESINSERT.Parameters.Add(“@ trans”,SqlDbType.BigInt).Value = Transaction_label。文字“,它不起作用,为什么呢? – Abram

+0

那么会做到这一点,但Iam想知道你添加参数的方式,因为我只是用这种方式'SALESINSERT.Parameters.Add(“@ trans”,SqlDbType.BigInt).Value = Transaction_label.Text',它没有工作为什么呢? – Abram

+0

@Abram 1)我喜欢使用'.Add(New SqlParameter With {....',因为它明确了参数是什么*,它的工作原理* 2)你有一个数据类型不匹配错误。你不能给一个数字分配一个字符串 - 如果你使用Option Strict On,编译器会为你指出。 –

0

使用单引号的日期值",'" & DateTimePicker1.Value.Date & "')"

或者

",#" & DateTimePicker1.Value.Date & "#)" 
0

问题是与给定日期的格式。您可以通过使用.ToString()格式化dateTime输入来避免此问题。即,

DateTimePicker1.Value.Date.ToString("yyyy-MM-dd HH:mm:ss") 

然后是真正的问题injection;以避免您必须使用parameterised queries代替仅用于文本查询。