Check if a table is empty on SQLite - vb.net

I'm trying to adapt to VB.NET the code of the most voted answer from this post:
Sqlite Check if Table is Empty
Original code is
SQLiteDatabase db = table.getWritableDatabase();
String count = "SELECT count(*) FROM table";
Cursor mcursor = db.rawQuery(count, null);
mcursor.moveToFirst();
int icount = mcursor.getInt(0);
if(icount>0)
//leave
else
//populate table
My code looks like ('Only to have a message on the screen I will fill the If - Else code later')
Using conn As New SQLiteConnection("Data Source=myDataBase.sqlite;Version=3;foreign keys=true")
Try
conn.Open()
Dim emptyUserTable = "SELECT COUNT(*) FROM usersTable"
Dim cmdIsEmpty As SQLiteCommand = New SQLiteCommand(emptyUserTable, conn)
Try
Dim Answer As Integer
Answer = cmdIsEmpty.ExecuteNonQuery()
MsgBox(Answer)
Catch ex As Exception
MsgBox(ex.ToString())
End Try
End Using
But the "Answer" is allways -1, with empty table or not.
I donĀ“t know how to use getWritableDataBase because I get a
getWritableDatabase is not a member of SQLiteConnection
The same with rawQuery.
How can I check if usersTable is empty or not on VB.NET?

I've abstracted your code a little so it can be used for any table:
Private Function IsTableEmpty(tblName As String) As Boolean
Dim sql = String.Format("SELECT COUNT(*) FROM {0}", tblName)
Using conn As New SQLiteConnection(LiteConnStr)
Using cmd As New SQLiteCommand(sql, conn)
conn.Open()
Dim rows = Convert.ToInt32(cmd.ExecuteScalar())
Return rows = 0
End Using
End Using
End Function
Usage:
If IsTableEmpty("usersTable") Then
Console.Beep()
End If
Notes
The command object should be disposed when you are done with it, so it is used on a Using block.
There is not need to copy your connection string everywhere. You can define it once as a form/class level variable and reuse it everywhere
ExecuteScalar() gets the count back, then it is tested for 0 rows

Related

Select max value in MS Access database

I need to select the max value in my row column. When I hit line
(FindCurrentTimeCard = Val(myreader("Row"))
I get an error:
System.IndexOutOfRangeException
Code:
Public Function FindCurrentTimeCard() As Integer
Dim myconnection As OleDbConnection = New OleDbConnection
Dim query As String = "Select MAX(Row) from Table2"
Dim dbsource As String =("Provider=Microsoft.ACE.OLEDB.12.0;DataSource=S:\Docs\PRODUCTION\Shop Manager\Shop_Manager\Shop_Manager\Database2.accdb;")
Dim conn = New OleDbConnection(dbsource)
Dim cmd As New OleDbCommand(query, conn)
Try
conn.Open()
Dim myreader As OleDbDataReader = cmd.ExecuteReader()
myreader.Read()
FindCurrentTimeCard = Val(myreader("Row"))
conn.Close()
Catch ex As OleDbException
MessageBox.Show("Error Pull Data from Table2")
FindCurrentTimeCard = 1
End Try
End Function
Table2
The issue is that when you evaluate an aggregate function (or indeed, any expression performing some operation on a field or fields), the result of such evaluation will be assigned an alias (such as Expr1000) unless an alias is otherwise stated.
Hence, when you evaluate the SQL statement:
select max(table2.row) from table2
MS Access will return the result assigned to an alias such as Expr1000:
Hence, the SQL statement does not output a column named Row, causing your code to fail when attempting to retrieve the value of such column:
FindCurrentTimeCard = Val(myreader("Row"))
Instead, you should specify an alias to which you may refer in your code, e.g.:
select max(table2.row) as maxofrow from table2
With your function then returning the value associated with such column:
FindCurrentTimeCard = Val(myreader("maxofrow"))
Comments and explanations in-line
Public Function FindCurrentTimeCard() As Integer
Dim CurrentTimeCard As Integer
'The Using block ensures that your database objects are closed and disposed
'even it there is an error
'Pass the connection string directly to the connection constructor
Using myconnection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;DataSource=S:\Docs\PRODUCTION\Shop Manager\Shop_Manager\Shop_Manager\Database2.accdb;")
Dim query As String = "Select MAX(Row) from Table2"
Using cmd As New OleDbCommand(query, myconnection)
Try
myconnection.Open()
'since you are only retrieving a single value
'you can used .ExecuteScalar which gets the value
'in the first row, first column
CurrentTimeCard = CInt(cmd.ExecuteScalar)
Catch ex As OleDbException
MessageBox.Show("Error Pull Data from Table2")
End Try
End Using
End Using
'vb.net uses the Return statement to return the value of the function
Return CurrentTimeCard
End Function

Taking one value from a table

sorry if this has been asked before but I everything I found has not helped.
I'm looking to set a value from a table to the text property of a label. This is what I have so far:
In a separate class with the connection string "conn" -
(SQL Region)
Public Const SELECT_1 As String = "SELECT TOP 1 * FROM [TableTimes]
WHERE [timeID] = #PKey"
(Methods Region)
Public Shared Function returnOneRow(PrimaryKey As Integer) As TableTimes
Dim returnRow As New TableTimes(0)
Dim conn As New SqlConnection
conn.connectionstring = Conn.getConnectionString
Dim command As New SqlCommand
command.connection = conn
command.CommandType = CommandType.Text
command.CommandText = SQL.SELECT_1
command.Parameters.AddWithValue("#PKey", PrimaryKey)
Try
conn.Open()
Dim dR As IDataReader = command.ExecuteReader
If dR.Read() Then
returnRow.timeID = PK
If Not IsDBNull(dR(Fields.linkID)) Then returnRow.linkID = dR(Fields.linkID)
If Not IsDBNull(dR(Fields.dateTime)) Then returnRow.dateTime = dR(Fields.dateTime)
End If
Catch ex As Exception
Console.WriteLine(Err.Description)
End Try
Return returnRow
End Function
And then back in the main form I am trying to set the dateTime to a label based on what primary key (timeID) I enter as a parameter. This is the closest I can think of:
label.Text = (Tables.TableTimes.returnOneRow(1).dateTime).ToString
I know the output should be "2016-02-04 10:00:00" for the row with the timeID of 1 based on my table data, but instead it returns "0001-01-01 12:00:00" no matter what parameter I enter.
I would prefer to not change my method or sql statement and just change how I call the function in the main form if that's possible.
Thank you!

Search records in database for those that match what a user enters

I'm trying to write a function that searches records in my database for the object of those that match the SearchCriteria. The functions parameters look like so:
RetrieveObject(SearchCriteria) As String (SearchCritera is a string aswell)
Right now for testing purposes I am using a console app that asks the user to search by first name.
Console.Writeline("Search by first name: ")
Dim firstName = Console.Readline()
I then use my function: RetrieveObject(firstName)
I want my function to show all the values (lastname, titlename, state, zip) for that particular person that was passed to the RetrieveObject function.
The problem I am having is that I cannot seem to understand how I'm going to match what the user enters with the value in the database.
If anyone could just put me in the right direction to help me understand how to accomplish this, I'd be so grateful!
Here is my code so far:
Private Function RetrieveObject(SearchCriteria As String) As String
Dim cn As OdbcConnection = New OdbcConnection(myCon)
Dim myQuery = "SELECT * FROM Applicant WHERE [strFirstName] LIKE '%son'"
Using com As New OdbcCommand(myQuery)
cn.Open()
com.Connection = cn
com.CommandType = CommandType.Text
com.CommandText = myQuery
com.Parameters.AddWithValue("#strFirstName", SearchCriteria)
Try
com.ExecuteReader()
Catch ex As Exception
MsgBox(ex.Message.ToString())
End Try
End Using
Return SearchCriteria
End Function
Thanks again!
To create a WHERE condition you need to provide (at the most basic level) three informations to the database engine. The first bit is the column name that you want to search for, the second piece is the operator that you want to use for matching records, and finally the value to search for
SELECT * FROM table WHERE FieldName = 'AStringValue'
Of course we could have a lot of variations with operators and field datatype but this answer is limited to your actual situation.
It is important to note that your query could return more than one record (in particular if you add wildcards operators as LIKE, so you cannot simply return a single value with this query, but instead you return a DataTable where you can loop over the Rows collection to see all the records returned by the query
So your code should be changed to
Private Function RetrieveObject(SearchCriteria As String) As DataTable
Dim myQuery = "SELECT * FROM Applicant WHERE [strFirstName] LIKE ?"
Try
Using cn = New OdbcConnection(myCon)
Using da = new OdbcDataAdapter(myQuery, cn)
da.SelectCommand.Parameters.Add("?", OdbcType.VarChar).Value = SearchCriteria
Dim dt = new DataTable()
da.Fill(dt)
return dt
End Using
End Using
Catch ex As Exception
MsgBox(ex.Message.ToString())
return Nothing
End Try
End Function
Now you could call this method with something like
Dim table = RetrieveObject("John%")
if table IsNot Nothing Then
For Each row in table.Rows
Console.WriteLine(row["strFirstName"].ToString())
Next
End If
If you really need to return a json string with all the FirstName matched then you could add this to the last lines of the code above
.....
da.Fill(dt)
Dim names = dt.AsEnumerable().Select(Function(x) x.Field(Of String)("strFirstName")).ToArray()
string output = JsonConvert.SerializeObject(names);
return output;
And of course change again the return value to be a string.
You can also pass your search criteria into function which returns dataset as shown below , one more thing ,you can use the function in textbox textchange event in forms
Also while search include LIKE as LIKE '%" & #strFirstName & "%' which can help you narrow search results if needed
Public Function Search(ByVal Criteria As String) As DataSet
Try
Dim ds As New DataSet
Using sqlCon As New SqlConnection(connStr)
stQuery="SELECT * FROM Applicant WHERE [strFirstName]
LIKE '%" & #strFirstName & "%'"
Dim sqlCmd As New SqlCommand(stQuery, sqlCon)
Dim sqlAda As New SqlDataAdapter(sqlCmd)
sqlCmd.CommandType = CommandType.Text
sqlCmd .Parameters.AddWithValue("#strFirstName", Criteria )
sqlAda.Fill(ds)
End Using
Return ds
Catch ex As Exception
MsgBox(ex.Message.ToString())
End Try
End Function

Update View in Access not updating record even though return value in VB.Net return 1

I'm stuck on this problem and cannot seem to fix it, my code below runs and and checkinsert returns 1 if one record is updated or 0 if none, problem is in Access the table column is not updated.
I cannot find why its not working, so i'm hoping a fresh pair of eyes can spot the problem.
If I run the update View in Access, it works OK.
UPDATE tblStudentNameAndScore
SET tblStudentNameAndScore.QuizCount = QuizCount+1,
tblStudentNameAndScore.TimeLastQuestionAsked = Now()
WHERE tblStudentNameAndScore.StudentID=[?];
VB.Net
Public Function UpdateStudentScoreIfAnswerCorrect(ByVal studentId As String) As String
Try
Dim strAccessConn As String = _appConfigDbConn
Dim cn As OleDbConnection = New OleDbConnection(strAccessConn)
cn.Open()
Dim da As New OleDbCommand("qryUpdateStudentScore", cn)
da.CommandType = CommandType.StoredProcedure
'da.Parameters.AddWithValue("#StudentID", studentId)
da.Parameters.Add("#StudentID", OleDbType.VarChar).Value = studentId
Dim checkinsert As New Integer
checkinsert = da.ExecuteNonQuery()
If checkinsert > 0 Then
Return "Success"
End If
cn.Close()
cn.Dispose()
Return "Fail"
Catch ex As Exception
Throw New ApplicationException(ex.InnerException.Message.ToString())
End Try
End Function
I'm using Access 2010 and VB.NET Express
Thanks for any help
I used your exact code and it seemed to work. Maybe my connection string was a bit different, but it worked in my test.
My connection string:
Dim strAccessConn As String = "Provider= Microsoft.ACE.OLEDB.12.0;Data Source=c:\555\Test For StackOverflow.accdb"

get column value according to another column value from datatable in vb.net

i have a datatable similar to this:
id msg
1 thank you..
2 kindly...
3 please insert..
4 please stop
i need to get a msg according to a specific id from the datatable that's how i'm filling my datatable:
msgTable = selectMsg()
MsgBox(i need to get the msg here)
Public Function selectMsg() As DataTable
Dim command As SqlCommand = New SqlCommand("selectMsg", cn)
command.CommandType = CommandType.StoredProcedure
Dim da As New SqlDataAdapter(command)
'If dt.Rows.Count <> 0 Then
' dt.Rows.Clear()
'End If
Try
da.Fill(msgDS, "N_AI_HOME_CARE")
msgDT = msgDS.Tables(0)
Catch ex As Exception
logFile("SP selectMsg ---" + ex.Message)
End Try
Return msgDT
End Function
any suggestion will be much appreciated !
Supposing that your stored procedure returns the whole datatable of your messages (a very bad move because if the table is big you could have performance and network problems) then you need to apply the Select method with a filter expression to your returned datatable
msgTable = selectMsg()
Dim rows() = msgTable.Select("ID = " & idOfMessage)
if rows.Length > 0 then
MsgBox(row(0)(1).ToString()) ' read the first row, second column of the table'
End If
But I think you should use a more correct approach using a simple ExecuteScalar that doesn't return the entire datatable but just the first row and first column of a query
Public Function selectMsg(idOfMessage as Integer) As String
Dim command As SqlCommand = New SqlCommand("SELECT msg from tableName where ID = #id", cn)
command.Parameters.AddWithValue("#id", idOfMessage)
Dim result = command.ExecuteScalar()
if string.IsNullOrEmpty(result) Then
result = "No message found"
End If
return result
End Function
well acctually i just found that you use
MsgBox(msgTable.Rows(0)(1).ToString())
without any select method :)