单击vb中的添加按钮后,如果您不将文本框字段保留为null或为空,则代码执行良好
但是当将某些字段留空时会返回错误
无法将参数值从String转换为Int32
STORED PROC
CREATE PROCEDURE AddOfficeEquipmentProfile
(
@OE_ID varchar(11),
@OE_Category char(3) =NULL,
@OE_SubCategory char(3)= NULL,
@OE_Name varchar(35)=NULL,
@OE_User varchar(35)=NULL,
@OE_Brand varchar(15)=NULL,
@OE_Model varchar(35)=NULL,
@OE_Specs varchar(1000)=NULL,
@OE_SerialNo varchar(35)=NULL,
@OE_PropertyNo varchar(35)=NULL,
@OE_MacAddress varchar(100)=NULL,
@OE_Static_IP varchar(15)=NULL,
@OE_Vendor varchar(35)=NULL,
@OE_PurchaseDate smalldatetime,
@OE_WarrantyInclusiveYear int=NULL,
@OE_WarrantyStatus char(2)= NULL,
@OE_Status varchar(15)=NULL,
@OE_Dept_Code char(3)= NULL,
@OE_Location_Code char(8)= NULL,
@OE_Remarks varchar(1000)= NULL
)
AS
INSERT INTO tblOfficeEquipmentProfile (OE_ID, OE_Category, OE_SubCategory, OE_Name, OE_User, OE_Brand, OE_Model, OE_Specs, OE_SerialNo,
OE_PropertyNo, OE_MacAddress, OE_Static_IP, OE_Vendor, OE_PurchaseDate, OE_WarrantyInclusiveYear, OE_WarrantyStatus, OE_Status, OE_Dept_Code,
OE_Location_Code, OE_Remarks )
VALUES (@OE_ID, @OE_Category, @OE_SubCategory, @OE_Name, @OE_User, @OE_Brand, @OE_Model,
@OE_Specs, @OE_SerialNo, @OE_PropertyNo, @OE_MacAddress, @OE_Static_IP, @OE_Vendor, @OE_PurchaseDate, @OE_WarrantyInclusiveYear, @OE_WarrantyStatus,
@OE_Status, @OE_Dept_Code, @OE_Location_Code, @OE_Remarks)
GO
VB.NET代码
cmd.CommandType = CommandType.StoredProcedure
cmd.CommandText = "AddOfficeEquipmentProfile"
cmd.Parameters.Add("@OE_ID", SqlDbType.VarChar, 11, "oeq-su-999")
cmd.Parameters.Add("@OE_Category", SqlDbType.Char, 3, "COM").Value = DBNull.Value
cmd.Parameters.Add("@OE_SubCategory", SqlDbType.Char, 3, "SU").Value = DBNull.Value
cmd.Parameters.Add("@OE_Name", SqlDbType.VarChar, 35, "adminpmis01").Value = DBNull.Value
cmd.Parameters.Add("@OE_User", SqlDbType.VarChar, 35, "Ivan").Value = DBNull.Value
cmd.Parameters.Add("@OE_Brand", SqlDbType.VarChar, 15, "DELL").Value = DBNull.Value
cmd.Parameters.Add("@OE_Model", SqlDbType.VarChar, 35, "optiplex").Value = DBNull.Value
cmd.Parameters.Add("@OE_Specs", SqlDbType.VarChar, 1000, "dualcore").Value = DBNull.Value
cmd.Parameters.Add("@OE_SerialNo", SqlDbType.VarChar, 35, "sgh5960").Value = DBNull.Value
cmd.Parameters.Add("@OE_PropertyNo", SqlDbType.VarChar, 35, "j7h7h6g6f2").Value = DBNull.Value
cmd.Parameters.Add("@OE_MacAddress", SqlDbType.VarChar, 100, "j7h7:h6g6f2").Value = DBNull.Value
cmd.Parameters.Add("@OE_Static_IP", SqlDbType.VarChar, 15, "192.168.1.5").Value = DBNull.Value
cmd.Parameters.Add("@OE_Vendor", SqlDbType.VarChar, 35, "ADWAYS").Value = DBNull.Value
cmd.Parameters.Add("@OE_PurchaseDate", SqlDbType.DateTime)
cmd.Parameters.Add("@OE_WarrantyInclusiveYear", SqlDbType.Int).Value = DBNull.Value
cmd.Parameters.Add("@OE_WarrantyStatus", SqlDbType.Char, 2, "IN").Value = DBNull.Value
cmd.Parameters.Add("@OE_Status", SqlDbType.VarChar, 15, "Good").Value = DBNull.Value
cmd.Parameters.Add("@OE_Dept_Code", SqlDbType.Char, 3, "ADM").Value = DBNull.Value
cmd.Parameters.Add("@OE_Location_Code", SqlDbType.Char, 8, "ADM_OFC").Value = DBNull.Value
cmd.Parameters.Add("@OE_Remarks", SqlDbType.VarChar, 1000, "ACTIVE").Value = DBNull.Value
cmd.Parameters("@OE_ID").Value = txtOEID.Text
cmd.Parameters("@OE_Category").Value = cmbCategory.Text
cmd.Parameters("@OE_SubCategory").Value = cmbSubCategory.Text
cmd.Parameters("@OE_Name").Value = txtName.Text
cmd.Parameters("@OE_User").Value = txtUser.Text
cmd.Parameters("@OE_Brand").Value = cmbBrand.Text
cmd.Parameters("@OE_Model").Value = cmbModel.Text
cmd.Parameters("@OE_Specs").Value = txtSpecs.Text
cmd.Parameters("@OE_SerialNo").Value = txtSerialNo.Text
cmd.Parameters("@OE_PropertyNo").Value = txtPropertyNo.Text
cmd.Parameters("@OE_MacAddress").Value = txtMacAddress.Text
cmd.Parameters("@OE_Static_IP").Value = txtStaticIP.Text
cmd.Parameters("@OE_Vendor").Value = txtVendor.Text
cmd.Parameters("@OE_PurchaseDate").Value = dtpPurchaseDate.Value
cmd.Parameters("@OE_WarrantyInclusiveYear").Value = txtWarrantyInclusiveYear.Text
cmd.Parameters("@OE_WarrantyStatus").Value = txtWarrantyStatus.Text
cmd.Parameters("@OE_Status").Value = txtStatus.Text
cmd.Parameters("@OE_Dept_Code").Value = cmbDeptCode.Text
cmd.Parameters("@OE_Location_Code").Value = cmbLocationCode.Text
cmd.Parameters("@OE_Remarks").Value = txtRemarks.Text
cmd.ExecuteNonQuery()
sqlconn.Close()
答案 0 :(得分:2)
??运算符可以帮助您轻松检查Null值。
示例:
cmd.Parameters("@OE_ID").Value = txtOEID.Text ?? DBNull.Value;
cmd.Parameters("@OE_Category").Value = cmbCategory.Text ?? DBNull.Value;
答案 1 :(得分:2)
我认为您缺少的是(因为您在过去几天内多次询问此问题的变体,因此了解表单中的控件如何映射到您与{{{{{{{ 1}},反过来那些SqlCommand
参数如何映射到存储过程的参数。缺乏理解(因为你正在学习,缺乏并不是坏事)加上如何处理NULL价值观让你无穷无尽。
我会尝试解释整个概念,而不是单独回答一个问题,因此您可以将其应用于编写代码时可能遇到的任何情况。
首先,您的表单上有一组SqlCommand
和TextBox
控件。这两个控件都具有ComboBox
属性 - 此属性始终返回一个字符串,即使您在其中放入12345或10/01/2007也是如此。这意味着您必须将从Text
或TextBox.Text
获得的字符串转换(转换)为相关存储过程参数的相应数据类型(除非其CHAR / VARCHAR或类似内容)。
创建ComboBox.Text
对象时,您将向参数集添加参数。顺便说一下,这是非常好的练习,并且对你学习它感到荣幸 - 因为它会缓解SQL注入攻击(在WinForm应用程序中并不总是高风险,但它是一个很好的编码实践进入。
您添加到SqlCommand
的{{1}}个对象需要与存储过程中的参数相匹配,这也是一个好处。但是,看起来您可能尝试在第四个参数中传递默认值,并且该参数不是用于设置默认值,而是用于在UPDATE语句中指定源列。
最后,您有了存储过程。不需要任何参数 - 因此您可以安全地接受在表单中没有值的任何参数。实质上,当您在存储过程中的参数上设置默认值(NULL或其他)时,您可以从调用中省略该参数,SQL Server将使用您在存储过程的声明中指定的默认值。 / p>
您正在代码中执行额外的工作 - 首先您将参数all设置为null,然后通过将值设置为等于表单上的相应控件来覆盖该分配。这是你遇到大部分麻烦的地方。
正如其他人至少在你的几个问题上建议的那样,我会检查控件是否有值 - 如果是,则将参数及其值添加到集合中(根据需要进行转换)。这将减少您的“双重”任务。
所以它看起来像这样:
SqlParameter
等等。当你有一个非VARCHAR / CHAR参数时,你需要做一些额外的工作(因为你在购买日期使用SqlCommand
,If txtOEID.Text.Trim() <> "" Then
cmd.Parameters.Add("@OE_ID", SqlDbType.VarChar, 11).Value = txtOEID.Text.Trim()
End If
If cmbCategory.Text.Trim() <> "" Then
cmd.Parameters.Add("@OE_Category", SqlDbType.Char, 3).Value = cmbCategory.Text.Trim()
End If
属性已经是{{1所以你不必担心它):
DateTimePicker
在上面的例子中,我建议使用Value
来增加你不会意外地尝试解析非数字值的机会(因为你使用的是VS 2003 / .NET 1.1 DateTime
不是可用)。
简而言之,当您在应用程序中创建参数时,您需要了解从用户传入的数据类型以及存储过程所期望的数据类型。如果它们不匹配,则在将参数添加到集合时,您需要将用户输入转换为存储过程的正确数据类型。
如果参数具有在存储过程中指定的默认值,则只需在用户未提供值时跳过添加参数即可。虽然在NULL的情况下,请确保您插入的目标列标记为NULLABLE。
我强烈建议您转储VS 2003并利用VS 2012的 Express 版本,因为您错过了一大堆功能,这将使您作为程序员的生活更轻松。
如果您需要澄清任何事情,请询问。
答案 2 :(得分:0)
尝试对所有值使用内联IF
。
cmd.Parameters("@OE_ID").Value = If(txtOEID.Text.Trim().Length > 0, txtOEID.Text, DBNull.Value)
它的作用是首先修剪弦,然后检查它的长度。如果长度大于零,则在true
部分传递字符串,否则传递DBNull.Value
。
答案 3 :(得分:0)
因为将字符串转换为int并且我看到的唯一int是@OE_WarrantyInclusiveYear
参数。在您的代码中,您可以安全地尝试转换为int。
Dim year As Integer
If Integer.TryParse(txtWarrantyInclusiveYear.Text, year) Then
cmd.Parameters("@OE_WarrantyInclusiveYear").Value = year
End If