C#:SQL Server查询问题
我创建SQL Server Management Studio中的表使用此代码:C#:SQL Server查询问题
CREATE TABLE contact(
ID INT IDENTITY NOT NULL,
FIRSTNAME VARCHAR(100),
LASTNAME VARCHAR(100)
)
,并在C#中我用这个代码:
SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE");
SqlDataAdapter sd = new SqlDataAdapter();
sd.InsertCommand = new SqlCommand("INSERT INTO contact VALUES(@ID, @FIRSTNAME, @LASTNAME)");
sd.InsertCommand.Parameters.Add("@ID", SqlDbType.Int).Value = textBox1.Text;
sd.InsertCommand.Parameters.Add("@FIRSTNAME", SqlDbType.VarChar).Value = textBox2.Text;
sd.InsertCommand.Parameters.Add("@LASTNAME", SqlDbType.VarChar).Value = textBox3.Text;
sc.Open();
sd.InsertCommand.ExecuteNonQuery();
sc.Close();
,但是当我添加值到数据库中,我得到的错误:
"ExecuteNonQuery: Connection property has not been initialized"
,我加入sc
给我的第一insertcommand
固定它,但是当我运行程序我得到另一个错误:
An explicit value for the identity column in table 'contact' can only be specified when a column list is used and IDENTITY_INSERT is ON.
这样来做:
using(SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE"))
{
using(SqlCommand command = new SqlCommand())
{
command.CommandText = "INSERT INTO contact (FirstName, LastName) VALUES(@FIRSTNAME , @LASTNAME");
command.CommandType = CommandType.Text;
command.Connection = sc;
command.Parameters.AddWithValue("@FIRSTNAME", textBox2.Text);
command.Parameters.AddWithValue("@LASTNAME", textBox3.Text);
sc.Open();
command.ExecuteNonQuery();
}
}
重要注意事项:
1)设置你的表最多有标识列作为一个标识列,并设置自动增量为真。当您插入时,这将自动生成数字ID
2)您试图插入标识列 - 除非启用标识插入,否则实际上无法执行此操作。我不会打扰 - 只需使用自动增量列并让数据库控制id生成步骤。
您可以生成你的表是这样的:
CREATE TABLE Contact
(
Id int PRIMARY KEY IDENTITY,
FirstName varchar(100),
LastName varchar(100)
)
得到一个自动增量的主键。
3)你不需要SqlDataAdapter。
我通常避免使用'SqlParameter.AddWithValue(..)'调用 - ADO.NET需要猜测传入的数据的类型,并在大多数情况下都正确 - 但它可能会出错。我喜欢**明确**定义类型,以便我没有讨厌的惊喜..... –
嗨marc_s,我从来没有出错,但那是因为我通常只是懒惰,没有定义整个参数,但是传递正确的类型 - 我知道该列是一个int,该列是一个字符串等等等等。它还使得使用KeyValuePair
...或者 - 如果 - 无论出于何种原因 - 传入的值是空值 - 哪种数据类型应该ADO。 NET *猜测*为? –
您需要将您要使用到的SqlCommand
InsertCommand = new SqlCommand("INSERT INTO contact VALUES(@ID , @FIRSTNAME , @LASTNAME)", sc);
您需要配置您的连接和命令,以及连接。这样做的标准模式是:
using (SqlConnection conn = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE")){
conn.Open();
using (SqlCommand command = new SqlCommand(sqlString, conn)){
//stuff...
command.ExecuteNonQuery();
}
}
噢是的,我不知道我是怎么忘记它的,非常感谢 –
关注评论downvote?我看不出有什么问题吗? –
有SqlConnection
和SqlDataAdapter
没有关系。其实你不需要SqlDataAdapter
。您只需要SqlConnection
和SqlCommand
,您必须使用接受连接的构造函数重载。
你需要sd.InsertCommand = new SqlCommand("INSERT INTO contact VALUES(@ID , @FIRSTNAME , @LASTNAME)", sc);
由于ID
是INT IDENTITY
字段,因此您不应(也不能)向其中插入值。但是,如果使用“通用”INSERT
语句而没有明确指定要插入值的列,则INSERT
语句将尝试将数据插入所有列 - 包括ID
,您无法插入任何内容。
解决方案(我推荐使用总是)是明确定义其列值插入:
INSERT INTO dbo.contact(FirstName, LastName) VALUES(@FIRSTNAME, @LASTNAME)
,如果你需要改变你的表并添加另一列这也适用 - 你原来的陈述将失败,因为表格现在突然有四列,但你的陈述只会提供三个值。如果您明确定义了要为其提供值的列,那么您的语句更健壮并且效果更好。
所以你完整的代码应该是这样的:
using(SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRUE"))
using(SqlCommand cmdInsert = new SqlCommand("INSERT INTO dbo.Contact(FirstName, LastName) VALUES(@FIRSTNAME, @LASTNAME)", sc))
{
cmdInsert.Parameters.Add("@FIRSTNAME", SqlDbType.VarChar, 100).Value = textBox2.Text;
cmdInsert.Parameters.Add("@LASTNAME", SqlDbType.VarChar, 100).Value = textBox3.Text;
sc.Open();
cmdInsert.ExecuteNonQuery();
sc.Close();
}
你可以做任何方式:
一个。设置你的连接对象适配器的连接的InsertCommand:
sd.InsertCommand.Connection = sc;
或者
湾在初始化插入命令时传递连接对象,如下所示:
sd.InsertCommand =
new SqlCommand("INSERT INTO contact VALUES(@ID, @FIRSTNAME, @LASTNAME)", sc);
您应该将连接创建封装在'using'语句中。 – Oded
您没有将DataAdapter连接到连接 –
为什么直接使用'DataAdapter'而不是'Command'? – Oded