Oracle.ManagedDataAccess Procedures with Date as a Parameter causing exception - vb.net

create or replace PROCEDURE PROCEDURE_ONE(
T1_CURSOR OUT SYS_REFCURSOR,
Date_Start_P in Date Default sysdate
)
as
begin
OPEN T1_CURSOR FOR ...
This works when testing with Oracle SQL Developer
My VB.Net code doesn't like the parameter
Private Function Load_Aging_Stock() As DataTable
Try
Dim dba As New Data_Access_Class
Dim strSQL As String = "JOHN.PROCEDURE_ONE"
Dim dt As DataTable
Dim cmd As OracleCommand = dba.CreateStoredProcCommand(strSQL)
Dim oracleParameter(1) As OracleParameter
oracleParameter(0) = New OracleParameter()
oracleParameter(1) = New OracleParameter()
cmd.BindByName = True
With cmd
oracleParameter(0) = cmd.Parameters.Add("T1_Cursor", dbType:=Oracle.ManagedDataAccess.Client.OracleDbType.RefCursor, ParameterDirection.Output)
'.Parameters.Add("T1_CURSOR", OracleClient.OracleType.Cursor).Direction = ParameterDirection.Output
If Me.chk_No_Date_Start.Checked = False Then
Dim tmpDate As String = CDate(Me.dt_Start_Date.Text.Trim).ToString("yyyy-MM-dd")
oracleParameter(1) = cmd.Parameters.Add("Date_Start_P", dbType:=Oracle.ManagedDataAccess.Client.OracleDbType.Varchar2, val:=tmpDate, ParameterDirection.Input)
'.Parameters.Add("Date_Start_P", OracleClient.OracleType.DateTime).Value = Me.dt_Start_Date.Text
End If
End With
dt = dba.ExecuteSelectCmdDataTbl(cmd)
Return dt
Catch ex As Exception
Dim Err As New SS_Errors("frm__Report", "Load_Report", ex)
Return Nothing
End Try
End Function
I've also tried the same code but replaced Varchar2 with Date and both times, I get the same exception
One of the identified items was in an invalid format.

Don't pass the string as parameter value, just use the Date value, i.e.
oracleParameter(1) = cmd.Parameters.Add("Date_Start_P", dbType:=OracleDbType.Date, val:=CDate(Me.dt_Start_Date.Text.Trim), ParameterDirection.Input)

Related

Variable 'reader' is used before it has been assigned a value. A null reference exception could result at run time

Trying to fix a warning and not sure how to restructure code as reader.IsClosed is throwing a warning that states "Variable 'reader' is used before it has been assigned a value. A null reference exception could result at run time." Logistically, since reader As SqlDataReader && reader is not initialized with a value then I could ignore as should be fine at runtime, but my inexperience would make me believe there is a better way?
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT"))
Dim spName As String = Me.GetStoreProcname()
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CInt(value)
End If
End If
Catch ex As Exception
Throw
Finally
If Not reader.IsClosed Then
reader.Close()
End If
End Try
Return 0
End Function
We can narrow the problem down to this excerpt:
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader( ... )
Finally
If Not reader.IsClosed Then reader.Close()
End Try
The problem comes if an exception is thrown by the ExecuteReader() function. In that event, the reader variable is never assigned a value. It's still Nothing when you try to evaluate reader.IsClosed, and that will cause an exception.
Given you don't actually do anything with the exception and the SqlHelper takes care of the connection and command objects, you can narrow the entire function down to just this:
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam = {
New SqlClient.SqlParameter("#" + Me.GetMetaData().PrimaryKey.ColumnName, 0),
New SqlClient.SqlParameter("#UserID", userId),
New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT")
}
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam)
If reader.Read() Then Return CInt(reader(0))
End Using
Return 0
End Function
#jmcilhinney, #o_O, #Chris Dunaway ... Thank you for the help + appreciation + admiration for your knowledge + reverence == deverence(); ... This removed the error:
Public Function GetTotalAmount(ByVal userId As Long) As Decimal
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_TOTAL_AMOUNT"))
Dim spName As String = Me.GetStoreProcname()
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CDec(value)
End If
End If
End Using
Return 0
End Function

oracle bulkcopy from vb.net databale

I am loading the CSV file to vb.net datatable .
then I am using Bulk copy command to write to database.
The problem is if one date cell in the data table is empty, i am receiving
ORA:-01840 input value not long enough for date format.
How to resolve this.
Public Class Form1
Dim cn As New OracleConnection("Data Source =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = ipaddressofserver)(PORT = portofserver))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = oracleservicename)) ) ; User Id=useridofdb;Password=passwordofdb")
cn.Open()
MsgBox("connection opened")
Dim dt As DataTable = ReadCSV("D:\test.csv")
DataGridView1.DataSource = dt
Try
Dim _bulkCopy As New OracleBulkCopy(cn)
_bulkCopy.DestinationTableName = "TEST_TABLE"
_bulkCopy.BulkCopyTimeout = 10800
_bulkCopy.WriteToServer(dt)
cn.Close()
cn.Dispose()
cn = Nothing
MsgBox("Finished")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Function ReadCSV(ByVal path As String) As System.Data.DataTable
Try
Dim sr As New StreamReader(path)
Dim fullFileStr As String = sr.ReadToEnd()
sr.Close()
sr.Dispose()
Dim lines As String() = fullFileStr.Split(ControlChars.Lf)
Dim recs As New DataTable()
Dim sArr As String() = lines(0).Split(","c)
For Each s As String In sArr
recs.Columns.Add(New DataColumn())
Next
Dim row As DataRow
Dim finalLine As String = ""
For Each line As String In lines
row = recs.NewRow()
finalLine = line.Replace(Convert.ToString(ControlChars.Cr), "")
row.ItemArray = finalLine.Split(","c)
recs.Rows.Add(row)
Next
Return recs
Catch ex As Exception
Throw ex
End Try
End Function
End Class

DBNull value for parameter is not supported. Table-valued parameters cannot be DBNull

I am currently trying to pass a two table value parameters from a .net application to a database.
The error that I am getting is
DBNull value for parameter '#StageNotes' is not supported. Table-valued parameters cannot be DBNull.
I have checked that the parameter value is not null when I pass it, and the error that I get is not a sqlException, rather just a general Exception that passes this error back
The parameters are declared like so
Dim stageNotesparamTable2SQL As New SqlParameter("#StageNotes", SqlDbType.Structured)
Dim responsesParamTable2SQL As New SqlParameter("#Responses", SqlDbType.Structured)
and the values are assigned like this
Dim responseTable = ResponsesToDt()
responsesParamTable2SQL.Value = responseTable
Dim stageTable = StageNotesToDt()
stageNotesparamTable2SQL.Value = stageTable
The parameters are declared in the stored proc like this
#StageNotes [App].[StageNotesTableType] READONLY,
#Responses [app].QuestionResponseTableType READONLY,
When debugging I see that the stageNotesparamTable2SQL.Value is showing that there is a datatable in there and has the data so it is definitely not null.
I would be grateful if anyone could help me with this.
thanks
-- edit ---
Protected Function ResponsesToDt() As DataTable
Dim dt As New DataTable()
dt.Columns.Add("CheckId", GetType(Integer))
dt.Columns.Add("QuestionId", GetType(Integer))
dt.Columns.Add("AnswerId", GetType(Integer))
dt.Columns.Add("StaffNumber", GetType(String)).MaxLength = 15
Dim dictValues = _dicOfControlsAndValues.Where(Function(x) x.Key.Contains("ddl_Stage_"))
For Each item In dictValues
Dim ddlIdBreakDown = item.Key.ToString().Split("_").ToList
Dim checkid As Integer = item.Key.ToString().Split("_").Last
Dim questionId As Integer = Convert.ToInt16(ddlIdBreakDown(4))
Dim answerId As Integer = Convert.ToInt16(item.Value)
Dim staffNumber As String = GetLoggedOnStaffNumber()
dt.Rows.Add(checkid, questionId, answerId, staffNumber)
Next
Return dt
End Function
Protected Function StageNotesToDt() As DataTable
Dim dt As New DataTable
dt.Columns.Add("CheckId", GetType(Integer))
dt.Columns.Add("StageId", GetType(Integer))
dt.Columns.Add("StageNotes", GetType(String))
dt.Columns.Add("ModifiedDate", GetType(String))
Dim dictValues = _dicOfControlsAndValues.Where(Function(x) x.Key.Contains("textArea_Stage"))
For Each item In dictValues
Dim stageNote As String = String.Empty
Dim ddlIdBreakDown = item.Key.ToString().Split("_").ToList
If String.IsNullOrEmpty(item.Value.ToString()) Then
stageNote = "."
Else
stageNote = item.Value.ToString()
End If
Dim checkid As Integer = item.Key.ToString().Split("_").Last
Dim stageId As Integer = Convert.ToInt16(ddlIdBreakDown(2))
Dim stageNotes As String = stageNote
Dim modifiedDate As DateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")
dt.Rows.Add(checkid, stageId, stageNotes, modifiedDate)
Next
Return dt
End Function
-- edit 2 --
DAL.ExecCommand("[App].[usp_SaveCheckDetails]", "",
checkIdParam,
userIdParam,
caseNoteParam,
checkNoteParam,
checkCompletedParam,
CheckFeedbackSentToUserId,
stageNotesparamTable2SQL,
responsesParamTable2SQL)
Then the DAL im having to call.
The DAL is a shared repo that Im not able to edit at the moment:
Public Function ExecCommand(ByVal spName As String, ByVal connStringName As String, ByVal ParamArray SPParms() As SqlClient.SqlParameter) As Boolean
Dim SqlConnection As New SqlConnection
Dim sqlCommand As New SqlClient.SqlCommand
Dim returnCode As Boolean = False
Try
If connStringName <> "" Then
SqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings(connStringName).ConnectionString
Else
SqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString
End If
sqlCommand.CommandType = CommandType.StoredProcedure
sqlCommand.CommandText = spName
For Each p As SqlParameter In SPParms
If p.Direction <> ParameterDirection.Output Then
If Not p.Value.GetType() = GetType(Integer) Then
If p.Value.ToString() = "" OrElse p.Value = Nothing Then
p.Value = DBNull.Value
End If
End If
End If
sqlCommand.Parameters.Add(p)
Next
sqlCommand.Connection = SqlConnection
SqlConnection.Open()
sqlCommand.ExecuteNonQuery()
returnCode = True
Catch sqlEx As SqlException
HelpersErrorHandling.WriteAppLogEntry(Me.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().ToString, sqlEx)
Catch ex As Exception
If Not ex.Message.ToString().Contains("Thread was being aborted") Then
HelpersErrorHandling.WriteAppLogEntry(Me.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().ToString, ex)
End If
Finally
Try
sqlCommand.Parameters.Clear()
sqlCommand.Dispose()
SqlConnection.Close()
SqlConnection.Dispose()
Catch ex As Exception
HelpersErrorHandling.WriteAppLogEntry(Me.GetType().Name, System.Reflection.MethodBase.GetCurrentMethod().ToString, ex)
End Try
End Try
Return returnCode
End Function

'Value of type string cannot be converted to system.data.datatable' in vb.net

This is my code. I keep having an error "value of type string cannot be converted to system.data.datatable"
Function GetTable() As DataTable
Dim SQLConnection As New SqlConnection(ConfigurationManager.ConnectionStrings("Zeinchatconnection").ToString())
Dim CommSQL As New SqlClient.SqlCommand
Dim ChatDataAdapter As SqlDataAdapter
Dim paramSQL As SqlClient.SqlParameter
Dim DStable As DataSet
Dim table As New DataTable
Dim szName As String = ""
Dim szNumber As String = ""
Try
If SQLConnection.State = ConnectionState.Closed Then
SQLConnection.Open()
End If
CommSQL.Connection = SQLConnection
CommSQL.CommandType = CommandType.StoredProcedure
CommSQL.CommandText = "spc_newselect"
CommSQL.ExecuteNonQuery()
ChatDataAdapter = New SqlDataAdapter(CommSQL)
ChatDataAdapter.Fill(DSTable)
table.Rows.Clear()
table.Clear()
table = DStable.Tables(0)
Dim i As Integer = 0
For i = 0 To table.Rows.Count - 1
szName = szName & " " & table.Rows(i).Item(0) & table.Rows(i).Item(1)
szNumber = szNumber & " " & table.Rows(i).Item(0) & table.Rows(i).Item(1)
Next
GetTable = "1"
Catch ex As System.Data.SqlClient.SqlException
GetTable = "0"
Catch ex As Exception
GetTable = "0"
If (IsNothing(ChatDataAdapter) = False) Then ChatDataAdapter.Dispose()
If (IsNothing(CommSQL) = False) Then CommSQL.Dispose()
SQLConnection.Close()
End Try
Return table
End Function
The part where the errors are is gettable= "1" and below.
GetTable = "1" indicates that you want to set the returnValue of your function. As your function is defined as Function GetTable() As DataTable your compiler shows an error!
A few lines below there is a correct return stmt (Return table) so I am not quite sure what your goal is with GetTable = "1"?
I would assume that you would like to have an additional returnValue indicating whether your function call was successful or not. But as a matter of fact functions may only have one returnValue.
You may choose to set your table var to nothing, or use a ref param ...
' possible solution 1 - using nothing value
Function GetTable() As DataTable
Try
' your code goes here
' remove GetTable = "1"
Catch ex as Exception
' change GetTable = "0" to
table = nothing
End Try
' other code ...
End Function
' possible solution 2 - ref param
Function GetTable(ByRef status as integer) as DataTable
Try
' your code goes here
' remove GetTable = "1"
status = 1
Catch ex as Exception
' change GetTable = "0" to
status = 0
End Try
' other code ...
End Function
At solution 2 you may also choose a boolean parameter indicating your call was successful or not.
Your function GetTable returns a DataTable
you can't convert "1" to a DataTable as the message suggests which is what is happening on the line GetTable = "1"
If you want to return a DataTable and Set a flag to see the status; change your function definition as so:
Function GetTable(byref result as Integer) As DataTable
Then instead of GetTable = "1" change this to result = 1. This way you can inspect the result value and return a DataTable:
Dim res as Integer
Dim dt as DataTable = GetTable(res)
If res = 1 then
'It worked!
End If
Side Note: Turn Option Strict On

Oracle error ORA-01008 inside VB.NET code

Why am I getting this Oracle error when executing this VB.NET code?
Ora-01008: all variables not bound
Dim szSQLEvt As String = ""
Dim sbEvt As New StringBuilder
sbEvt.Append("INSERT INTO WORKORDERHISTORY (WORKORDERNUMBER, WORKORDEREVENT, EVENTDATE, USERNAME) ")
sbEvt.Append("VALUES(:EvtWorkOrderNumber, :WorkOrderEvent, :EventDate, :EvtUsername) ")
szSQLEvt = sbEvt.ToString
Dim cmdEvt As New OracleCommand
cmdEvt.BindByName = True
cmdEvt.Connection = conn
cmdEvt.CommandText = szSQLEvt
cmdEvt.Parameters.Add(":EvtWorkOrderNumber", Oracle.DataAccess.Client.OracleDbType.Varchar2)
cmdEvt.Parameters.Item(":EvtWorkOrderNumber").Value = szNewWONum
cmdEvt.Parameters.Add(":WorkOrderEvent", Oracle.DataAccess.Client.OracleDbType.Varchar2)
cmdEvt.Parameters.Item(":WorkOrderEvent").Value = "assigned"
cmd.Parameters.Add(":EventDate", Oracle.DataAccess.Client.OracleDbType.Date)
cmd.Parameters.Item(":EventDate").Value = Today
cmd.Parameters.Add(":EvtUsername", Oracle.DataAccess.Client.OracleDbType.Varchar2)
cmd.Parameters.Item(":EvtUsername").Value = szCurrUser
If conn.State <> ConnectionState.Open Then conn.Open()
cmdEvt.ExecuteNonQuery()
conn.Close()