我有一张桌子......
if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[ADDRESS_BOOK]')
and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[ADDRESS_BOOK]
GO
CREATE TABLE [dbo].[ADDRESS_BOOK]
(
[ID] [bigint] IDENTITY (1, 1) NOT NULL ,
[FIRST_NAME] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[LAST_NAME] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[CONTACT_NOS] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[MODIFIED_BY] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[MODIFIED_TIME] [timestamp] NULL
) ON [PRIMARY]
GO
我的问题是将数据插入此表的SQL语句应该是什么?
我试过
Dim sb As New StringBuilder
With sb
.Append("SET IDENTITY_INSERT ADDRESS_BOOK ON ")
.Append("INSERT INTO ADDRESS_BOOK(ID,FIRST_NAME,LAST_NAME,")
.Append("CONTACT_NOS,MODIFIED_BY,MODIFIED_TIME) VALUES(NULL,")
.Append("'" & TbFName.Text & "','" & TbLName.Text & "','" & TbContactNos.text & "','" & TbUser.Text & "',NULL)")
.Append(" SET IDENTITY_INSERT ADDRESS_BOOK OFF")
End With
Dim cmd As New SqlCommand
cmd.Connection = conn
cmd.CommandText = sb.ToString
cmd.ExecuteNonQuery()
但它给了我错误......
Cannot insert the value NULL into column 'ID', table 'MY_DB.dbo.ADDRESS_BOOK'; column does not allow nulls. INSERT fails. The statement has been terminated.
答案 0 :(得分:3)
这一行:
.Append("CONTACT_NOS,MODIFIED_BY,MODIFIED_TIME) VALUES(NULL,")
您正试图在不接受NULL
的列中插入NULLS
。
ID列设置为自动增量(IDENTITY (1,1)
)。
只需将该列从查询参数中删除(它将自动递增),您的查询应该没问题。
建议:使用参数化查询。它是一种更清晰,更优化的查询数据库的方式。它有很多优点(你可以自己阅读,我在这里不会对它们有所了解)。
此外,您不需要在每一行都使用追加。它只是糟糕的编码和非常恼人的阅读!此外,像这样的代码极不可能通过任何一轮的代码审查。
<强> 编辑: 强>
INSERT INTO ADDRESS_BOOK(FIRST_NAME, LAST_NAME, CONTACT_NOS, MODIFIED_BY, MODIFIED_TIME) VALUES('FirstName', 'LastName', '1234567890', 'SomeName', '2014-01-01 12:15:17.227')
请注意,我在这里根本没有提到专栏ID
。执行此语句时,包含此行的表将自动具有ID
值。
希望这有帮助!!!
答案 1 :(得分:2)
这里有一个以上的问题。 timestamp数据类型(aka rowversion)不是datetime数据类型。请在这里阅读。 http://technet.microsoft.com/en-us/library/ms182776.aspx
其次,正如其他人已经指出你的代码对sql注入是开放的。你真的应该为这类事情使用存储过程。
以下是我将如何编写此内容,包括具有正确数据类型的ddl。
CREATE TABLE [dbo].[ADDRESS_BOOK]
(
[ID] [bigint] IDENTITY (1, 1) NOT NULL ,
[FIRST_NAME] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[LAST_NAME] [varchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[CONTACT_NOS] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[MODIFIED_BY] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[MODIFIED_TIME] [timestamp] NULL
) ON [PRIMARY]
GO
create procedure Address_Book_Insert
(
@FName varchar(10)
, @LName varchar(10)
, @Contact_NOS varchar(50)
, @Modified_By varchar(20)
, @Modified_Time datetime
) as
INSERT ADDRESS_BOOK
(
FIRST_NAME
, LAST_NAME
, CONTACT_NOS
, MODIFIED_BY
, MODIFIED_TIME
)
VALUES
(
@FName
, @LName
, @Contact_NOS
, @Modified_By
, @Modified_Time
)
go
然后这很简单。您更改代码以使用存储过程,建立参数并执行存储过程。您可以轻松分离逻辑和数据,您的代码将更安全,并且维护起来更容易。
答案 2 :(得分:0)
不要使用SQL注入,很容易破坏你的程序。 另外,不要为ID发送空值,请确保使用IDENTITY(1,1)自动增量 我建议你使用存储过程做什么......就像这样:
ON SQL:
CREATE PROCEDURE '<schemaname>.InsertOnAddressBook'
(
--this is the arguments/parameters you should pass to the stored procedure
@TbFName varchar(30), --remember, this limit of varchar can be changed as you wish
@TbLName varchar(30),
@TbContactNos varchar(30),
@TbUser varchar(20)
)
AS
BEGIN
SET IDENTITY_INSERT ADDRESS_BOOK ON
INSERT INTO ADDRESS_BOOK
(FIRST_NAME,LAST_NAME,CONTACT_NOS,MODIFIED_BY,MODIFIED_TIME)
VALUES(@TbFName, @TbLName, @TbContactNos, @TbUser, NULL)
SET IDENTITY_INSERT ADDRESS_BOOK OFF
END
ON VB.NET SIDE:
cmd.CommandText = "<schemaname>.InsertOnAddressBook"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@TbFName",TbFName.text)
cmd.Parameters.AddWithValue("@TbLName",TbLName.text)
cmd.Parameters.AddWithValue("@TbContactNos",TbContactNos.text)
cmd.Parameters.AddWithValue("@TbUser",TbUser.text)
安全性方面,从后面的代码执行存储过程更加安全!
答案 3 :(得分:0)
如果IDENTITY_INSERT
设置为ON
,那么我们必须为Explicit value
列指定IDENTITY
。否则会出现错误:
当IDENTITY_INSERT设置为ON时,必须为表'TableName'中的标识列指定显式值。
另一方面:
只需将该列从查询参数中删除(它将自动递增),您的查询应该没问题。
从@Satwik Nadkarny实施上述声明,我找到了答案。
<强> SOLUTION:强>
Dim sb As New StringBuilder
With sb
'.Append("SET IDENTITY_INSERT ADDRESS_BOOK ON ") '<-- No need to set it ON if we do not specify the Explicit value.
.Append("INSERT INTO ADDRESS_BOOK(FIRST_NAME,LAST_NAME,") '<-- I leaved the ID column out of the query
.Append("CONTACT_NOS,MODIFIED_BY,MODIFIED_TIME) VALUES(NULL,")
.Append("'" & TbFName.Text & "','" & TbLName.Text & "','" & TbContactNos.text & "','" & TbUser.Text & "','" & MODIFIED_TIME & "')")
'.Append(" SET IDENTITY_INSERT ADDRESS_BOOK OFF") '<-- No need to set it OFF
End With
Dim cmd As New SqlCommand
cmd.Connection = conn
cmd.CommandText = sb.ToString
cmd.ExecuteNonQuery()
<强> SQL:强>
"INSERT INTO TABLE_NAME(FIELD2,FIELD3,FIELD4) VALUES(FIELD2_DATA,FIELD3_DATA,FIELD4_DATA)"
在上面的SQL查询语句中,FIELD1
是ID
自动增量标识(1,1)字段,我将其从查询中排除。此外,我必须学习查询参数化,因为我从未使用过它。
最后,我知道为什么我被投票支持会很有帮助。
感谢@Satwik的想法。它对我帮助很大。