Grab data from Mysql and loop through results - mysql

I need to check a mysql table periodically and if there are any rows found, I need to loop through them and perform some actions.
My SQL string is nice and simple: "SELECT * FROM 'dbcpman_jobs'".
There could be 1 returned row, or there could be 20 returned rows.
For each returned row, I need to assign some of the data to variables...
Dim job_id As String = jobrow.Item("id")
Dim job_jobid As String = jobrow.Item("jobid")
Dim job_status As String = jobrow.Item("status")
Dim job_dbxid As String = jobrow.Item("dbxid")
Then i need to make an API call using the information that's just been split out...
Try
Dim jobapicall As New System.Net.WebClient
jobcheckresult = jobapicall.DownloadString(fulljobapicheckurl)
Catch ex As Exception
Console.WriteLine("Error 'DBX-Err-1' - Error during API call")
End Try
Can someone point me in the right direction to loop through all rows found?
My code currently checks the first item found only, which is not ideal as if that job fails, everything else gets held up.
Thanks

FOR EACH loop was the answer.
something like this...
For Each jobRow As DataRow in dtJobResults.Rows
Try
what I want to do for each returned row.
Catch Ex as exception
messagebox.show("Oh no, something went wrong!")
End Try
Next

Related

Copy a DataRow to another table (vb.net / mysql)

I have a Two identical data tables in my project, One is Purchase Orders and the other is a template datatable. (IE: the user can select a template when creating a new row in the original table.)
A Save Template button runs:
Public Shared Sub AddPO_as_Template(Name As String, DR As DataRow)
Dim ds As New SomeDataSet
Dim ta As New SomeDataSetDataSetTableAdapters.PurchaseOrderTemplatesTableAdapter
Try
DR("Name") = Name
ds.PurchaseOrderTemplates.ImportRow(DR)
ta.Update(ds)
Catch ex As Exception
CommonRoutines.ShowExceptionDialog("Could not add the Template, an error occured.", ex.Message)
End Try
End Sub
This particular code throws a concurrency violation. I assume this is happening because the ID column is auto increment and I as using the origional row's ID.
Now; the ID in the second table (PurchaseOrderTemplates) is not important at all, so it can be anything. I have tried setting -1, dbnull, "", etc.... the DB keeps trowing exceptions on the update command.
How can I reset the ID column so it just adds as normal? (I know i could create a newrow and move all the columns accross, but this seems the long way.)
Thanks
EDIT: Copying the rows (via .itemarray) works fine, but i need to get the auto increment value from the table somehow to avoid concurrency violations.
Edit2: So i got it working as per the answer below, but I'd still love to know how to get import row working like this.
Adding the Row as follows works.
Public Shared Sub AddPO_as_Template(Name As String, DR As DataRow)
Dim ds As New SomeDataSet
Dim ta As New SomeDataSetTableAdapters.PurchaseOrderTemplatesTableAdapter
Dim NewRow As DataRow
NewRow = ds.PurchaseOrderTemplates.NewRow
NewRow.ItemArray = DR.ItemArray
NewRow("Name") = Name
NewRow("ID") = 1
ds.PurchaseOrderTemplates.Rows.Add(NewRow)
ta.Update(ds)
End Sub
The MySQL database ignores the value in the ID column, and just sets its own auto increment value.

Delete query when in a loop gives first chance error second time through

This code in my vb.net controller:
For i = 0 To depToDelete.Count - 1
cmd.CommandText = "delete from budget.budget_monthlybudgetfees where guid in(#strdepToDelete, #strOtherToDelete);"
cmd.Parameters.Add("#strdepToDelete", MySql.Data.MySqlClient.MySqlDbType.VarChar, 36).Value = depToDelete(i)
cmd.Parameters.Add("#strOtherToDelete", MySql.Data.MySqlClient.MySqlDbType.VarChar, 36).Value = otherToDelete(i)
Try
cmd.ExecuteNonQuery()
success = True
Catch ex As Exception
success = False
End Try
Next
I have set the connection string earlier. The delete query runs first time through but second time it throws a "first chance exception of type 'MySql.Data.MySqlClient.MySqlException' in MySql.Data.dll. I have tried putting Trim on parameters as per another post suggestion, but still the same error. I have tried setting cmd.CommandText to "" at beginning of loop but no change.
Most likely you get the error message because you add the parameters on each iteration of the loop. Parameters can be added only once. However, you can of course change their assigned value in the loop like this:
cmd.Parameters("#myParameter").Value = "Assign value here"
So, just add the parameters before the loop and then only change the value during the loop.

Pulling out specific text in an html file using vb.net

I am trying to get three values from a large html file. I thought I could use the substring method, but was informed that the position of the data may change. Basically, in the following code I need to pick out "Total number of records: 106", "Number of records imported:106", and "Number of records rejected: 0"
<B>Total number of records : </B>106</Font><br><Font face="arial" size="2"><B>Number of records imported : </B>106</Font><br><Font face="arial" size="2"><B>Number of records rejected : </B>0</Font>
I hope this is clear enough. Thanks in advance!
Simple string operations like IndexOf() and Substring() should be plenty to do the job. Regular Expressions would be another approach that'd take less code (and may allow more flexibility if the HTML tags can vary), but as Mark Twain would say, I didn't have time for a short solution, so I wrote a long one instead.
In general you'll get better results around here by showing you've at least made a reasonable attempt first and showing where you got stuck. But for this time...here you go. :-)
Private Shared Function GetMatchingCount(allInputText As String, textBefore As String, textAfter As String) As Integer?
'Find the first occurrence of the text before the desired number
Dim startPosition As Integer = allInputText.IndexOf(textBefore)
'If text before was not found, return Nothing
If startPosition < 0 Then Return Nothing
'Move the start position to the end of the text before, rather than the beginning.
startPosition += textBefore.Length
'Find the first occurrence of text after the desired number
Dim endPosition As Integer = allInputText.IndexOf(textAfter, startPosition)
'If text after was not found, return Nothing
If endPosition < 0 Then Return Nothing
'Get the string found at the start and end positions
Dim textFound As String = allInputText.Substring(startPosition, endPosition - startPosition)
'Try converting the string found to an integer
Try
Return CInt(textFound)
Catch ex As Exception
Return Nothing
End Try
End Function
Of course, it'll only work if the text before and after is always the same. If you use that with a driver console app like this (but without the Shared, since it'd be in a Module then)...
Sub Main()
Dim allText As String = "<B>Total number of records : </B>106</Font><br><Font face=""arial"" size=""2""><B>Number of records imported : </B>106</Font><br><Font face=""arial"" size=""2""><B>Number of records rejected : </B>0</Font>"""""
Dim totalRecords As Integer? = GetMatchingCount(allText, "<B>Total number of records : </B>", "<")
Dim recordsImported As Integer? = GetMatchingCount(allText, "<B>Number of records imported : </B>", "<")
Dim recordsRejected As Integer? = GetMatchingCount(allText, "<B>Number of records rejected : </B>", "<")
Console.WriteLine("Total: {0}", totalRecords)
Console.WriteLine("Imported: {0}", recordsImported)
Console.WriteLine("Rejected: {0}", recordsRejected)
Console.ReadKey()
End Sub
...you'll get output like so:
Total: 106
Imported: 106
Rejected: 0

SSIS Convert Blank or other values to Zeros

After applying the unpivot procedure, I have an Amount column that has blanks and other characters ( like "-"). I would like to convert those non-numberic values to zero. I use replace procedure but it only converts one at the time.
Also, I tried to use the following script
/**
Public Overrides Sub Input()_ProcessInputRows(ByVal Row As Input()Buffer)
If Row.ColumnName_IsNull = False Or Row.ColumnName = "" Then
Dim pattern As String = String.Empty
Dim r As Regex = Nothing
pattern = "[^0-9]"
r = New Regex(pattern, RegexOptions.Compiled)
Row.ColumnName = Regex.Replace(Row.ColumnName, pattern, "")
End If
End Sub
**/
but i'm getting error.I don't much about script so maybe I placed in the wrong place. The bottom line is that I need to convert those non-numberic values.
Thank you in advance for your help.
I generally look at regular expressions as a great way to introduce another problem into an existing one.
What I did to simulate your problem was to write a select statement that added 5 rows. 2 with valid numbers, the rest were an empty string, string with spaces and one with a hyphen.
I then wired it up to a Script Component and set the column as read/write
The script I used is as follows. I verified there was a value there and if so, I attempted to convert the value to an integer. If that failed, then I assigned it zero. VB is not my strong suit so if this could have been done more elegantly, please edit my script.
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
' Ensure we have data to work with
If Not Row.ColumnName_IsNull Then
' Test whether it's a number or not
' TryCast doesn't work with value types so I'm going the lazy route
Try
' Cast to an integer and then back to string because
' my vb is weak
Row.ColumnName = CStr(CType(Row.ColumnName, Integer))
Catch ex As Exception
Row.ColumnName = 0
End Try
End If
End Sub

How to do a simple entity copy in Linq-to-SQL?

When using a Linq-to-SQL class, how can I make a simple copy of an entity and save it?
My entity has a guid for a unique ID that gets automatically generated in the SQL Server.
I don't require a "deep clone".
I tried to use some clone methods that are out there but I couldn't figure out how to get everything serialized that needed to be serialized (got stuck on the DataContext not being serializable).
Can I just get an entity, detach it from the DataContext, null out the unique ID and InsertOnSubmit in a new DataContext? If so, how would I do this?
VB.net code preferred but not required.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UPDATE:
Public Shared Function ReIssue(RequestID As Guid) As Guid
Dim req As Request
Dim new_req As Request
Using dc1 As New MBDataContext()
req = (From r In dc1.Requests Where r.ID = RequestID).Single()
End Using
new_req = req
new_req.ID = Guid.Empty
new_req.CreateDate = Nothing
Using dc2 As New MBDataContext()
dc2.Requests.InsertOnSubmit(new_req)
dc2.SubmitChanges()
End Using
End Function
I get an error: An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.
on this line: dc2.Requests.InsertOnSubmit(new_req)
Nulling out the unique id and then calling InsertOnSubmit is the right way to go. Some things you have to consider though:
What is the type of the id? Is it an int? A Guid? Is it nullable? If it is nullable, make sure to set it to null, if it is an int, then to 0, or a Guid, then to Guid.Empty.
Does the type have a timestamp of some kind? If so, then you have to reset/set it to null as well, depending on the type.
Once you've done that, you can call InsertOnSubmit and then SubmitChanges and the change should take place.
Note, if you are doing this for a large number of records, you are better off writing a stored procedure which will perform the insert into the table using a select from the other table. It will be much faster that way (you won't be loading the data from the database into memory then pushing it back, inserting the records one at a time).
This method seems to have worked perfectly.
Making the final code look like this:
Public Shared Function ReIssue(RequestID As Guid) As Guid
Using dc As New MBDataContext()
Dim req As Request
req = (From r In dc.Requests Where r.ID = RequestID).Single()
Dim new_req As Request = DirectCast(Entity.Copy(req, New Request()), Request)
dc.Requests.InsertOnSubmit(new_req)
dc.SubmitChanges()
req.ActiveRequestParentID = new_req.ID
dc.SubmitChanges()
Return new_req.ID
End Using
End Function
Public NotInheritable Class Entity
Private Sub New()
End Sub
Public Shared Function Copy(source As Object, destination As Object) As Object
Dim sourceProps As System.Reflection.PropertyInfo() = source.[GetType]().GetProperties()
Dim destinationProps As System.Reflection.PropertyInfo() = destination.[GetType]().GetProperties()
For Each sourceProp As System.Reflection.PropertyInfo In sourceProps
Dim column As ColumnAttribute = TryCast(Attribute.GetCustomAttribute(sourceProp, GetType(ColumnAttribute)), ColumnAttribute)
If column IsNot Nothing AndAlso Not column.IsPrimaryKey Then
For Each destinationProp As System.Reflection.PropertyInfo In destinationProps
If sourceProp.Name = destinationProp.Name AndAlso destinationProp.CanWrite Then
destinationProp.SetValue(destination, sourceProp.GetValue(source, Nothing), Nothing)
Exit For
End If
Next
End If
Next
Return destination
End Function
End Class