C#:SQL Server查询问题

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

我使用以下代码在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=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语句弄混了。我编辑了答案以反映这一点。