为sql参数设置默认值null

时间:2013-05-04 03:36:54

标签: sql vb.net

单击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()

4 个答案:

答案 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价值观让你无穷无尽。

我会尝试解释整个概念,而不是单独回答一个问题,因此您可以将其应用于编写代码时可能遇到的任何情况。

首先,您的表单上有一组SqlCommandTextBox控件。这两个控件都具有ComboBox属性 - 此属性始终返回一个字符串,即使您在其中放入12345或10/01/2007也是如此。这意味着您必须将从TextTextBox.Text获得的字符串转换(转换)为相关存储过程参数的相应数据类型(除非其CHAR / VARCHAR或类似内容)。

创建ComboBox.Text对象时,您将向参数集添加参数。顺便说一下,这是非常好的练习,并且对你学习它感到荣幸 - 因为它会缓解SQL注入攻击(在WinForm应用程序中并不总是高风险,但它是一个很好的编码实践进入。

您添加到SqlCommand的{​​{1}}个对象需要与存储过程中的参数相匹配,这也是一个好处。但是,看起来您可能尝试在第四个参数中传递默认值,并且该参数不是用于设置默认值,而是用于在UPDATE语句中指定源列。

最后,您有了存储过程。不需要任何参数 - 因此您可以安全地接受在表单中没有值的任何参数。实质上,当您在存储过程中的参数上设置默认值(NULL或其他)时,您可以从调用中省略该参数,SQL Server将使用您在存储过程的声明中指定的默认值。 / p>

您正在代码中执行额外的工作 - 首先您将参数all设置为null,然后通过将值设置为等于表单上的相应控件来覆盖该分配。这是你遇到大部分麻烦的地方。

正如其他人至少在你的几个问题上建议的那样,我会检查控件是否有值 - 如果是,则将参数及其值添加到集合中(根据需要进行转换)。这将减少您的“双重”任务。

所以它看起来像这样:

SqlParameter

等等。当你有一个非VARCHAR / CHAR参数时,你需要做一些额外的工作(因为你在购买日期使用SqlCommandIf 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