0

I have an application that shows the shift target of a certain reference. I have a lot of references divided in 3 shifts (morning, afternoon, evening) The app is working good but now i want to reset the counter of the shift targets in the beginning of every shift for all references. I mean, when the clock is 6am, all the morning shift should put the counter on 0. I have the following code but is not working. Something is missing and i'm stuck.

Dim rtime As New TimeSpan(0, 0, CInt(requestddate.TimeOfDay.TotalSeconds))


        hora1 = New TimeSpan(6, 0, 0)
        hora2 = New TimeSpan(14, 0, 0)
        hora3 = New TimeSpan(22, 0, 0)

        ConnectDatabase()

        If rtime = hora1 Then

            count = 0

            Try

                With cmd4
                    .Connection = conn
                    .CommandText = "Select ShiftTarget.IDShiftTarget from ShiftTarget, turnos, linhas WHERE ShiftTarget.IDLinha = linhas.IDLinha and ShiftTarget.IDTurno = turnos.IDTurno And turnos.Descricao = 'Manha' And linhas.NomeLinha = '" & GlobalVariables.linha & "'"
                End With

                While objReader.Read()
                listaIDs.Add(objReader("IDShiftTarget").ToString())
            End While

            objReader.Close()

            DisconnectDatabase()

            ConnectDatabase()

            With cmd1
                .Connection = conn
                .CommandText = "INSERT into contador (IDShiftTarget, Data, Contador) VALUES (@ID, @date, @cont)"
                For Each item As String In listaIDs
                    MsgBox(item)
                    .Parameters.AddWithValue("@ID", item)
                    .Parameters.AddWithValue("@date", data.ToString("yyyy-MM-dd"))
                    .Parameters.AddWithValue("@cont", count)
                    .ExecuteNonQuery()
                Next
            End With

        Catch ex As Exception
            If ex.InnerException IsNot Nothing Then
                MsgBox(ex.InnerException)
            End If
        End Try

        DisconnectDatabase()

Can someone tell me what am i doing wrong?

Update: This is what i get (and it's expected) from the select query: enter image description here

And this is the table where i want to reset the counter: enter image description here

So, imagine, when the actual time is 6am, i want to insert something like:

IDContador   IDShiftTarget      Data      Contador
11933          32           2016-02-23       0
11934          19           2016-02-23       0
11935          20           2016-02-23       0
11936          35           2016-02-23       0

I cannot simply reset to 0 where idshifttarget is equal to 19,20,32,35 because that would reset all the records, and i want to keep them in the table. I need to check the MAX(ID) where the shiftTarget is the value i got in the array, and then put the Contador to 0.

UPDATE:

I have made this changes in the code:

While objReader.Read()
                listaIDs.Add(objReader("IDShiftTarget").ToString())
            End While

            objReader.Close()

            DisconnectDatabase()

            ConnectDatabase()

            With cmd1
                .Connection = conn
                .CommandText = "INSERT into contador (IDShiftTarget, Data, Contador) VALUES (@ID, @date, @cont)"
                For Each item As String In listaIDs
                    MsgBox(item)
                    .Parameters.AddWithValue("@ID", item)
                    .Parameters.AddWithValue("@date", data.ToString("yyyy-MM-dd"))
                    .Parameters.AddWithValue("@cont", count)
                    .ExecuteNonQuery()
                Next
            End With

        Catch ex As Exception
            If ex.InnerException IsNot Nothing Then
                MsgBox(ex.InnerException)
            End If
        End Try

        DisconnectDatabase()

With this code i can only see the first ID and in the console i get the next error: Exception thrown: 'System.InvalidOperationException' in MySql.Data.dll

15
  • Please narrow down I have the following code but is not working. What is the expected behavior ? How does the code not meet this behavior? Which counter are you talking about? Do you want to set something in the database or in your code? I cannot see any link between your posted code and question, sorry. Commented Feb 23, 2016 at 12:16
  • Is your program running continuously/ as a service? If so you could create a TimeSpan which represents the remaining hours/minutes/seconds to the "next" 6am time shift. Additionally create a Timer whose Interval is set to the TimeSpan.TotalMilliseconds. In the Timer Tick Event Handler execute your Inserts. After that set the Timer Interval to 24 hours. Proceed with the other shifts accordingly. Commented Feb 23, 2016 at 15:08
  • Yes, the program is running continuously and this code i posted is inside a 1sec timer. I don't think that adding more timers would be the best solution, once that the code i have is probably almost good. Is missing something but i can't see what. Anyway, thank you for your suggestion. I'll think about it :) Commented Feb 23, 2016 at 15:11
  • 1
    Have you debuged your code? Is an exception thrown when calling ExecuteNonQuery? Edit: Your catch block swallows the exception if it has no InnerException. Change it so the original exception is also shown in the MsgBox. Edit2: You try to execute an Insert statement whil looping thru a DataReader which is not allowed in mysql. Commented Feb 23, 2016 at 15:54
  • 1
    Jap. Loop thru the DataReader and store all IDShiftTarget in a List or something. Then close the Reader, loop thru the List and execute the Inserts. I have to more concerns about your code: If objReader.Read = True Then will lead to that the first row of your query is ignored! 2nd: Both in your Select and Insert statements you concat parameters in the WHERE/VALUES clause. Please use prepared statements with bound parameters to avoid SQL Injection. Commented Feb 23, 2016 at 16:38

1 Answer 1

1

There are some things in your code which lead to wrong havior:

  • You cannot execute a CRUD action while looping thru a DataReader: Create a list to store IDShiftTargets, close the DataReader and then loop thru the list and execute the Insert statements.
  • Take care that the data types of your DB columns match with the code data types (IDShiftTarget int/Integer, IDShiftTarget date/DateTime, ...).
  • When using a prepared statement with bound parameters make sure that you use AddWithValue only once outside the loop and set it in the loop with Parameter("@ID").Value = item
  • Since the code is executed in a timer event which ticks every second, it is
    likely that a first execution has not finished until the next timer ticks. If you want to run the code secure and synchron make sure that the current execution is not disturbed, e.g. setting Timer.Enabled= False at the beginning of the function and Timer.Enabled=True after function has finished. Or just set the timer tick high enough (d'oh).
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.