Erroneous Oracle numeric or value error - vb.net

I have an ongoing issue in which a windows service gets this Oracle error:
Message: ORA-06502: PL/SQL: numeric or value error: character to number conversion error
However, I am sure that I am passing a numeric value to Oracle. Working with our Oracle DBA and an Oracle support ticket we were able to capture what the Oracle server receives. My problem is with bind variable #10. The value Oracle reports in the trace log on the server is "A#Y8". However, the value I am actually sending is 167569173.
The Oracle value “A#Y8” does not look familiar – it’s not the value from another field. It is always the same value in the Oracle trace file – always A#Y8. But the numeric value that I am sending is different for each record.
The service pulls data every few minutes from an external source and inserts it into Oracle. It works for about two days and then I get the ORA-06502. Once I get the Oracle error I keep getting it on every pass until I restart the service. When the service restarts it works property for a few days – even though it is pulling the same data that was causing the error.
The Windows Service is written in VB.Net.
When I read the data I put the field into nullable Integer –
Int32?.
I send this variable to an Oracle package which throws the
ORA-06502 and the trace value show the value of "A#Y8".
I then log the value of the variable and my log shows it as numeric
(it logs as 167569173).
The conversion error happens on the call to the procedure. That is, when trying to pass the parameter to the procedure no on the actual insert within the procedure.
Somehow, the Integer value in my code is not an Integer when Oracle receives it. There appears to be some corruption but I don’t think it is in Vb.Net. My field is an integer and would not hold the value Oracle reports.
If the field did hold that value then it should log that value when I log it.
How can I see what value the Oracle client is sending to the Oracle server? I cannot find any relevant client logs.
Any ideas on what could be causing this?
Here is the Oracle trace entry:
Bind#10
oacdty=01 mxl=32(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000010 frm=01 csi=178 siz=0 off=480
kxsbbbfp=9fffffffbed31848 bln=32 avl=06 flg=01
value="A#Y8"
EXEC #11529215044982021440:c=0,e=1300,p=0,cr=34359738368,cu=0,mis=0,r=0,dep=0,og=1,plh=0,tim=2656312500288
ERROR #4:err=6502 tim=2656312500311
Here is my code:
This is the method that inserts into the database - it throws the error:
Public Shared Sub AddNewUploadedDocument(document As ManualUploadDocument)
Using conn As OracleConnection = DataFactory.GetConnection()
Using command As New OracleCommand("OM.EXTERNAL_DOCUMENT_OBJECTS.insertUploadedDocuments", conn)
command.CommandType = CommandType.StoredProcedure
command.Parameters.Add("tSelecteeID", document.SelecteeID)
command.Parameters.Add("tFileName", document.FileNameGUID)
command.Parameters.Add("tFileType", document.FileType)
command.Parameters.Add("tOriginalFileName", document.OriginalFileName)
command.Parameters.Add("tOriginalFileType", document.OriginalFileType)
command.Parameters.Add("tDocTypeID", DBNull.Value)
command.Parameters.Add("tStatus", document.Status.ToString())
command.Parameters.Add("tSource", Integer.Parse(document.Source))
command.Parameters.Add("tSubmitted", Convert.ToInt32(document.Submitted))
command.Parameters.Add("tIsStaffingConversion", Convert.ToInt32(document.IsStaffingConversion))
command.Parameters.Add("tStaffingDocumentationID", document.StaffingDocumentationID)
command.ExecuteNonQuery()
End Using
'close connection
conn.Close()
End Using
End Sub
After this, I call this method to log the values:
Private Shared Function getInsertAttemptFields(document As OnBoardingDataObjects.ManualUploadDocument) As String
Dim sb As New StringBuilder()
sb.AppendLine("Insert Fields")
sb.Append("tSelecteeID:")
sb.AppendLine(document.SelecteeID)
sb.Append("tFileName:")
sb.AppendLine(document.FileNameGUID)
sb.Append("tFileType:")
sb.AppendLine(document.FileType)
sb.Append("tOriginalFileName:")
sb.AppendLine(document.OriginalFileName)
sb.Append("tOriginalFileType:")
sb.AppendLine(document.OriginalFileType)
sb.Append("tDocTypeID:")
sb.AppendLine("<null>")
sb.Append("tStatus:")
sb.AppendLine(document.Status.ToString())
sb.Append("tSource:")
sb.AppendLine(Integer.Parse(document.Source))
sb.Append("tSubmitted:")
sb.AppendLine(Convert.ToInt32(document.Submitted))
sb.Append("tIsStaffingConversion:")
sb.AppendLine(Convert.ToInt32(document.IsStaffingConversion))
sb.Append("tStaffingDocumentationID:")
sb.AppendLine(document.StaffingDocumentationID)
Return sb.ToString()
End Function
It is the same object that I pass to both methods. The StaffingDocumentationID field is the one that the Oracle trace shows as A#Y8 and the log shows as 167569173.
Here is the definition of the manualUploadDocument object that I am passing around. For brevity, I remove the code in some methods - the properties are what is relevant here and the removed code does not reference them.
<Serializable()>
Public Class ManualUploadDocument
Private _Submitted As Boolean = False
Public Property DocumentUploadID As Integer
Public Property SelecteeID As Integer
Public ReadOnly Property FileName As String
Get
Return FileNameGUID + "." + FileType
End Get
End Property
Public Property FileType As String
Public Property OriginalFileName As String = ""
Public Property OriginalFileType As String = ""
Public Property DocumentTypeID As Integer
Public Property DocumentType As String = ""
Public Property UploadDate As Date
Public Property FileNameGUID As String
Public Property Status As PublicEnums.ManualUploadStatus
Public Property Source As PublicEnums.ManualUploadSource
Public Property IsMarkedFortransmission As Boolean = False
Public Property TransmissionStatusDescription As String
Public Property IsStaffingConversion As Boolean = False
Public Property StaffingDocumentationID As Int32?
Public Property Submitted As Boolean
Get
Return _Submitted
End Get
Set(value As Boolean)
_Submitted = value
End Set
End Property
Public Shared Function getStatusDisplayName(status As PublicEnums.ManualUploadStatus) As String
Dim name As String = ""
'Some code here
Return name
End Function
Public Shared Function getStatusDescription(status As PublicEnums.ManualUploadStatus) As String
Dim val As String = ""
'Some code here
Return val
End Function
End Class

Well, I don't see any error in the provided codes. So, there should be some errors in OM.EXTERNAL_DOCUMENT_OBJECTS.insertUploadedDocuments stored procedure. In any case, I have three recommendations:
1- Make sure the stored procedure OM.EXTERNAL_DOCUMENT_OBJECTS.insertUploadedDocuments is correct.
2- Use a try catch block in AddNewUploadedDocument, like:
Public Shared Sub AddNewUploadedDocument(document As ManualUploadDocument)
Using conn As OracleConnection = DataFactory.GetConnection()
Using command As New OracleCommand("OM.EXTERNAL_DOCUMENT_OBJECTS.insertUploadedDocuments", conn)
Try
command.CommandType = CommandType.StoredProcedure
command.Parameters.Add("tSelecteeID", document.SelecteeID)
command.Parameters.Add("tFileName", document.FileNameGUID)
command.Parameters.Add("tFileType", document.FileType)
command.Parameters.Add("tOriginalFileName", document.OriginalFileName)
command.Parameters.Add("tOriginalFileType", document.OriginalFileType)
command.Parameters.Add("tDocTypeID", DBNull.Value)
command.Parameters.Add("tStatus", document.Status.ToString())
command.Parameters.Add("tSource", Integer.Parse(document.Source))
command.Parameters.Add("tSubmitted", Convert.ToInt32(document.Submitted))
command.Parameters.Add("tIsStaffingConversion", Convert.ToInt32(document.IsStaffingConversion))
command.Parameters.Add("tStaffingDocumentationID", document.StaffingDocumentationID)
command.ExecuteNonQuery()
Catch Ex as Exception
Log (document.StaffingDocumentationID)
Log (Ex.StackTrace)
End Try
End Using
'close connection
conn.Close()
End Using
End Sub
3- If everything else failed, rewrite AddNewUploadedDocument using sql statements instead of stored procedure.

Related

Implicit conversion from object to integer and other errors

I have two Layes Classes Business Layer And Data Layer And i have The Main class i called DatabaseManager contain all functions i need for stored procedures
I search on these errors I cannot find solutions
First Error in DatabaseManager class is :
implicit conversion from object to integer
Public Function ExecuteScalar(ByVal sql As String) As Object
Dim cmd As New SqlCommand(sql) With {
.CommandType = CommandType.Text,
.Connection = Connection
}
Dim retval As Integer = ExecuteScalar(cmd)
Return retval
End Function
In Data Layer Class i have this code :
Friend Function Get_Last_Visits_Type(ByRef cmd As SqlCommand)
Dim retval As Integer
cmd = New SqlCommand("Get_Last_Visits_Type")
retval = dm.ExecuteScalar(cmd)
Return retval
End Function
I got two errors here
function without an 'as' clause return type of object assumed
And
implicit conversion from object to integer
When Form Loaded i put this code on Load action :
TxtVisitTypeID.Text = Val(p.Get_Last_Visits_Type)
And i got this error :
implicit conversion from Double to String
Thanks...
Quite a few problems here as mentioned in comments:
Avoid naming a function anything that is a reserved word in the scope of your project at the very least: ExecuteScalar is a method of SqlCommand so use something like MyExecuteScalar instead.
Dim retval As Integer = ExecuteScalar(cmd) probably should be Dim retval As Integer = cmd.ExecuteScalar() unless you want a recursion (which I doubt). (Refer 1.)
Turn Option Strict on in your project settings. As mentioned, ALWAYS have this on. (And I prefer to have Option Explicit on and Option Infer off as well for similar reasons.)
With compile options set as in 3. you will have (valid) compilation errors pertaining to type conversion (at least), with a good chance of resulting in working code once you fix them. Eg Dim retval As Integer = Ctype(cmd.ExecuteScalar(), Integer) (if you're sure that the result of the query will be Integer, otherwise you will need to test and/or error trap).
Connection isn't defined anywhere: .Connection = Connection. You don't pass it nor declare it.
Since retval is declared as an Integer then the return type can also be tightened up to Integer as well, rather than Object.
Your second function has no return type.
What is dm? Not declared/defined.
Consider using Using blocks to close-and-dispose of SQL connection and command on exit.
CommandType.Text is the default so you only need to state it by way of explanation.
Here's what I'd do with your first function:
Public Function MyExecuteScalar(ByVal sql As String) As Integer
Try
Using con As New SqlConnection(sql)
Using cmd As New SqlCommand(sql, con)
Return CType(cmd.ExecuteScalar(), Integer)
End Using
End Using
Catch
Return -1 ' Or something recognizable as invalid, or simply Throw
End Try
End Function
Addressing the first function:
This code is too abstract to be useful. The name of the function is bad. It appears to be recursive but the value you pass back to the function is not a string but a command. If the line of code is Dim retval As Integer = cmd.ExecuteScalar(), then .ExecuteScalar() returns an Object. You cannot convert an Object to an Integer without a conversion method. If you are declaring retval as an Integer why would you have typed your function As Object? I won't even get into the connection problem here. I suggest you delete the function and start again.
Addressing the second function:
Why are you passing the command ByRef? This function has no connection at all! How do you expect it to execute anything? Same problem with retval As Integer and ExecuteScalar returning an Object.
Again, delete and start again.
Now to the code in Form.Load:
Val went out with VB6. I can give unanticipated results. Guess what, Val returns a Double. A .Text property expects a string. Also you appear to be calling the function you showed us above. That function asks for the calling code to provide an argument, namely an SqlCommand object.
My suggestions:
Forget about layers and try to learn the basics of data access with ADO.net. Turn on Option Strict now and forever. Ask new questions with a single problem. Tell us what line the error occurs on. You have been advised before that functions require a datatype but it doesn't seem to sink in.

Creating a Windows Restore Point?

So I have this code, and am running into some issues that I haven't so far been able to sort out:
Anywhere there are Parameters, i.e. "CreateRestorePoint", or the inParams params, I get the green squiggly underline that says to use (ex.) "NameOf(CreateRestorePoint) instead of specifying the program element name".
However, whether I do so or leave it, I get the same error:
System.ArgumentOutOfRangeException: 'Specified argument was out of the range of valid values. Parameter name: path'
The code:
Public Function CreateRestorePoint(Description As String, EventType As Integer, RestorePointType As Integer) As Integer
Try
Dim classInstance As New ManagementObject("root\DEFAULT", "SystemRestore", Nothing)
' Obtain [in] parameters for the method
Dim inParams As ManagementBaseObject = classInstance.GetMethodParameters("CreateRestorePoint")
' Add the input parameters
inParams("Description") = Description
inParams("EventType") = EventType
inParams("RestorePointType") = RestorePointType
' Execute the method and obtain the return values
Dim outParams As ManagementBaseObject = classInstance.InvokeMethod("CreateRestorePoint", inParams, Nothing)
' List outParams
Debug.Print("Out parameters: ")
Debug.Print("ReturnValue: {0}", outParams("ReturnValue"))
CreateRestorePoint = 1
Catch err As ManagementException
Debug.Print(String.Format("An error occurred while trying to execute the WMI method: {0}", err.Message))
End Try
Return CreateRestorePoint
End Function
Here's how I'm calling the function:
Dim CRP As New JSEWindowsRestore.WindowsRestoreFunctions
CRP.CreateRestorePoint(String.Format("Test Restore Point: {0}", DateTime.Now), 100, 12)
Anyone spot the problem?
Everything looks pretty good. The only thing that you need to change is ManagementObject in the first couple lines to ManagementClass.
Dim classInstance As New ManagementClass("root\DEFAULT", "SystemRestore", Nothing)
ManagementObject refers to an instance of a class and ManagementClass refers to the class itself. The path error you were receiving was because the code was expecting a path to an instance and not a class itself.
As for the green squiggly lines, they shouldn't prevent you from compiling but its possible Visual Studio will like this syntax better.
inParams.Properties("Description").Value = Description
inParams.Properties("EventType").Value = EventType
inParams.Properties("RestorePointType").Value = RestorePointType
Also, make sure the application has administrator privileges or you'll get an access denied when you try to invoke this method.

nhibernate fill class with custom data from different tables

I have a web application (asp.net + SQL db) and I'm mapping it with nHibernate with relative success =).
This web reads an Oracle db (from an ERP system), collects and display data from it but its not using nHibernate for this task.
I have done several reports each one with its own vb.net class that I fill with intrincated queries,
collecting data from a bunch of Oracle tables. So my question is:
Can i do an specific hql query and fill my vb.class in a custom way (Maybe not mapping it), specifying one by one which column of my query fills each property?
===================== EDIT WITH SOLUTION =====================
Just if someone need the resolution, I post the solution in an example.
Public Class classExample
Private pProperty1 As Decimal
Private pProperty2 As String
Public Property Property1() As Decimal
Get
Property1 = pProperty1
End Get
Set(ByVal Value As Decimal)
pProperty1 = Value
End Set
End Property
Public Property Property2() As String
Get
Property2 = pProperty2
End Get
Set(ByVal Value As String)
pProperty2 = Value
End Set
End Property
Public Overloads Function Load() As System.Collections.Generic.List(Of classExample)
Using session As NHibernate.ISession = ISessionFactory.OpenSession()
Dim strsql As String = "SELECT.... FROM...."
Dim Query As NHibernate.IQuery = session.CreateSQLQuery(strsql)
Query.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(Of classExample))
Return Query.List(Of classExample)()
End Using
End Function
End Class
Thanks for your help.
You need to use a result transformer as here (see second code block).

Calling a module procedure that has a parameter of a class

I am Writing a API for FedEx and our Universe database, the FedEx code has been written but i now need to create a string to write back to our Universe database. The question is how would i make this tracking number into a variable so that i can use it in that string. this is the procedure in the module:
Public Sub ShowTrackingDetails(ByRef TrackingIds() As TrackingId)
' Tracking information for each package
Console.WriteLine()
Console.WriteLine("Tracking details")
If (TrackingIds IsNot Nothing) Then
For Each trackingId As TrackingId In TrackingIds
Console.WriteLine("Tracking # {0} Form ID {1}", trackingId.TrackingNumber, trackingId.FormId)
Next
End If
End Sub
in the for each method trackingId.TrackingNumber returns what i need.
You can use the ToString method to convert a number to a string
Dim numberAsString As String = trackingId.TrackingNumber.ToString()
However, it is probably better to store numbers in a database as numbers rather than as strings.
If you want the variable to be available outside the ShowTrackingDetails method, you can declare it as Public or Private.
Private numberAsString As String
Public Sub ShowTrackingDetails(ByRef TrackingIds() As TrackingId)
'your code
numberAsString = trackingId.TrackingNumber.ToString()
'your code
End Sub

How to declare global variable that reads the last line of richtextbox

I have this code
Dim totalLines As Integer = frmTerminal.rtbDisplay.Lines.Length
Dim lastLine As String = frmTerminal.rtbDisplay.Lines(totalLines - 1)
That code effectively reads the last line of my richtextbox and it is very useful to all of my functions.
Problem:
Because most of my functions rely on detecting the last line of a richtextbox I would like to declare it as global and public variable. But whenever I make it global and public it result in an error stating that
An unhandled exception of type 'System.TypeInitializationException' occurred in xxxxxx.exe
It means something like I want to count the lines of a not yet created richtextbox, so my question is how do I effectively get the lastline of a richtextbox in a global and public way?
You could try using a public property
Public ReadOnly Property LastLine() As String
Get
Dim returnValue As String = String.Empty
If rtbDisplay.Lines.Count > 0 Then
returnValue = rtbDisplay.Lines(rtbDisplay.Lines.Count - 1)
End If
Return returnValue
End Get
End Property
While declaring it as public variable may not help, you can declare it as a public property in your class.
Public ReadOnly Property LastLine() As String
Get
Return frmTerminal.rtbDisplay.Lines(frmTerminal.rtbDisplay.Lines.Length - 1)
End Get
End Property