My application outputs DBNull but in the database it isn't DBNull - mysql

My application outputs "System.InvalidCastException: "Object cannot be cast from DBNull to other types."
Dim sqlquery = String.Format("SELECT id, date, film, start_time, end_time, participants_count, confirmed FROM calendar WHERE id='" & id & "'")
connection.Open()
With command
.Connection = connection
.CommandText = sqlquery
End With
dataadapter.SelectCommand = command
dataadapter.Fill(datatable)
id = Convert.ToInt32(datatable.Rows(0).Item("id"))
Dim date_ As String = datatable.Rows(0).Item("date").ToString
Dim film As String = datatable.Rows(0).Item("film").ToString
Dim start_time As String = datatable.Rows(0).Item("start_time").ToString
Dim end_time As String = datatable.Rows(0).Item("end_time").ToString
Dim participants_count As Integer = Convert.ToInt32(datatable.Rows(0).Item("participants_count"))
Dim confirmed As Integer = Convert.ToInt32(datatable.Rows(0).Item("confirmed"))
The problem arises there: "participants_count" and "confirmed". All the other columns are working perfectly. In the database these two columns aren't DBNull: Picture of the real MySQL-Result. They can't even be DBNull: MySQL Structure
If I output the value of both with a MessageBox it also contains nothing.
I would be very grateful if I became a solution.
Julius

Dim participants_count As Integer
Integer.TryParse(datatable.Rows(0).Item("participants_count").Tostring, participants_count)
This will attempt to convert it to an Integer and returns 0 if it fails otherwise it will set the value to participants_count. This should help with the DBNull issue. You can do this with the confirmed field to.

You can get the query results without using a DataTable. That way you can be exact about the data types and so there is less chance of something unexpected happening:
Dim connStr = "your connection string"
Dim sql = "SELECT `id`, `date`, `film`, `start_time`, `end_time`, `participants_count`, `confirmed` FROM `calendar` WHERE `id` = #id"
Dim id = "2"
Dim date_ As DateTime
Dim start_time As TimeSpan
Dim end_time As TimeSpan
Dim participants_count As Integer
Dim confirmed As Boolean
Using conn As New MySqlConnection(connStr)
Using cmd As New MySqlCommand(sql, conn)
cmd.Parameters.Add(New MySqlParameter With {
.ParameterName = "#id",
.MySqlDbType = MySqlDbType.VarChar,
.Size = 8,
.Value = id})
conn.Open()
Dim rdr = cmd.ExecuteReader()
If rdr.HasRows Then
date_ = rdr.GetDateTime(1)
start_time = rdr.GetTimeSpan(3)
end_time = rdr.GetTimeSpan(4)
participants_count = rdr.GetInt16(5)
confirmed = rdr.GetBoolean(6)
End If
conn.Close()
End Using
End Using
The SQL parameter should have its .MySqlDbType and .Size set to match the id column in the database. The rdr.Get... functions should be chosen to match the types from the database.

Related

trying to input data into my .NET program through a mySQL database

Hi I am trying to import data from a database into variable in my program but I keep on getting the error:
System.InvalidCastException: 'Conversion from type 'DBNull' to type 'String' is not valid.'
Dim value As Integer
Dim MySqlConn As MySqlConnection
Dim sql As New MySqlCommand
Dim dataAdapter As New MySqlDataAdapter
Dim dataFromDB As New DataSet
Dim numrows As Integer
MySqlConn = New MySqlConnection
MySqlConn.ConnectionString = "server=localhost;user id=root;database=gamedata;"
Try
MySqlConn.Open()
sql = New MySqlCommand("SELECT Ccost FROM cards WHERE `UserName` = '" & UserName & "' AND `Game` = '" & game & "'", MySqlConn)
dataAdapter = New MySqlDataAdapter(sql)
dataAdapter.Fill(dataFromDB)
numrows = dataFromDB.Tables(0).Rows.Count
For counter = 1 To numrows - 1
value = dataFromDB.Tables(0).Rows(counter).Item(0)
Next
sql = New MySqlCommand("Select Level,Health,Score,PlayerTime FROM savedata WHERE `UserName` = '" & UserName & "' AND `Game` = '" & game & "'", MySqlConn)
dataAdapter = New MySqlDataAdapter(sql)
dataAdapter.Fill(dataFromDB)
numrows = dataFromDB.Tables(0).Rows.Count
'For counter = 0 To 1
level = dataFromDB.Tables(0).Rows(0).Item(0)
Phealth = dataFromDB.Tables(0).Rows(0).Item(1)
score = dataFromDB.Tables(0).Rows(0).Item(2)
time = dataFromDB.Tables(0).Rows(0).Item(3)
Catch ex As MySqlException
MsgBox("Error " & ex.Message)
End Try
database code:
use `Gamedata`;
create table `SaveData`
(`GameCode` int AUTO_INCREMENT not null,`Game` enum('1','2','3','4') not null,`UserName` varchar(20) not null,`level` int not null, `Health` int not null,`Score` int not null,`PlayerTime` time not null,
foreign key(`UserName`) REFERENCES `player` (`UserName`),
primary key(`GameCode`));
Here is a slightly different approach. This code requires the following Imports at the top of the file.
Imports System.Data.SqlTypes
You need to declare your database objects with Using blocks so they will be closed and disposed even if there is an error. Queries should always be written using parameters. Not it only does it avoid sql injection but it is easier to read and write.
A database integer can be null but not so in .net. The SqlInt32 has an .IsNull property that we can use for testing. If you try to convert a null string to a string by, for example calling .ToString, you will get an error.
Private ConStr As String = "server=localhost;user id=root;database=gamedata;"
Private Sub OpCode(UserName As String, Game As String)
Dim value As Integer
Dim dt As New DataTable
Dim strSql = "SELECT Ccost FROM cards WHERE `UserName` = #UserName AND `Game` = #Game"
Try
Using Sql As New MySqlCommand(strSql, New MySqlConnection(ConStr))
Sql.Connection.Open()
Sql.Parameters.Add("#UserName", MySqlDbType.VarChar).Value = UserName
Sql.Parameters.Add("#Game", MySqlDbType.VarChar).Value = Game
Dim obj = Sql.ExecuteScalar
value = If(obj Is Nothing, 0, CInt(obj))
Sql.CommandText = "Select Level,Health,Score,PlayerTime FROM savedata WHERE `UserName` = #UserName AND `Game` = #Game;"
Using reader = Sql.ExecuteReader
dt.Load(reader)
End Using
End Using
Dim level = If(CType(dt.Rows(0)(0), SqlString).IsNull, "", dt.Rows(0)(0).ToString)
Dim Phealth = If(CType(dt.Rows(0)(1), SqlString).IsNull, "", dt.Rows(0)(1).ToString)
Dim score = If(CType(dt.Rows(0)(2), SqlInt32).IsNull, 0, CInt(dt.Rows(0)(2)))
Dim time = If(CType(dt.Rows(0)(3), SqlInt32).IsNull, 0, CInt(dt.Rows(0)(3)))
Catch ex As MySqlException
MsgBox("Error " & ex.Message)
End Try
End Sub

How do I generate a new Primary Key ID through code?

So basically I'm trying to write the below code to the database and I have the primary key as an Int and it was autogen but when writing to the database it didnt allow me to do it kept telling me that I wasn't allowed to enter a null value (because the code is obviously not writing to the primary key field) so I used the line
cmd.Parameters.Add("#EventID", SqlDbType.Int).Value = 3
But the problem is I have to change the value each time I want to test a new record i.e. 1,2,3,4 and so on. I was wondering is there a line of code I can put in to make it create a value by adding +1 each time so I don't need to go into the code and enter a new number each time. Below is the full code writing to the database so you can see a better view of it
Dim Con As SqlConnection
Dim cmd As SqlCommand
Dim recordsAffected As String
Dim cmdstring As String = "INSERT [Event Table](EventID, EventTypeID, EventName, VenueName, NumberOfGuests, Date, ClientAddress, WeddingName, BuildingAddress) Values(#EventID, #EventTypeID, #EventName, #VenueName, #NumberOfGuests, #Date, #ClientAddress, #WeddingName, #BuildingAddress)"
Con = New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\YellowDoor.mdf;Integrated Security=True;User Instance=True")
cmd = New SqlCommand(cmdstring, Con)
cmd.Parameters.Add("#EventID", SqlDbType.Int).Value = 3
cmd.Parameters.Add("#EventTypeID", SqlDbType.Text).Value = EventTypeDD.SelectedValue
cmd.Parameters.Add("#EventName", SqlDbType.Text).Value = EventNametxt.Text
cmd.Parameters.Add("#VenueName", SqlDbType.Text).Value = VenueLoDD.SelectedValue
cmd.Parameters.Add("#NumberOfGuests", SqlDbType.Int).Value = CInt(NumOfGtxt.Text)
cmd.Parameters.Add("#Date", SqlDbType.Int).Value = CInt(DateTxt.Text)
cmd.Parameters.Add("#ClientAddress", SqlDbType.Text).Value = txtAddress.Text
cmd.Parameters.Add("#WeddingName", SqlDbType.Text).Value = txtWedding.Text
cmd.Parameters.Add("#BuildingAddress", SqlDbType.Text).Value = txtBAddress.Text
Con.Open()
recordsAffected = cmd.ExecuteNonQuery
Con.Close()
If your EventID is an IDENTITY column, you should never try to set a value for it.
Just ignore that field both as parameter or inside the INSERT command.
And you can retrieve the value assigned by the database engine to your field in this way
Dim Con As SqlConnection
Dim cmd As SqlCommand
Dim cmdstring As String = "INSERT [Event Table] " & _
"(EventTypeID, EventName, VenueName, NumberOfGuests, [Date], ClientAddress, " & _
"WeddingName, BuildingAddress) Values(#EventTypeID, #EventName, #VenueName, " & _
"#NumberOfGuests, #Date, #ClientAddress, #WeddingName, #BuildingAddress); " & _
"SELECT SCOPE_IDENTITY()"
Using Con = New SqlConnection(".....")
Using cmd = New SqlCommand(cmdstring, Con)
cmd.Parameters.Add("#EventTypeID", SqlDbType.Text).Value = EventTypeDD.SelectedValue
.....
Con.Open()
Dim result = cmd.ExecuteScalar()
if result IsNot Nothing Then
Dim newEventID = Convert.ToInt32(result)
....
End If
End Using
End Using
With this code you don't pass anything for the EventID field but you add a second command text to your query. This second command will return the last value generated for an IDENTITY column by the database for your connection. This double command (A.K.A. batch commands) is executed using ExecuteScalar because we are interested in the single value returned by the SELECT SCOPE_IDENTIY()
Notice also that DATE is a reserved word in T-SQL so it is possible to use it as name of a column only if you enclose it in square brackets

How to use if condition using two tables in MySQL

Can anyone help me on this? What I wanted to happen is that if the value exist in Table 1 (employee), it will then check Table 2 (mobilelist) if it also exist there. Here's the code:
Private Sub TextBox_IDNumber_LostFocus(sender As Object, e As EventArgs) Handles TextBox_IDNumber.LostFocus
Mysqlconn = New MySqlConnection
Mysqlconn.ConnectionString = "server=localhost;userid=root;password=12345;database=my_db"
Dim READER As MySqlDataReader
Dim READER2 As MySqlDataReader
Dim _isFound As Boolean = False
Dim _isExist As Boolean = False
Try
Mysqlconn.Open()
Dim empmr As String
Dim empml As String
Dim fn1 As String
Dim fn2 As String
Dim ln1 As String
Dim ln2 As String
empmr = "Select * from my_db.employee where IDNumber ='" & TextBox_IDNumber.Text & "'"
empml = "Select * from my_db.mobilelist where IDNumber = '" & TextBox_IDNumber.Text & "' AND DateAssigned is not Null AND DateReturned is Null"
Command = New MySqlCommand(empmr, Mysqlconn)
READER = Command.ExecuteReader
While READER.Read()
_isFound = True
fn1 = READER.GetString("FirstName")
ln1 = READER.GetString("LastName")
End While
If _isFound Then
TextBox_FirstName.Text = fn1
TextBox_LastName.Text = ln1
ElseIf Not _isExist Then
MessageBox.Show("Record Not Found in Master Data")
TextBox_IDNumber.Clear()
TextBox_FirstName.Clear()
TextBox_LastName.Clear()
TextBox_IDNumber.Focus()
End If
Catch ex As MySqlException
MessageBox.Show("Error!")
Finally
Mysqlconn.Dispose()
End Try
End Sub
Assuming you have the appropriate Primary Key and Foreign Key relationship between the tables Employee and MobileList you use this query to find records on the MobileList table for an employee:
Dim myQuery as string
myQuery = "SELECT FirstName, LastName, MobileNumber
FROM Employee
JOIN MobileList
ON Employee.IDNumber=MobileList.IDNumber
WHERE Employee.IDNumber=#ID"
Note: You should rename the IDNumber column on the MobileList to avoid confusion.
You should also improve your access to the database with the Using statement and take advantage of Parameters to prevent SQL injection:
Using myConn As New SqlConnection("Your connection string")
myConn.Open()
Using myCmd As New SqlCommand(myQuery, myConn)
myCmd.Parameters.AddWithValue("#ID", "Your ID value")
Using myReader As SqlDataReader = myCmd.ExecuteReader()
If myReader.HasRows Then
'There are mobile numbers issued to that ID'
Do While myReader.Read()
'Iterate through all existing records'
Loop
Else
'There are no mobile numbers issued to that ID'
End If
End Using
End Using
End Using
Keep in mind that this gives you the mobile numbers for a particular employee, it doesn't tell you if a particular employee exists.

Sql Select Data Mysql Error

Newbie want to ask
I want to display the data based on the limit input by the user,
example: user enter a value of 100, and the data will appear as 100.
limit value is always changing according to the value in the input by the user
but there is a problem You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near'' 100'' at line 1.
please help to resolve this problem ..
thank you
Public Function Tampil_Stock(ByVal limit_kar As String) As List(Of Class_stock)
Dim tmpBaca As New List(Of Class_stock)
Dim cmd As New MySqlCommand
Dim dreader As MySqlDataReader
Dim ds As New DataSet
Dim sql As String
Try
sql = "SELECT NoReg,status,status_kartu FROM tb_stock WHERE status= '0' and status_kartu= '0' ORDER BY NoReg ASC limit ?fn"
cmd = New MySqlCommand(sql, myconnection.open)
cmd.Parameters.Add(New MySqlParameter("?fn", MySqlDbType.String, 10)).Value = limit_kar
dreader = cmd.ExecuteReader
While dreader.Read
Dim objTemp As New Class_stock
objTemp.NoReg_ = dreader.Item("NoReg")
'objTemp.NoPin_ = dreader.Item("NoPin")
objTemp.status_ = dreader.Item("status")
objTemp.status_kartu_ = dreader.Item("status_kartu")
tmpBaca.Add(objTemp)
End While
Catch sqlex As MySqlException
Throw New Exception(sqlex.Message.ToString())
End Try
myconnection.close()
Return tmpBaca
'dreader.Close()
End Function
Insert data in listview
Sub Loadlist (Optional ByVal criteria As Integer = 0)
Dim objList As List (Of Class_stock)
As String Dim nourut
objList = stock.Tampil_Stock (criteria)
nourut = 1
Me.ListView1.Items.Clear ()
For i As Integer = 0 To objList.Count - 1
nourut = ListView1.Items.Count + 1
Me.ListView1.Items.Add (nourut)
Me.ListView1.Items (i). SubItems.Add (objList.Item (i). NoReg_)
Next
end Sub
limit_kar should be an integer, you used string. Also changed the parameter to integer instead of string.
Public Function Tampil_Stock(ByVal limit_kar As Integer) As List(Of Class_stock)
Dim tmpBaca As New List(Of Class_stock)
Dim cmd As New MySqlCommand
Dim dreader As MySqlDataReader
Dim ds As New DataSet
Dim sql As String
Try
sql = "SELECT NoReg,status,status_kartu FROM tb_stock WHERE status= '0' and status_kartu= '0' ORDER BY NoReg ASC limit ?fn"
cmd = New MySqlCommand(sql, myconnection.open)
cmd.Parameters.Add(New MySqlParameter("?fn", MySqlDbType.Int)).Value = limit_kar
dreader = cmd.ExecuteReader
While dreader.Read
Dim objTemp As New Class_stock
objTemp.NoReg_ = dreader.Item("NoReg")
'objTemp.NoPin_ = dreader.Item("NoPin")
objTemp.status_ = dreader.Item("status")
objTemp.status_kartu_ = dreader.Item("status_kartu")
tmpBaca.Add(objTemp)
End While
Catch sqlex As MySqlException
Throw New Exception(sqlex.Message.ToString())
End Try
myconnection.close()
Return tmpBaca
'dreader.Close()
End Function

How to convert an SQLCOMMAND to INT

I have the following code where table name is student and column name is sem_of_study from the type of INT
Dim userquery As String = "select sem_of_study from student where username='" + Session("user") + "'"
Dim usercom As New SqlCommand(userquery, conn)
Dim a = usercom.ExecuteReader
I was wondering if I could convert the SQL Command into integer so I can use it in IF statements!!
so that variable a would
if a=1 then
else if a=2 then
Besides the fact you should use parameterized queries (search SO -- plenty of examples), you need to do something like this reading in the DataReader rows:
Dim a as Integer
Dim myReader As SqlDataReader = usercom.ExecuteReader()
If myReader.HasRows Then
myReader.Read()
a = myReader.GetInt32(0)
End If
And for the parameters:
Dim userquery As String = "select sem_of_study from student where username=#username"
Dim usercom as SqlCommand = new SqlCommand()
usercom.Connection = conn
usercom.CommandType = CommandType.Text
usercom.CommendText = userquery
usercom.Parameters.AddWithValue("username", Session("user"))