只有在使用列列表并且 IDENTITY_INSERT 为 ON 时,才能为表“Fee”中的标识列指定显式值
Posted
技术标签:
【中文标题】只有在使用列列表并且 IDENTITY_INSERT 为 ON 时,才能为表“Fee”中的标识列指定显式值【英文标题】:An explicit value for the identity column in table 'Fee' can only be specified when a column list is used and IDENTITY_INSERT is ON 【发布时间】:2021-04-02 11:19:30 【问题描述】:我在 SQL Server 中创建了这个表来存储有关学生费用的数据:
create table Fee(
feeID int primary key identity(1,1),
classID int foreign key references Class(classID),
nameID int foreign key references Students(studentsID),
firstNameID int foreign key references Students(studentsID),
dateOfAdmission varchar(50),
monthKey int foreign key references Month(monthID), sum int
)
在 Visual Studio 中,我尝试使用以下方法将数据保存在表中:
private void btn_fee_Save_Click(object sender, EventArgs e)
int Class = Convert.ToInt32(cmbFeeClass.SelectedValue.ToString());
int Name = Convert.ToInt32(cmbFeeName.SelectedValue.ToString());
int firstName = Convert.ToInt32(cmbFeeFirstName.SelectedValue.ToString());
int Month = Convert.ToInt32(cmbMonth.SelectedValue.ToString());
try
if (cmbFeeClass.Text != "" && cmbFeeName.Text != "" && cmbFeeFirstName.Text != "" && cmbMonth.Text != "" && txtSum.Text != "")
cmd = new SqlCommand("insert into Fee values('"+ Class + "', '" + Name + "', '" + firstName + "', " +
"'" + dtDateOfAdmission.Text + "', '" + Month + "', '" + "', '" + txtSum.Text + "')", con.ConnectionOpening());
cmd.ExecuteNonQuery();
MessageBox.Show("The data has been saved", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Information);
else
MessageBox.Show("Please fill in all the fields!", "INFO", MessageBoxButtons.OK, MessageBoxIcon.Information);
catch (Exception ex)
MessageBox.Show(ex.Message);
con.CloseConnection();
如何更改代码以使我不再出现此错误:
【问题讨论】:
1) 使用完整的insert
语法,在其中明确指定要插入的列(始终这样做的最佳做法)。 2) 使用SqlParameter
's 传递数据,而不是连接字符串,这会让您对 SQL 注入敞开大门。
***.com/questions/14376473/…
dateOfAdmission varchar(50),
不 - 重新开始!
【参考方案1】:
您收到错误是因为您没有在 INSERT
语句中指定列。如果没有这些,SQL 将以先到先得的方式将值分配给列,并且在您的表定义中,feeID
列是第一个。 feeID
列被定义为主键标识列,并且该列值始终是自动生成的。
下面的代码展示了如何使用 Columns 部分构造 Sql 语句,并且还使用了参数。这将帮助您防止将来出现重大错误。
using (SqlConnection con = new SqlConnection(<__ADD_YOUR_CONNECTION_STRING_HERE__>))
con.open()
using (SqlCommand cmd = con.CreateCommand())
String sql = "INSERT INTO FEE ( classID, nameID, firstNameID, dateOfAdmission, monthKey)" +
"VALUES (@classID, @nameID, @firstNameID, @dateOfAdmission, @monthKey)";
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("classID", SqlDbType.Int) Value = Class );
cmd.Parameters.Add(new SqlParameter("nameID", SqlDbType.Int) Value = Name );
cmd.Parameters.Add(new SqlParameter("firstnameID", SqlDbType.Int) Value = firstName );
cmd.Parameters.Add(new SqlParameter("dateOfAdmission", SqlDbType.VarChar) Value = dtDateOfAdmission.Text );
cmd.Parameters.Add(new SqlParameter("monthKey", SqlDbType.Int) Value = Month );
command.ExecuteNonQuery();
注意:
您应该认真考虑将dateOfAdmission
列的类型从VARCHAR(50)
更改为DATE
- 这会将日期值存储为正确的日期,而不是字符串。这也将使您将来的工作更加轻松。
建议使用代码using (...)
,以确保在不需要时释放数据库资源。
【讨论】:
另外,您可能希望考虑如果任何字符串值为null
会发生什么。以上是关于只有在使用列列表并且 IDENTITY_INSERT 为 ON 时,才能为表“Fee”中的标识列指定显式值的主要内容,如果未能解决你的问题,请参考以下文章
我的(Vba)代码仅适用于列表中的1个变量,并且在列表框中使用多个变量时仅返回空白
仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'xxxx'中的标识列指定显式值
仅当使用列列表并且 IDENTITY_INSERT 为 ON [重复] 时,才能指定表“客户”中标识列的显式值