Cannot open any more tables - OleDbException was unhandled - vb.net

Good Day,
My question is how to handle the exception or get rid of the error pertaining to "Cannot open any more tables". For an overview to the program I was creating, I pull out the record of subject in ms access 2007, I loop to that record to randomly assign a schedule and one by one I insert the newly record with assigned schedule in the table.
My program flow of inserting the record work only for a certain number of times, like almost 200 and at some point it stop and pop-up the oledbexception
Thanks in advance for your time on answering my question.
here is my code for more detailed overview of my program,
Private Sub Assignsched(ByVal rType As String, ByVal subjectCode As String, ByVal SecID As String, ByVal CourseCode As String)
If shrdcon.con.State = ConnectionState.Closed Then
shrdcon.con.Open()
End If
Dim RoomNum As Integer
dtARoom.Clear()
Dim stoploop As Boolean
Dim count As Integer = 0
Dim rm1 As String
RoomAssign = ""
rm1 = "SELECT * FROM tblRoom WHERE RoomType = '" & rType & "'"
Dim dat As New OleDbDataAdapter(rm1, shrdcon.con)
dat.Fill(ds, "ARoom")
stoploop = False
count = 0
Do Until stoploop = "True"
RoomNum = rndm.Next(0, ds.Tables("ARoom").Rows.Count)
RoomAssign = ds.Tables("ARoom").Rows(RoomNum).Item(1)
ScheduleGeneration()
If checkExisting(sTime, eTime, RoomAssign, daypick) = False Then
RoomA = RoomAssign
GenerateOfferingID()
Dim cmd1 As New OleDbCommand()
cmd1.CommandText = "INSERT INTO [tblSubjectOffer]([SubjectOID],[SubjectCode],[SectionID],[Day],[sTime],[eTime],[RoomName],[CourseCode]) VALUES('" & _
myId & "','" & subjectCode & "','" & SecID & "','" & daypick & "'," & sTime & "," & eTime & ",'" & RoomA & "','" & CourseCode & "')"
cmd1.Connection = shrdcon.con
cmd1.ExecuteNonQuery()
cmd1.Dispose()
Dim pipz As New OleDbCommand("Update tblGenerator Set NextNo='" & myId & "' where TableName ='" & "tblSubjectOffer" & "'", shrdcon.con)
pipz.ExecuteNonQuery()
pipz.Dispose()
stoploop = True
Else
stoploop = False
End If
If stoploop = False Then
If count = 30 Then
stoploop = True
Else
count = count + 1
End If
End If
Loop
End Sub

This is typical error happens with Microsoft Jet engine when You have exceeded the maximum number of open TableIDs allowed by the Microsoft Jet database engine, which is 2048 with Jet3.5 engine and 1024 with older engines.
Even though you are closing the Command objects after each use, you are still using the same connection for the whole process, which actually holds the TableID's and is at some point of time exceeding the number of allowed open TableID's.
A probable solution would be to update the Jet Engine with the latest, which is available here
It might solve your problem, but if you are already using the latest engine, you have to look into other options to reduce the number of DB operations.
Try using the UpdateBatch method for applying the updates as a batch.
Hope this helps
Private Sub Command1_Click()
Dim myConnection As ADODB.Connection
Dim rsData As ADODB.Recordset
Set myConnection = New ADODB.Connection
myConnection.ConnectionString = "xxxxxxxxxxxxxxxxxxxx"
myConnection.Open
Set rsData = New ADODB.Recordset
rsData.CursorLocation = adUseClient
rsData.Open "select * from mytable", myConnection, adOpenStatic, adLockBatchOptimistic
For i = 1 To 10000
rsData.AddNew
rsData.Fields(0).Value = 1
rsData.Fields(1).Value = 2
Next i
rsData.UpdateBatch
rsData.Close
myConnection.Close
Set rsData = Nothing
End Sub

Good Evening,
Recently I encounter this type of error and i was able to resolve it by adding
con.close and call conState (a procedure conState- check below) before any insert/update or select statement
In my code i have something like
For i = 0 To DataGridView1.RowCount - 1
reg = DataGridView1.Rows(i).Cells(0).Value
Label2.Text = reg
'i added this two lines
***con.Close()***
***Call conState()***
Dim cmdcheck As New OleDbCommand("Select * from [2015/2016 UG CRF] where regno ='" & reg & "'", con)
Dim drcheck As OleDbDataReader
drcheck = cmdcheck.ExecuteReader
If drcheck.Read = True Then
GoTo A
End If
coursesFirst = String.Empty
coursesSecond = String.Empty
creditFirst = 0
creditSecond = 0
Dim cmdlevel As New OleDbCommand("Select * from [2015/2016 UG registration Biodata 5 april 16] where regno ='" & reg & "'", con)
Dim drlevel As OleDbDataReader
drlevel = cmdlevel.ExecuteReader
If drlevel.Read = True Then
level = drlevel.Item("level").ToString
faculty = drlevel.Item("faculty").ToString
program = drlevel.Item("programme").ToString
End If
...............
next
The conState is a connection testing if connection is closed is should open it again like in below
Public Sub conState()
If con.State = ConnectionState.Closed Then
con.Open()
End If
End Sub
This stop the error message

I got this exception in my C# application and the cause was using OleDbDataReader instances without closing them:
OleDbDataReader reader = cmd.ExecuteReader();
bool result = reader.Read();
reader.Close(); // <= Problem went away after adding this
return result;

Related

Availability using Access Database

I am attempting to make a hotel booking system. However the availability has got me a bit confused. I have about 15 buttons which I am able to save the number to the database but when the form loads/ date changed. I need the button to stay red and be unclickable. For example if I had a room 11 booked from 3/06/17 to 5/06/17 then I'd need the button to remain red from the 3/06/17 to 4/06/17 since the room is able to still be booked on the 5/06/17 after cleaning. I hope this makes sense. Below is the code I am using to try to do this. The code does run however the button does not turn red.
I was thinking does my SQL statement need to be changed but I'm not too sure. I'm pretty new to coding so an explanation would be helpful. Thanks.
Private Sub ReadRecords()
Dim btn As Button = Nothing
Dim BookingFound As Boolean = False
Using MyConn As New OleDbConnection
MyConn.ConnectionString = connString
MyConn.Open()
Dim check As String = "SELECT COUNT(*) FROM [BookingInformation] WHERE [Date In] = '" & dtpDateIn.Value.Date & "' AND [Date Out] = '" & dtpDateOut.Value.Date & "'"
Dim BookingExists As Boolean = False
Dim command As OleDbCommand = New OleDbCommand(check, MyConn)
Using reader As OleDbDataReader = command.ExecuteReader()
While reader.Read()
If reader(0) = 0 Then
BookingExists = False
Else
BookingExists = True
End If
End While
End Using
If BookingExists = True Then
Dim getData As String = "SELECT * FROM [BookingInformation] WHERE [Date Out] = '" & dtpDateOut.Text & "'"
Dim command2 As OleDbCommand = New OleDbCommand(getData, MyConn)
Using reader As OleDbDataReader = command2.ExecuteReader()
While reader.Read()
BookingFound = True
strDateIn = reader("Date In").ToString()
strDateOut = reader("DateOut").ToString
strRoomNumber = reader("Room Number").ToString
End While
If BookingFound = True Then
btn.BackColor = Color.Red
End If
End Using
End If
MyConn.Close()
End Using
End Sub
Private Sub Room_Booking_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ReadRecords()
End Sub
You should make your access database understand your input as date, access database is very sensitive to datatypes, for example if you write
"SELECT * FROM [user_tb] WHERE user_id=1"
Your code will work fine if your user_id data type is autonumber.
so try
Dim getData As String = "SELECT * FROM [BookingInformation] WHERE [Date Out] = #" & dtpDateOut.Text & "#"
Instead of
Dim getData As String = "SELECT * FROM [BookingInformation] WHERE [Date Out] = '" & dtpDateOut.Text & "'"
That is replace ' with #

MysqlDataReader.Read stuck on the last record and doesnt EOF

i confused why mySqlDataReader.Read stuck on the last record and doesnt EOF ..
Here's my private function for executeSql :
Private Function executeSQL(ByVal str As String, ByVal connString As String, ByVal returnRecordSet As Boolean) As Object
Dim cmd As Object
Dim objConn As Object
Try
If dbType = 2 Then
cmd = New MySqlCommand
objConn = New MySqlConnection(connString)
Else
cmd = New OleDbCommand
objConn = New OleDbConnection(connString)
End If
'If objConn.State = ConnectionState.Open Then objConn.Close()
objConn.Open()
cmd.Connection = objConn
cmd.CommandType = CommandType.Text
cmd.CommandText = str
If returnRecordSet Then
executeSQL = cmd.ExecuteReader()
executeSQL.Read()
Else
cmd.ExecuteNonQuery()
executeSQL = Nothing
End If
Catch ex As Exception
MsgBox(Err.Description & " #ExecuteSQL", MsgBoxStyle.Critical, "ExecuteSQL")
End Try
End Function
And this is my sub to call it where the error occurs :
Using admsDB As MySqlConnection = New MySqlConnection("server=" & rs("server") & ";uid=" & rs("user") & ";password=" & rs("pwd") & ";port=" & rs("port") & ";database=adms_db;")
admsDB.Open()
connDef.Close()
rs.Close()
'get record on admsdb
Dim logDate As DateTime
Dim str As String
str = "select userid, checktime from adms_db.checkinout in_out where userid not in (select userid " &
"from adms_db.checkinout in_out join (select str_to_date(datetime,'%d/%m/%Y %H:%i:%s') tgl, fid from zsoft_bkd_padang.ta_log) ta " &
"on ta.fid=userid and tgl=checktime)"
Dim rsAdms As MySqlDataReader = executeSQL(str, admsDB.ConnectionString, True)
Dim i As Integer
'This is where the error is, datareader stuck on the last record and doesnt EOF
While rsAdms.HasRows
'i = i + 1
logDate = rsAdms(1)
'save to ta_log
str = "insert into ta_log (fid, Tanggal_Log, jam_Log, Datetime) values ('" & rsAdms(0) & "','" & Format(logDate.Date, "dd/MM/yyyy") & "', '" & logDate.ToString("hh:mm:ss") & "', '" & logDate & "')"
executeSQL(str, oConn.ConnectionString, False)
rsAdms.Read()
End While
'del record on admsdb
str = "truncate table checkinout"
executeSQL(str, admsDB.ConnectionString, False)
End Using
i'm new to vbnet and really have a little knowledge about it,, please help me,, and thank you in advance..
The issue is that you're using the HasRows property as your loop termination expression. The value of that property never changes. Either the reader has rows or it doesn't. It's not a check of whether it has rows left to read, so reading has no effect.
You are supposed to use the Read method as your flag. The data reader begins without a row loaded. Each time you call Read, it will load the next row and return True or, if there are no more rows to read, it returns False.
You normally only use HasRows if you want to do something special when the result set is empty, e.g.
If myDataReader.HasRows Then
'...
Else
MessageBox.Show("No matches found")
End If
If you don't want to treat an empty result set as a special case then simply call Read:
While myDataReader.Read()
Dim firstFieldValue = myDataReader(0)
'...
End While
Note that trying to access any data before calling Read will throw an exception.

How to know the available time and date in Reservation/CheckIn Program

I am using Visual Basic.Net and I have a problem in knowing the available Date, Time, and Room for the reservation/checkin of Hotel/Resort Reservation Program. Here in this code provided below, when I tried to reserve the specific room in a specific date and time, then restart the program, when I tried to save again with the unavailable room/date/time, the program's condition has wrongly allowed to save it again with the conflict schedule. I am using visual basic. Thank you :)
Dim varConflictSched As Boolean = False
Dim dsCheckIn As New DataSet
Dim daCheckIn As OdbcDataAdapter = New OdbcDataAdapter("SELECT * FROM tblCheckIn ORDER BY ID", MyConn)
daCheckIn.Fill(dsCheckIn, "tblCheckIn")
Dim DateTimeRangeNewIn(Val(Me.txtstaying.Text)) As DateTime
Dim DateCheckInNew As DateTime = Me.dtpCheckIn.Value
For a As Integer = 0 To dsCheckIn.Tables("tblCheckIn").Rows.Count - 1
Dim DateTimeRangeOldIn(dsCheckIn.Tables("tblCheckIn").Rows(a)("Staying")) As DateTime
REM Check if the room number is in used
If Me.cbRoomNumber.SelectedItem = dsCheckIn.Tables("tblCheckIn").Rows(a)("RoomNumber").ToString Then
REM Check if the date and time of the specified room number is in used
Dim varCheckInDate As DateTime = dsCheckIn.Tables("tblCheckIn").Rows(a)("CheckInDate")
For b As Integer = 0 To dsCheckIn.Tables("tblCheckIn").Rows(a)("Staying")
For c As Integer = 0 To Val(Me.txtstaying.Text)
DateTimeRangeOldIn(b) = varCheckInDate.AddDays(b)
DateTimeRangeNewIn(c) = DateCheckInNew.AddDays(c)
If DateTimeRangeOldIn(b).Date = DateTimeRangeNewIn(c).Date Then
If DateDiff(DateInterval.Minute, DateTimeRangeOldIn(b), DateTimeRangeNewIn(c)) <= 0 Then
varConflictSched = True
Exit For
End If
End If
Next
Next
End If
Next
If Me.txtAmount.Text = "" Or Me.txtSearch.Text = "" Or Me.txtstaying.Text = "" Or Me.txtTotal.Text = "" Or Me.cbRoomNumber.SelectedIndex = -1 Or Me.cbRoomtype.SelectedIndex = -1 Then
MessageBox.Show("Required field(s) should not be left blank" & vbCrLf & "Please try again", "NO BLANK SPACE", MessageBoxButtons.OK, MessageBoxIcon.Error)
ElseIf varConflictSched = True Then
MessageBox.Show("Can't set schedule with this date." & vbCrLf & "Please insert another date.", "CONFLICT", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Dim DAdapter As OdbcDataAdapter = New OdbcDataAdapter("SELECT * FROM tblCheckIN ORDER BY ID ", MyConn)
Dim DSet As New DataSet
DAdapter.Fill(DSet, "tblCheckIN")
Dim NewID As Integer = DSet.Tables("tblCheckIN").Rows(DSet.Tables("tblCheckIN").Rows.Count - 1)("ID") + 1
Dim CommCheckIn As OdbcCommand = New OdbcCommand("INSERT INTO tblCheckIN (ID,CustomerID,Roomtype,RoomNumber,Amount,CheckInDate,Staying)VALUES(" & NewID & ",'" & Me.txtSearch.Text & "','" & Me.cbRoomtype.SelectedItem & "','" & Me.cbRoomNumber.SelectedItem & "','" & Me.txtAmount.Text & "','" & Me.dtpCheckIn.Value & "' , '" & Me.txtstaying.Text & "')", MyConn)
MyConn.Open()
CommCheckIn.ExecuteNonQuery()
MyConn.Close()
MessageBox.Show("Your Checking-In is succesfully saved. ", "SAVED", MessageBoxButtons.OK, MessageBoxIcon.Information)
Me.ClearAll()
End If
You don’t need looping code to find a collision.
A collision occurs when:
RequestionStartDate <= EndDate
And
RequestEndDate >= StartDate
Of course you have to add roomnumber to above, but it rather simple.
So on book button, your code will do this:
Dim strSQL As String
Dim rstData As New DataSet
Dim daRead As SqlDataAdapter
strSQL = "select * from tblCheckIn where RoomNumber = #RoomNum " & _
" AND ( (#CheckIn <= CheckOutDate) AND (#CheckOut >= CheckInDate) )"
Dim MySql As SqlCommand = New SqlCommand(strSQL, GetCon)
MySql.Parameters.Add("#RoomNum", SqlDbType.Int).Value = Me.RoomNumber.Value
MySql.Parameters.Add("#CheckIn", SqlDbType.DateTime).Value = Me.dtpCheckIn.Value
MySql.Parameters.Add("#CheckOut", SqlDbType.DateTime).Value = Me.dtpCheckOut.Value
daRead.SelectCommand = MySql
daRead.Fill(rstData)
If rstData.Tables(0).Rows.Count > 0 Then
MsgBox("you have a booking collsion")
End If
The above works since you never allow a collsion, and the above will return any record that you "over lap". this includes the cases like this:
RequestStart RequestEnd
| |
| exsiting Start/end |
or
RequestStart RequestEnd
| |
| exist Start Exist end |
or
RequestStart RequestEnd
| |
| exist Start Exist end |
in fact any combination of ANY overlap will be found by the above simple query.

if record exists update else insert sql vb.net

I have the following problem, I am developing a Clinic application using vb.net, the doctor has the ability to add medical information using checkboxes checkbox2.text = "Allergy" textbox15.text is the notes for Allergy, I want to insert the record if the patient's FileNo(Textbox2.text) doesn't exist, if it does then update the notes only, so far I was able to update it after 3 button clicks I don't know why????
any help is appreciated :)
thanks in advance
Dim connection3 As New SqlClient.SqlConnection
Dim command3 As New SqlClient.SqlCommand
Dim adaptor3 As New SqlClient.SqlDataAdapter
Dim dataset3 As New DataSet
connection3.ConnectionString = ("Data Source=(LocalDB)\v11.0;AttachDbFilename=" + My.Settings.strTextbox + ";Integrated Security=True;Connect Timeout=30")
command3.CommandText = "SELECT ID,Type FROM Medical WHERE FileNo='" & TextBox2.Text & "';"
connection3.Open()
command3.Connection = connection3
adaptor3.SelectCommand = command3
adaptor3.Fill(dataset3, "0")
Dim count9 As Integer = dataset3.Tables(0).Rows.Count - 1
If count9 > 0 Then
For countz = 0 To count9
Dim A2 As String = dataset3.Tables("0").Rows(countz).Item("Type").ToString
Dim B2 As Integer = dataset3.Tables("0").Rows(countz).Item("ID")
TextBox3.Text = A2
If A2 = CheckBox1.Text Then
Dim sql4 As String = "update Medical set MNotes=N'" & TextBox22.Text & "' where FileNo='" & TextBox2.Text & "' and Type = '" & CheckBox1.Text & "' and ID='" & B2 & "';"
Dim cmd4 As New SqlCommand(sql4, connection3)
Try
cmd4.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.Message)
End Try
ElseIf A2 = CheckBox2.Text Then
Dim sql4 As String = "update Medical set MNotes=N'" & TextBox15.Text & "' where FileNo='" & TextBox2.Text & "' and Type = '" & CheckBox2.Text & "' and ID='" & B2 & "';"
Dim cmd4 As New SqlCommand(sql4, connection3)
Try
cmd4.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
Next
Else
If CheckBox1.Checked = True Then
Dim sql4 As String = "insert into Medical values('" & CheckBox1.Text & "',N'" & TextBox22.Text & "','" & TextBox2.Text & "')"
Dim cmd4 As New SqlCommand(sql4, connection3)
Try
cmd4.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
If CheckBox2.Checked = True Then
Dim sql4 As String = "insert into Medical values('" & CheckBox2.Text & "',N'" & TextBox15.Text & "','" & TextBox2.Text & "')"
Dim cmd4 As New SqlCommand(sql4, connection3)
Try
cmd4.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End If
I think one of your problems may be related to your reducing the count of your table rows by 1 and then testing it above 0:
Dim count9 As Integer = dataset3.Tables(0).Rows.Count - 1
If count9 > 0 Then
Try changing to:
Dim count9 As Integer = dataset3.Tables(0).Rows.Count
If count9 > 0 Then
Also, make sure one of the check-boxes (CheckBox1 or CheckBox2) mentioned later in your code is ticked.
-- EDIT --
Sorry - didn't explain why! The reason is that the majority of array/list like structures in .NET are zero based (i.e. start counting from 0 instead of 1).
The best course of action for you is to maximize your productivity by allowing SQL to do what it does best. Assuming you are using SQL Server 2008, the MERGE function is an excellent use case for the conditions that you have supplied.
Here is a very basic example that is contrived based upon some of your code:
CREATE PROCEDURE [dbo].[csp_Medical_Merge]
#MType int, #FileNo varchar(20), #MNotes varchar(max), #ID int, #OtherParams
AS
BEGIN
MERGE INTO [DatabaseName].dbo.Medical AS DEST
USING
(
/*
Only deal with data that has changed. If nothing has changed,
then move on.
*/
SELECt #MType, #MNotes, #FileNo, #ID, #OtherParams
EXCEPT
Select [Type], MNotes, FileNo, ID, OtherFields from [DatabaseName].dbo.Medical
) As SRC ON SRC.ID = DEST.ID
WHEN MATCHED THEN
UPDATE SET
DEST.MNOTES = SRC.MNOTES,
DEST.FileNo = SRC.FileNo,
DEST.Type = SRC.Type
WHEN NOT MATCHED BY TARGET THEN
INSERT (FieldsList)
VALUEs (FileNo, MNotes, etc, etc);
END
GO

Object reference not set to an instance of an object. For Loop

Function FindUserByCriteria(ByVal _state As String, ByVal _county As String, ByVal _status As String, ByVal _client As String, ByVal _department As String, ByVal _ordernumber As String) As DataTable
'Code to load user criteria from database
Dim ordertype As String
If _status = "Online" Then
ordertype = "Online"
ElseIf _status = "Tax Cert Call" Then
ordertype = "Call"
End If
Dim TaxConnStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ConfigurationManager.AppSettings("Database")
Dim dbConnection As OleDbConnection = New OleDbConnection(TaxConnStr)
Try
Dim queryString As String
queryString = "Select Username, Amount, Rank FROM UserCriteria "
queryString += "WHERE UserCriteria.State = '" & _state & "' AND UserCriteria.County = '" & _county & "' AND UserCriteria.Status = '" & _status & "' AND UserCriteria.Client = '" & _client & "' AND UserCriteria.Department = '" & _department & "' AND UserCriteria.OrderNumber = '" & _ordernumber & "';"
Dim dbCommand As OleDbCommand = New OleDbCommand
dbCommand.CommandText = queryString
dbCommand.Connection = dbConnection
Dim dataAdapter As OleDbDataAdapter = New OleDbDataAdapter
dataAdapter.SelectCommand = dbCommand
Dim dataSet As DataSet = New DataSet
dataAdapter.Fill(dataSet)
If dataSet.Tables(0).Rows.Count >= 1 Then
FindUserByCriteria = dataSet.Tables(0)
End If
Console.WriteLine(vbCrLf)
For i = 0 To FindUserByCriteria.Rows.Count - 1
If Not IsUserOnline(FindUserByCriteria.Rows(i).Item("UserName")) Then
FindUserByCriteria.Rows(i).Delete()
End If
Next
FindUserByCriteria.AcceptChanges()
Catch ex As Exception
Console.WriteLine(ex.Message)
myLogger.Log(ex.Message)
SendMail(ex.Message)
Finally
dbConnection.Close()
End Try
End Function
So, i get the "Object reference not set to an instance of an object." error at the
For i = 0 To FindUserByCriteria.Rows.Count - 1
line. I swear this was working for me not just 3 days ago...not sure what has changed in my code recently to make this error pop up. Any help would be nice.
you need to reverse the for loop for
For i = FindUserByCriteria.Rows.Count - 1 to 0 step -1
you need to delete backward otherwise you will reach an index already deleted
or you simply need to put the use of any FindUserByCriteria inside the if where it get set
If dataSet.Tables(0).Rows.Count >= 1 Then
FindUserByCriteria = dataSet.Tables(0)
Console.WriteLine(vbCrLf)
For i = 0 To FindUserByCriteria.Rows.Count - 1
If Not IsUserOnline(FindUserByCriteria.Rows(i).Item("UserName")) Then
FindUserByCriteria.Rows(i).Delete()
End If
Next
FindUserByCriteria.AcceptChanges()
End If