C#:SQL Server查询问题
我使用以下代码在SQL Server Management Studio中创建一个表:C#:SQL Server查询问题,c#,sql,sql-server,C#,Sql,Sql Server,我使用以下代码在SQL Server Management Studio中创建一个表: CREATE TABLE contact( ID INT IDENTITY NOT NULL, FIRSTNAME VARCHAR(100), LASTNAME VARCHAR(100) ) SqlConnection sc = new SqlConnection("Data Source=.\\SQLSERVER; Initial Catalog=BOSS; Integrated Security=TRU
CREATE TABLE contact(
ID INT IDENTITY NOT NULL,
FIRSTNAME VARCHAR(100),
LASTNAME VARCHAR(100)
)
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();
在C#中,我使用了以下代码:
CREATE TABLE contact(
ID INT IDENTITY NOT NULL,
FIRSTNAME VARCHAR(100),
LASTNAME VARCHAR(100)
)
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();
但当我将值添加到数据库时,会出现错误:
“ExecuteOnQuery:连接属性尚未初始化”
我通过将sc
添加到我的第一个insertcommand
来修复它,但是当我运行程序时,我遇到了另一个错误:
表“contact”中标识列的显式值只能为
在使用列列表且启用IDENTITY_INSERT时指定
您需要将要使用的连接传递给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();
}
}
SqlConnection
和SqlDataAdapter
之间没有关系
实际上,您不需要
SqlDataAdapter
。您只需要SqlConnection
和SqlCommand
,对于它们,您必须使用接受连接的构造函数重载。您需要sd.InsertCommand=new SqlCommand(“插入到联系人值(@ID,@FIRSTNAME,@LASTNAME)”,sc)代码>按以下方式执行:
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();
}
}
CREATE TABLE Contact
(
Id int PRIMARY KEY IDENTITY,
FirstName varchar(100),
LastName varchar(100)
)
需要注意的重要事项:
1) 将表设置为将Id列作为标识列,并将autoincrement设置为true。这将在插入时自动生成数字id
2) 您正试图插入到标识列中-除非启用标识插入,否则实际上无法执行此操作。我不想麻烦-只需使用自动增量列,让数据库控制id生成步骤
您可以通过以下方式生成表格:
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();
}
}
CREATE TABLE Contact
(
Id int PRIMARY KEY IDENTITY,
FirstName varchar(100),
LastName varchar(100)
)
获取自动递增的主键
3) 您不需要SqlDataAdapter。因为ID
是一个INT-IDENTITY
字段,所以不应该(也不能)在其中插入值。但是,如果使用“generic”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();
}
您可以采用以下两种方式:
a。将连接对象设置为适配器的insertcommand连接:
sd.InsertCommand.Connection = sc;
或
b。初始化insert命令时传递连接对象,如下所示:
sd.InsertCommand =
new SqlCommand("INSERT INTO contact VALUES(@ID, @FIRSTNAME, @LASTNAME)", sc);
您应该使用
语句将连接创建包装在中。您没有将DataAdapter连接到连接为什么要直接使用DataAdapter
而不是命令?我遇到了另一个问题:只有在列列表已被使用,标识插入已打开。如果您想得到答案,请将您的新问题放入新问题中。哦,是的,我不知道我是怎么忘记的,感谢lotCare对否决票发表评论?我看不出答案有什么问题吗?我通常避免使用SqlParameter.AddWithValue(…)
call-ADO.NET需要猜测传入的数据类型,并且在大多数情况下都是正确的-但它可能会出现可怕的错误。我更喜欢显式地定义类型,这样我就不会有令人不快的惊喜……嗨,marc_s,我从来没有让它出错过,但那是因为我通常很懒,没有定义整个参数,而是传递正确的类型——我知道该列是int,该列是字符串等等。它还使使用KeyValuePair样式方法编写通用的运行存储过程变得容易。不过,这是一个公平的评论,特别是当用户直接从由用户输入驱动的字段调用存储的proc:-)。。。或者,无论出于何种原因,如果传入的值是null
,ADO.NET应该猜测什么样的数据类型???我总是解析它并提供DBNull.value,但是,注意:-)谢谢marc_s-我目前正在使用MySql做一些事情,并且把create语句弄混了。我编辑了答案以反映这一点。