我正在使用一些简单的vb代码来记录用户登录我的程序。这个想法是服务器使用默认值自动用正确的时间/日期填充时间/日期列。我知道我可以从客户端计算机中检索这两个,但这取决于他们的设备被设置到正确的时间和时区。当我使用下面的代码时,我似乎无法让服务器使用默认值。我的两列似乎都采用00:00:00(时间一)和1900:01:01(日期列)。但是,当我使用Microsoft SQL Server Management Studio输入虚假数据时,它将默认为当前时间和日期。
con.open()
cmd = New SqlCommand("INSERT INTO Account_Login_Log VALUES (@memberID, @accountID, @logintime, @logindate)", con)
cmd.Parameters.AddWithValue("@memberID", "32")
cmd.Parameters.AddWithValue("@accountID", "91")
cmd.Parameters.AddWithValue("@logintime", "")
cmd.Parameters.AddWithValue("@logindate", "")
cmd.ExecuteNonQuery()
con.close()
我的问题是,为什么我的代码在服务器端自动默认为正确的时间和日期?
我尝试过:
使用dbNULL.value省略insert语句中的列,并简单地指定“”,就像我在上面的代码中所示。但所有人都诉诸于时间的开始。
修改 - 我在下面列出了完整的表格定义。
USE [Atlas]
GO
/****** Object: Table [dbo].[Account_Login_Log] Script Date: 26/01/2015 8:34:21 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Account_Login_Log](
[lLogID] [int] IDENTITY(10,1) NOT NULL,
[lMember_ID] [int] NOT NULL,
[lAccount_ID] [int] NOT NULL,
[lLogin_Time] [time](7) NOT NULL CONSTRAINT [DF_Account_Login_Log_lLogin_Time] DEFAULT (CONVERT([varchar](8),getdate(),(108))),
[lLogin_Date] [date] NOT NULL CONSTRAINT [DF_Account_Login_Log_lLogin_Date] DEFAULT (getdate()),
CONSTRAINT [PK_Account_Login_Log] PRIMARY KEY CLUSTERED
(
[lLogID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Account_Login_Log] WITH CHECK ADD CONSTRAINT [FK_Account_Login_Log_Account1] FOREIGN KEY([lAccount_ID])
REFERENCES [dbo].[Account] ([aAccount_ID])
GO
ALTER TABLE [dbo].[Account_Login_Log] CHECK CONSTRAINT [FK_Account_Login_Log_Account1]
GO
ALTER TABLE [dbo].[Account_Login_Log] WITH CHECK ADD CONSTRAINT [FK_Account_Login_Log_Member_Details] FOREIGN KEY([lMember_ID])
REFERENCES [dbo].[Member_Details] ([mMember_ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Account_Login_Log] CHECK CONSTRAINT [FK_Account_Login_Log_Member_Details]
GO
修改 - 我已经提供了证据证明我的列的默认值为getdate()
,而且lLogin_Time为(CONVERT([varchar](8),getdate(),(108)))
注入攻击注意:我的代码没有从用户那里获取任何值,所有这些都是基于程序&数据库值,所以我不担心注入攻击。
答案 0 :(得分:0)
为什么你认为
INSERT INTO Account_Login_Log (lMember_ID, lAccount_ID, lLogin_Time, lLogin_Date) VALUES (@memberID, @accountID, @logintime, @logindate)
会使用默认值吗?
如果您为表设置了默认值,请执行以下操作:
INSERT INTO Account_Login_Log (lMember_ID, lAccount_ID) VALUES (@memberID, @accountID)
因为您将值传递给insert语句,所以它使用那些而不是默认值。
查询管理器的工作方式不同的原因是,当您使用C#平台时,它会将您发送的内容转换为正确的类型(时间和日期),然后将值发送到使用的服务器。
答案 1 :(得分:0)
将代码更改为
Dim cmd = new SqlCommand("INSERT INTO Account_Login_Log " & _
"(lMember_ID, lAccount_ID) " &
"VALUES (@memberID, @accountID)", cnn)
cmd.Parameters.AddWithValue("@memberID", 32)
cmd.Parameters.AddWithValue("@accountID", 91)
cmd.ExecuteNonQuery()
要AddWithValue
,您应该传递正确的数据类型。如果列需要一个字符串,则应传递一个字符串,但如果该列需要一个int,则传递一个int,而不是一个字符串。此外,INSERT不需要为具有默认值的列传递值。如果您没有传递任何内容,将使用默认值。最后,INSERT语法要求,如果不传递所有字段名称的参数,则需要指定哪些列受查询影响。所以你需要添加更新的两列的名称
答案 2 :(得分:0)
我最终放弃了表格,并在一列中使用datetime
重新创建了表格。我还不完全确定为什么服务器默认为日历的开头,唯一合乎逻辑的是VB正在向列发送某种数据并且它默认为启动而不是当前datetime
。我已经包含了我的新表,它的代码只是因为未来任何人都会遇到同一问题,但我怀疑有人会这样做。
VB代码:
con.open()
cmd = New SqlCommand("INSERT INTO Account_Login_Logger (lAccount_ID) VALUES (@accountid)", con)
cmd.Parameters.AddWithValue("@accountid", 91)
cmd.ExecuteNonQuery()
con.close()
新数据库表:
USE [Atlas]
GO
/****** Object: Table [dbo].[Account_Login_Logger] Script Date: 27/01/2015 3:37:20 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Account_Login_Logger](
[lLogin_ID] [int] IDENTITY(10,1) NOT NULL,
[lAccount_ID] [int] NOT NULL,
[lDate_Time_Stamp] [datetime] NOT NULL CONSTRAINT [DF_Account_Login_Logger_lDate_Time_Stamp] DEFAULT (getdate()),
CONSTRAINT [PK__Account___0B8A2E93BF56F461] PRIMARY KEY CLUSTERED
(
[lLogin_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
当我这样做时,我的问题已解决。谢谢大家的帮助。