Разрешить сохранение нулевых значений в базе данных

Я использую Visual Studio .NET 2003, кнопка добавления работает нормально, когда все текстовые поля, поля со списком заполнены данными, но при тестировании, не заполняя поля данными, оставляя его NULL, он возвращает ошибку, говорящую: «Строка не была распознана как допустимый DateTime»

У меня есть текстовое поле с именем txtPurchasedDate.

Моя хранимая процедура

 CREATE PROCEDURE AddOfficeEquipmentProfile
    (
    @OE_ID      varchar(11)     =   NULL,
    @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       =   NULL,
    @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)

    IF @@ERROR<>0
        BEGIN
            ROLLBACK TRANSACTION
            RETURN 0
        END 
    ELSE
        BEGIN
            COMMIT TRANSACTION
            RETURN 1
        END
    GO

Мой код кнопки добавления Vb.net

 Dim cmd As SqlCommand = sqlconn.CreateCommand
        sqlconn.Open()
        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")
    cmd.Parameters.Add("@OE_SubCategory", SqlDbType.Char, 3, "SU")
    cmd.Parameters.Add("@OE_Name", SqlDbType.VarChar, 35, "adminpmis01")
    cmd.Parameters.Add("@OE_User", SqlDbType.VarChar, 35, "Ivan")
    cmd.Parameters.Add("@OE_Brand", SqlDbType.VarChar, 15, "DELL")
    cmd.Parameters.Add("@OE_Model", SqlDbType.VarChar, 35, "optiplex")
    cmd.Parameters.Add("@OE_Specs", SqlDbType.VarChar, 1000, "dualcore")
    cmd.Parameters.Add("@OE_SerialNo", SqlDbType.VarChar, 35, "sgh5960")
    cmd.Parameters.Add("@OE_PropertyNo", SqlDbType.VarChar, 35, "j7h7h6g6f2")
    cmd.Parameters.Add("@OE_MacAddress", SqlDbType.VarChar, 100, "j7h7:h6g6f2")
    cmd.Parameters.Add("@OE_Static_IP", SqlDbType.VarChar, 15, "192.168.1.5")
    cmd.Parameters.Add("@OE_Vendor", SqlDbType.VarChar, 35, "ADWAYS")

    cmd.Parameters.Add("@OE_PurchaseDate", SqlDbType.SmallDateTime)
    cmd.Parameters.Add("@OE_WarrantyInclusiveYear", SqlDbType.Int)
    cmd.Parameters.Add("@OE_WarrantyStatus", SqlDbType.Char, 2, "IN")
    cmd.Parameters.Add("@OE_Status", SqlDbType.VarChar, 15, "Good")
    cmd.Parameters.Add("@OE_Dept_Code", SqlDbType.Char, 3, "ADM")
    cmd.Parameters.Add("@OE_Location_Code", SqlDbType.Char, 8, "ADM_OFC")
    cmd.Parameters.Add("@OE_Remarks", SqlDbType.VarChar, 1000, "ACTIVE")
    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 = txtPurchaseDate.Text
    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()
    MsgBox("Successfully Added Equipment Profile")
    sqlconn.Close()

person ivandinglasan    schedule 02.05.2013    source источник
comment
в каком формате вы передаете дату покупки?   -  person Jason    schedule 02.05.2013
comment
если вы передаете нулевую дату, вы должны быть уверены, что ваша база данных настроена на разрешение нулевых значений. Для каждого столбца можно настроить разрешение нулевых значений.   -  person Jason    schedule 02.05.2013
comment
@Jason Джейсон, да, сэр, он разрешает нули, я проверил свою базу данных, что мне делать тогда   -  person ivandinglasan    schedule 02.05.2013
comment
@ Джейсон, он делает эту часть правильно. Он передает свой параметр PurchaseDate как smalldatetime, что делает формат неактуальным. Единственный формат времени имеет значение для дат и времени, когда вы их отображаете.   -  person Dan Bracuk    schedule 02.05.2013
comment
Сколько раз вы планируете задавать один и тот же (или похожий) вопрос? stackoverflow.com/q/16232173/745969, stackoverflow.com/q/16291644/745969, stackoverflow.com/q/16293543/745969 этот...?   -  person Tim    schedule 02.05.2013
comment
Просто из любопытства, почему вы используете VS 2003? Поддерживаете ли вы приложение 1.1, которое руководство/клиент отказывается разрешить вам обновить до более новой версии .NET? Вы можете получить бесплатные (экспресс) выпуски 2010 и 2012 годов.   -  person Tim    schedule 02.05.2013
comment
@Tim да, это бесплатная загрузка, но пробная версия на 30 дней   -  person ivandinglasan    schedule 02.05.2013
comment
@ivandinglasan - я говорю о Visual Studio *EXPRESS, которая бесплатна. Взгляните на microsoft.com/visualstudio/eng/downloads и прокрутите вниз до раздела Visual Studio Express 2012 и загрузите любой из них, который вам подходит. Вы сильно ограничиваете себя и свои возможности обучения, используя VS 2003.   -  person Tim    schedule 02.05.2013


Ответы (3)


Если вы хотите сохранить нулевые значения, вы должны использовать условную логику в своем коде vb, чтобы либо не отправлять эти параметры в хранимую процедуру, либо отправлять значение dbnull. Даже ваши поля char хранят пустые строки, что может не соответствовать вашим намерениям.

person Dan Bracuk    schedule 02.05.2013
comment
как будет синтаксис и логика, сэр? - person ivandinglasan; 02.05.2013
comment
@JohnFx Я бы не стал задавать вопрос, если бы у меня не закончились идеи, я уже пробовал dbNULL. Я сначала пробую разные вещи и изучаю Google, прежде чем публиковать - person ivandinglasan; 02.05.2013
comment
он уже сказал вам ответ, теперь вы просите его напечатать его на выходе. - person JohnFx; 02.05.2013
comment
ну, может быть, я не такой гений, как вы, сэр @JohnFx, что вы можете понять каждую мелочь - person ivandinglasan; 02.05.2013
comment
Вызывать вас из-за недостатка усилий, а не из-за отсутствия понимания. - person JohnFx; 02.05.2013
comment
откуда вы вообще знаете, что я не прилагаю усилий, если вы даже не видите мое рабочее пространство и представление дизайна vb - person ivandinglasan; 02.05.2013

Использовать

If (Not String.IsNullOrEmpty(txtPurchaseDate.Text)) Then
    cmd.Parameters("@OE_PurchaseDate").Value = txtPurchaseDate.Text
End If
person Ryan    schedule 02.05.2013
comment
Проверка IsNull(txtPurchaseDate.Text) может не быть строго необходимой - я думаю, что txtPurchaseDate.Text будет пустой строкой, если она не установлена. Вы можете проверить это, проверив значение во время выполнения. Хотя, наверное, это безопаснее, чем не включать чек. - person Ryan; 02.05.2013
comment
IsNull не объявлен, сэр. - person ivandinglasan; 02.05.2013
comment
Извините, код, который я дал, был VBA. Вместо этого вы можете использовать String.IsNullOrEmpty(txtPurchaseDate.Text) в качестве проверки для VB. - person Ryan; 02.05.2013
comment
String.IsNullOrEmpty недоступен в 1.1 - OP использует VS 2003, согласно тегам вопроса. - person Tim; 02.05.2013
comment
Затем используйте txtPurchaseDate.Text ‹› - person Ryan; 02.05.2013

Почему бы не использовать DateTimePicker для вашего PurchaseDate вместо текстового поля в txtPurchaseDate.Text, вы можете назвать свой элемент управления dtpPurchaseDate, тогда у вас есть:

cmd.Parameters("@OE_PurchaseDate").Value = dtpPurchaseDate.Value

Значение по умолчанию (или минимальное значение) для средства выбора даты и времени равно 1/1/1980, поэтому вы можете инициализировать значение dtpPurchaseDate до 1/1/1980, например:

dtpPurchaseDate = System.DateTime.Parse("1/1/1980")

Итак, это означает, что при сохранении в вашей базе данных оно имеет значение 01.01.1980, а не NULL.

Если вы хотите использовать кошелек с текстовым полем, вы можете проверить, пусто ли оно, а затем назначить минимальное значение даты, которое на самом деле равно 1/1/0001, например:

If (If (String.IsNullOrEmpty(txtPurchaseDate.Text)) Then
   cmd.Parameters("@OE_PurchaseDate").Value = DBNull.Value  
Else
   Dim tempPurchaseDate as DateTime

   System.DateTime.TryParse(txtPurchaseDate.Text, tempPurchaseDate)
   cmd.Parameters("@OE_PurchaseDate").Value = tempPurchaseDate         
End If

Но опять же, он имеет сохраненное значение в вашей базе данных как 01.01.0001.

Вы можете отобразить его пустым в текстовом поле, например: Учитывая, что у вас есть DataRow с именем dr

If (dr["OE_PurchaseDate"] = System.DateTime.Parse("1/1/0001")) Then
   txtPurchaseDate.Text = ""
Else
   txtPurchaseDate.Text = dr["OE_PurchaseDate"]
End If
person Edper    schedule 02.05.2013
comment
при использовании средства выбора даты и времени, что, если я оставлю его в покое, ничего не меняя, что будет датой по умолчанию? - person ivandinglasan; 02.05.2013