vb.net adding large sum on variable integer - mysql

I created a queuing system which would display multiple counters and the queue number of the customer and their service group but when I update them, all data looks like the first counter. My update function is refreshed on timer tick so every 1 second it updates the information.
Public Sub updatecountera()
openconnect()
SQLi = "SELECT `counter`, `logconcern`, `logcustcurr` FROM `access` WHERE logstatus= 1 and counter=1 "
SqlRun()
If myData.Rows.Count = 0 Then
countera.Text = "avail"
counteracust.Text = "avail"
counteraservice.Text = "avail"
Else
countera.Text = myData.Rows(0)(0)
counteracust.Text = myData.Rows(0)(1)
counteraservice.Text = myData.Rows(0)(2)
End If
closeConnect()
End Sub
Public Sub updatecounterb()
openconnect()
SQLi = "SELECT `logconcern`, `logcustcurr` FROM `access` WHERE logstatus= 1 and counter=2 "
SqlRun()
If myData1.Rows.Count = 0 Then
counterb.Text = "avail"
counterbcust.Text = "avail"
counterbservice.Text = "avail"
Else
counterb.Text = myData1.Rows(0)(0)
counterbcust.Text = myData1.Rows(0)(1)
counterbservice.Text = myData1.Rows(0)(2)
End If
closeConnect()
End Sub
Every timer tick only the information of countera shows on all counter (counterb, counterc). When I try to include mydata.clear(), it shows an error of "no data row position". How can I get all the counters to update information without compressing all info in 1 sql statement and selecting per data row since it is very messy to do that?
Edited to add SqlRun() method
yes i was missing 'counter' i added it on my counterb but it still shows identical information here is my sqlrun ():
Public Sub SqlRun()
'transfer sql connections
SQL = SQLi
myCommand.Connection = conn
myCommand.CommandText = SQL
'execute adapter commands
myAdapter.SelectCommand = myCommand
myAdapter.Fill(myData)
myAdapter.Fill(myData1)
myAdapter.Fill(mydata2)
End Sub

Related

How to check only month and year in MySQL DateTime column in Vb.net

Im saving some calculated values in to database each month.Before saving, i want to check data is already available for this month and year. IF the same month exists, then user has to select another month or leaving without saving that. In Vb.net, im using DateTimepicker for selecting month and save that in DateTIme format in mysql. In that i want to check only month and year is existing.
Mysql:
1 2019-05-01 14:24:20 ProA 8.34 3.59
2 2019-05-01 14:24:20 ProB 9.21 5.54
Here record available for ProA for May2019 is available. So user cannot save for may 2019 again.
Dim selectedDate = DateTimePicker1.Value
Dim startDate = New Date(selectedDate.Year, selectedDate.Month, 1)
conn.Open()
sQuery = "SELECT * FROM riskanalysis WHERE DATE_FORMAT(reportdate,'%c %Y') >= #StartDate "
cmd_listview = New MySqlCommand(sQuery, conn)
cmd_listview.Parameters.AddWithValue("#StartDate", startDate)
Using reader As MySqlDataReader = cmd_listview.ExecuteReader()
If reader.HasRows Then
' User already exists
MsgBox("Record Already Exist for this Month!", MsgBoxStyle.Exclamation, "Select another month!")
Else
sQuery = "INSERT INTO riskanalysis (reportdate, process, avgrisk, avgriskafterImp) VALUES (#dat, #process, #avgrisk, #riskafterimp);"
For i As Integer = 0 To ProcessRiskGridView.Rows.Count - 1
cmd_listview = New MySqlCommand(sQuery, conn)
cmd_listview.Parameters.AddWithValue("dat", DateTimePicker1.Value)
cmd_listview.Parameters.AddWithValue("process", ProcessRiskGridView.Rows(i).Cells(0).Value)
cmd_listview.Parameters.AddWithValue("avgrisk", ProcessRiskGridView.Rows(i).Cells(1).Value)
cmd_listview.Parameters.AddWithValue("riskafterimp", ProcessRiskGridView.Rows(i).Cells(2).Value)
cmd_listview.ExecuteNonQuery()
Next
End Using
conn.Close()
I tried for some mysql command but it didnt work.
You don't need to Select * to find out if a record exists. Just get the count. Don't retrieve data you don't need. You certainly don't need a reader.
Keep your database objects local so you can be sure they are closed and disposed. `Using...End Using blocks will handle this for you even if there is an error.
Don't use .AddWithValue See http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
You keep adding parameters to the collection over and over on each iteration. They only need to be added once. The value of #dat remains the same for all iterations. Only the values of the last 3 parameters change. You seem to be mixing up column names and parameter names. We are dealing with parameter names.
I have guessed at datatypes. Check your database for the actual datatypes and be sure to convert the values from the grid cells to the proper type if necessary. I don't know what kind of grid you are using and if it returns proper datatypes for .Value.
Example:
cmd.Parameters("#avgrisk") = CDbl(ProcessRiskGridView.Rows(i).Cells(1).Value)
Private Sub MySql()
Dim retVal As Integer
Dim selectedDate = DateTimePicker1.Value
Dim startDate = New Date(selectedDate.Year, selectedDate.Month, 1)
Dim sQuery = "SELECT Count(*) FROM riskanalysis WHERE DateTimeColumnName >= #StartDate; "
Using conn As New MySqlConnection("Your connection string")
Using cmd As New MySqlCommand(sQuery, conn)
cmd.Parameters.Add("#StartDate", MySqlDbType.DateTime).Value = startDate
conn.Open()
retVal = CInt(cmd.ExecuteScalar)
End Using
End Using
If retVal <> 0 Then
MessageBox.Show("Record Already Exist for this Month!")
Return
End If
sQuery = "INSERT INTO riskanalysis (reportdate, process, avgrisk, avgriskafterImp) VALUES (#dat, #process, #avgrisk, #riskafterimp);"
Using cn As New MySqlConnection("Your connection string")
Using cmd As New MySqlCommand(sQuery, cn)
With cmd.Parameters
.Add("#dat", MySqlDbType.DateTime).Value = selectedDate
.Add("#process", MySqlDbType.VarChar)
.Add("#avgrisk", MySqlDbType.Double)
.Add("#riskafterimp", MySqlDbType.Double)
End With
cn.Open()
For i As Integer = 0 To ProcessRiskGridView.Rows.Count - 1
cmd.Parameters("#process").Value = ProcessRiskGridView.Rows(i).Cells(0).Value
cmd.Parameters("#avgrisk") = ProcessRiskGridView.Rows(i).Cells(1).Value
cmd.Parameters("#riskafterimp") = ProcessRiskGridView.Rows(i).Cells(2).Value
cmd.ExecuteNonQuery()
Next
End Using
End Using
End Sub

How to calculate the expiration date 3 months before will be expire

I need help how to get 3 months before expiration date alert. I used mysql.
Try
Call connection()
cmd.CommandText = "select * from medicine where expiry_date < date_sub(now(), interval 3 month)"
dr = cmd.ExecuteReader
count = 0
While dr.Read
count = count + 1
End While
If count = 1 Then
pop.Image = Image.FromFile("E:\asasda.png")
pop.TitleText = "Notification Alert!!!"
pop.ContentText = "Medicine at Risk"
pop.AnimationDuration = 3000
pop.Popup()
Else
pop.Image = Image.FromFile("E:\asasda.png")
pop.TitleText = "Notification Alert!!!"
pop.ContentText = "No items for risk"
pop.AnimationDuration = 3000
pop.Popup()
End If
Catch ex As Exception
End Try
I commented our Call Connection(). It is best to keep your connections local so you can be sure they are closed and disposed.
A Using...End Using block will accomplish this even it there is an error. Also I don't see where you associated a connection to your command. The call keyword is not necessary in this case. I assume that Connection() returns a connection but your did not provide a variable to hold the connection.
Pass the Select statement and the connection directly to the constructor of the command.
You have consumed all the data you returned in the While loop. If you only only need the Count then ask for the Count and use .ExecuteScalar.
I don't see the point of the If because the if portion is identical to the else portion.
An empty Catch just swallows errors. Bad idea.
Private Sub OPCode()
Dim CountReturned As Integer
Try
'Call Connection()
Using cn As New MySqlConnection("Your connection string")
Using cmd As New MySqlCommand("select Count(*) from medicine where expiry_date < date_sub(now(), interval 3 month);", cn)
cn.Open()
CountReturned = CInt(cmd.ExecuteScalar)
End Using
End Using
If CountReturned = 1 Then
pop.Image = Image.FromFile("E:\asasda.png")
pop.TitleText = "Notification Alert!!!"
pop.ContentText = "Medicine at Risk"
pop.AnimationDuration = 3000
pop.Popup()
Else
pop.Image = Image.FromFile("E:\asasda.png")
pop.TitleText = "Notification Alert!!!"
pop.ContentText = "No items for risk"
pop.AnimationDuration = 3000
pop.Popup()
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
If you cannot get the MySql data_sub working then use vb and parameters.
Using cmd As New MySqlCommand("select Count(*) from medicine where expiry_date < #Minus3Months;", cn)
cmd.Parameters.Add("#Minus3Months", MySqlDbType.DateTime).Value = Now.AddMonths(-3)
cmd.CommandText = "select * from medicine where expiry_date < #threeMonthsAgo"
cmd.parameters.add("#threeMonthsAgo", variableWithYourDate)
You can pass in a value from VB using parameters.

MS Access 2007 DAO open recordset using a specified index

This is the first time I've asked a question although I have found the solutiion to many of my broblems here over the years.
I have a frustrating problem to which I cannot find an answer. I want to do the initial read prior to a read sequentially through a linked table opened as a dynaset DAO recordset using a specific index name as defined on the table.
My code returns error 3251 'operation is not supported...' on the .index line. No doubt there is an obvious solution (Mind you, I'm trying to avoid opening a SQL query which would be the obvious answer).
Public Function IOrdCustomerStock(CustomerID As Long, ProductID As Long, KeepRsOpen As Boolean, Optional UseIndexName As String) As Boolean
Set zcls_CS.CS_rs = CurrentDb.OpenRecordset(Name:=CS_TableName, Type:=RecordsetTypeEnum.dbOpenDynaset)
With zcls_CS.CS_rs
If Not IsMissing(UseIndexName) Then
.Index = UseIndexName
End If
.FindFirst "CS_CustomerID = " & CustomerID & " and CS_ProductID = " & ProductID
If .NoMatch Then
zcls_CS.CS_EOF = True
Else
zcls_CS.CS_EOF = False
zcls_CS.CS_ID = .Fields("[ID]")
zcls_CS.CS_CustomerID = .Fields("[CS_CustomerID]")
zcls_CS.CS_PhysSalesStock = .Fields("[CS_PhysSalesStock]")
zcls_CS.CS_ProductID = .Fields("[CS_ProductID]")
zcls_CS.CS_PurQuantityRecvd = .Fields("[CS_PurQuantityRecvd]")
zcls_CS.CS_PurUnitDesc = .Fields("[CS_PurUnitDesc]")
zcls_CS.CS_PurUnitFactor = .Fields("[CS_PurUnitFactor]")
zcls_CS.CS_SaleQuantityAlloc = .Fields("[CS_SaleQuantityAlloc]")
zcls_CS.CS_SaleQuantityOrdered = .Fields("[CS_SaleQuantityOrdered]")
zcls_CS.CS_SaleUnitDesc = .Fields("[CS_SaleUnitDesc]")
zcls_CS.CS_SaleUnitFactor = .Fields("[CS_SaleUnitFactor]")
End If
End With
If Not KeepRsOpen Then
Call IOclCustomerStock
End If
IOrdCustomerStock = Not zcls_CS.CS_EOF
End Function
Once I'd restricted the problem to linked tables, I found the following post:
https://social.msdn.microsoft.com/Forums/office/en-US/d402a8d2-0771-458c-b57e-09e2d6f0c536/trying-to-open-a-linked-table-whats-going-on?forum=accessdev
I don't pretend to understand the OpenDatabase parameters but it works. I just need to add the usual error handling to my little proof of concept:
Public Function IOksInitRsIX1CustomerStock(UseIndexName As String, CustomerID As Long, ProductID As Long) As Boolean
Set zcls_CS.CS_rs = OpenDatabase(Mid(DBEngine(0)(0).TableDefs(CS_TableName).Connect, 11)).OpenRecordset(CS_TableName)
With zcls_CS.CS_rs
zcls_CS.CS_rs.Index = UseIndexName
If (CustomerID > 0 And ProductID > 0) Then
.Seek "=", CustomerID, ProductID
Else
If CustomerID > 0 Then
.Seek "=", CustomerID
End If
End If
If .NoMatch Then
zcls_CS.CS_EOF = True
Else
zcls_CS.CS_EOF = False
zcls_CS.CS_ID = .Fields("[ID]")
zcls_CS.CS_CustomerID = .Fields("[CS_CustomerID]")
zcls_CS.CS_PhysSalesStock = .Fields("[CS_PhysSalesStock]")
zcls_CS.CS_ProductID = .Fields("[CS_ProductID]")
zcls_CS.CS_PurQuantityRecvd = .Fields("[CS_PurQuantityRecvd]")
zcls_CS.CS_PurUnitDesc = .Fields("[CS_PurUnitDesc]")
zcls_CS.CS_PurUnitFactor = .Fields("[CS_PurUnitFactor]")
zcls_CS.CS_SaleQuantityAlloc = .Fields("[CS_SaleQuantityAlloc]")
zcls_CS.CS_SaleQuantityOrdered = .Fields("[CS_SaleQuantityOrdered]")
zcls_CS.CS_SaleUnitDesc = .Fields("[CS_SaleUnitDesc]")
zcls_CS.CS_SaleUnitFactor = .Fields("[CS_SaleUnitFactor]")
End If
End With
IOksInitRsIX1CustomerStock = Not zcls_CS.CS_EOF
End Function

retrieving null date from database to vb.net

i am having a problem in recovering a null date from my database into datepicker in vb.net.
i was able to save a datein mysql with a null value but can't retrieve it to datepicker.
i tried this code but it doesn't work.
If reader.IsDBNull(0) Then
Return
Else
refdate.Text = reader.GetString("refdate")
End If
my code for retrieving is
Try
If e.RowIndex >= 0 Then
Dim row As DataGridViewRow
row = Me.DataGridView1.Rows(e.RowIndex)
forid.Text = row.Cells("id").Value.ToString
Try
connection.Open()
Dim sel As String
sel = "select * from recordtracker where id ='" & forid.Text & "'"
com = New MySqlCommand(sel, connection)
reader = com.ExecuteReader
While reader.Read
Cancel.Show()
Clear.Hide()
rdate.Enabled = False
rfromtbx.Enabled = False
doctype.DropDownStyle = ComboBoxStyle.DropDown
ID.Text = reader.GetInt32("id")
doctype.Text = reader.GetString("Type_of_Document")
itemtbx.Text = reader.GetString("Items")
rfromtbx.Text = reader.GetString("Received_From")
rdate.Text = reader.GetString("Received_Date")
remarks.Text = reader.GetString("Remarks")
margnote.Text = reader.GetString("Marginal_Note")
reftotbx.Text = reader.GetString("Referred_To")
acttaken.Text = reader.GetString("Action_Taken")
'refdate.Text = reader.GetString("refdate")
'If reader.Read() Then
If reader.IsDBNull(0) Then
Return
Else
refdate.Text = reader.GetString("refdate")
End If
Delete.Show()
' End If
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
any help is appreciated.
For future use, this was the answer needed by the asker.
reader.IsDBNull(0) gets the value of index zero which I presume that refdate is not in the first index.
Using reader.GetString("refdate") gets the String value; therefore, when retrieving null value, it returns error so better use isDbNull(reader("refdate")) to check if the field is null or not. To get the String value, you can simply use reader("refdate").toString

Why would AccessDataSource return different results to query in Access?

I have a query to return random distinct rows from an Access database. Here is the query:
SELECT * FROM
(SELECT DISTINCT m.MemberID, m.Title, m.FullName, m.Address,
m.Phone, m.EmailAddress, m.WebsiteAddress FROM Members AS m INNER JOIN MembersForType AS t ON m.MemberID = t.MemberID WHERE
(Category = 'MemberType1' OR Category = 'MemberType2')) as Members
ORDER BY RND(members.MemberID) DESC
When I run this in Access it returns the rows in different order every time, as per the random sort order. When I run it through my web app however the rows return in the same order every time. Here is how I call it in my code-behind:
private void BindData()
{
using (AccessDataSource ds = new AccessDataSource("~/App_Data/mydb.mdb", GetSQLStatement()))
{
ds.DataSourceMode = SqlDataSourceMode.DataReader;
ds.CacheDuration = 0;
ds.CacheExpirationPolicy = DataSourceCacheExpiry.Absolute;
ds.EnableCaching = false;
listing.DataSource = ds.Select(new DataSourceSelectArguments());
listing.DataBind();
if (listing.Items.Count == 0)
noResults.Visible = true;
else
noResults.Visible = false;
}
}
I added in all that stuff about caching because I thought maybe the query was being cached but the result was the same. I put a breakpoint in the code to make sure the query was the same as above and it was.
Any ideas? This is driving me nuts.
When executing the ACE/Jet RND function against a new connection the same seed value is used each time. When using MS Access you are using the same connection each time, which explains why you get a different value each time.
Consider these VBA examples: the first uses a new connection on each iteration:
Sub TestDiff()
Dim con As Object
Set con = CreateObject("ADODB.Connection")
With con
.ConnectionString = _
"Provider=MSDataShape;Data " & _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Tempo\Test_Access2007.accdb"
.CursorLocation = 3
Dim i As Long
For i = 0 To 2
.Open
Debug.Print .Execute("SELECT RND FROM OneRowTable;")(0)
.Close
Next
End With
End Sub
Output:
0.705547511577606
0.705547511577606
0.705547511577606
Note the same value each time.
The second example uses the same connection on each iteration (the .Open and .Close statements are relocated outside the loop):
Sub TestSame()
Dim con As Object
Set con = CreateObject("ADODB.Connection")
With con
.ConnectionString = _
"Provider=MSDataShape;Data " & _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Tempo\Test_Access2007.accdb"
.CursorLocation = 3
.Open
Dim i As Long
For i = 0 To 2
Debug.Print .Execute("SELECT RND FROM OneRowTable;")(0)
Next
.Close
End With
End Sub
Output:
0.705547511577606
0.533424019813538
0.579518616199493
Note different values each time.
In VBA code you can use the Randomize keyword to seed the Rnd() function but I don't think this can be done in ACE/Jet. One workaround is to use the least significant decimal portion of the ACE/Jet the NOW() niladic function e.g. something like:
SELECT CDBL(NOW()) - ROUND(CDBL(NOW()), 4) FROM OneRowTable
I would move the RND into the inner SELECT
SELECT * FROM
(SELECT DISTINCT m.MemberID, RND(m.MemberID) as SortOrder, m.Title,
m.FullName, m.Address, m.Phone, m.EmailAddress, m.WebsiteAddress
FROM Members AS m
INNER JOIN MembersForType AS t ON m.MemberID = t.MemberID
WHERE
(Category = 'MemberType1' OR Category = 'MemberType2')) as Members
ORDER BY
Members.SortOrder DESC
You can use time as one argument to the RND field
Dim Now As DateTime = DateTime.Now
Dim millSec As Integer = Now.Millisecond
finalQuery = "SELECT * FROM wordInfo ORDER BY Rnd(-(1000* ROUND(" + millSec.ToString("N") + ", 0)) * [ID])"
So here from date and time value, millisecond value is taken which will be integer and it is used in sql query by rounding it.
wordInfo is table name
ID is the column name in database table
This gives random order every time (since millisecond value is different) be it same connection or new connection.