Attempting to insert picture into sql database - mysql

I want to insert an image into my SQL database. I have this code currently and it is entering a Null where the image should be. Why is this occurring?
I'm using here a simple addquestion Class.
You can find the code I used bellow :
Imports System.IO
Imports System.Data.SqlClient
Public Class addquestion
Dim con As New System.Data.Odbc.OdbcConnection("DRIVER={MySQL ODBC 5.2 ANSI Driver};SERVER=localhost;PORT=3306;DATABASE=physicsapp;USER=root;PASSWORD=root;OPTION=3;")
Dim rs As Odbc.OdbcDataReader
Private Sub addquestion_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub QuestionButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles QuestionButton.Click
Dim myFileDlog As New OpenFileDialog
myFileDlog.InitialDirectory = "c:/"
myFileDlog.Filter = "All Files (*.*)|*.*" & _"|Picture Files (*.png)|*.png"
myFileDlog.FilterIndex = 1
myFileDlog.RestoreDirectory = True
If myFileDlog.ShowDialog() = _
DialogResult.OK Then
If Dir(myFileDlog.FileName) <> "" Then
MsgBox("File Exists: " & _
myFileDlog.FileName, _
MsgBoxStyle.Information)
Else
MsgBox("File Not Found", _
MsgBoxStyle.Critical)
End If
End If
qnametextbox.Text = myFileDlog.FileName
End Sub
Dim ans as Char = "B"
Dim file As String = qnametextbox.Text
Dim question As Image
question = Image.FromFile(file)
Dim ms As New MemoryStream()
question.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
Dim data As Byte() = ms.GetBuffer()
Dim s As String = "INSERT INTO tests VALUES (#Question ,'" & ans & "', 200)"
Dim sql As New Odbc.OdbcCommand(s, con)
sql.Parameters.Add("#Question", Odbc.OdbcType.VarBinary).Value = data
con.Open()
sql.ExecuteNonQuery()
con.Close()
this is the definition of the table
CREATE TABLE `tests` (
`Question` blob NOT NULL,
`CorrectAnswer` varchar(8) DEFAULT NULL,
`QuestionNumber` int(8) NOT NULL AUTO_INCREMENT,
KEY `QuestionNumber` (`QuestionNumber`)
) ENGINE=MyISAM AUTO_INCREMENT=201 DEFAULT CHARSET=utf8
Any suggestion can help.
Thanks.

Regardless of what data access technology or database you use, you need to convert am Image to a Byte first and then save that. On retrieval, you convert the Byte array back to an Image.
To save:
Dim connection As New SqlConnection("connection string here")
Dim command As New SqlCommand("UPDATE MyTable SET Picture = #Picture WHERE ID = 1", connection)
'Create an Image object.'
Using picture As Image = Image.FromFile("file path here")
'Create an empty stream in memory.'
Using stream As New IO.MemoryStream
'Fill the stream with the binary data from the Image.'
picture.Save(stream, Imaging.ImageFormat.Jpeg)
'Get an array of Bytes from the stream and assign to the parameter.'
command.Parameters.Add("#Picture", SqlDbType.VarBinary).Value = stream.GetBuffer()
End Using
End Using
connection.Open()
command.ExecuteNonQuery()
connection.Close()

Related

Uploading Datagridview data to MySQL DB

i created a simple mass upload of data from CSV to datagridview and save all datagridview rows into my MySQL table, the code works perfectly but when i check my database it insert a null values to my table heres my code.
This is my Button for Adding all values from my Datagridview
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim cmd As MySqlCommand
connection.Open()
Dim i As Integer
For i = 0 To DataGridView1.Rows.Count - 2
Dim row As DataGridViewRow = DataGridView1.Rows(i)
cmd = New MySqlCommand("INSERT INTO tbl_handling(tbl_docnumber,tbl_bpref,tbl_cname) values (#docnumber,#bref,#cname)", connection)
cmd.Parameters.Add("#docnumber", MySqlDbType.Int64).Value = DataGridView1.Rows(i).Cells(0).Value.ToString
cmd.Parameters.Add("#bref", MySqlDbType.VarChar).Value = DataGridView1.Rows(i).Cells(1).Value.ToString
cmd.Parameters.Add("#cname", MySqlDbType.VarChar).Value = DataGridView1.Rows(i).Cells(2).Value.ToString
cmd.ExecuteNonQuery()
Next
connection.Close()
connection.Dispose()
MessageBox.Show("Data All Uploaded")
End Sub
This is my code on inserting CSV file to my Datagrid view
Private Sub btnUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectData.Click
Dim fName As String = ""
OpenFileDialog1.InitialDirectory = "D:\TestFile"
OpenFileDialog1.Filter = "CSV files(*.csv)|*.csv"
OpenFileDialog1.RestoreDirectory = True
Dim colespected As Integer = 5
Dim sline As String = ""
If (OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK) Then
fName = OpenFileDialog1.FileName
Dim thereader As New StreamReader(fName, Encoding.Default)
Do
sline = thereader.ReadLine
If sline Is Nothing Then Exit Do
Dim words() As String = sline.Split(",")
DataGridView1.Rows.Add("")
For ix As Integer = 0 To 2
DataGridView1.Rows(DataGridView1.Rows.Count - 1).Cells(ix).Value = words(ix)
Next
Loop
thereader.Close()
End If
End Sub
I am assuming that your data is displaying successfully in the grid. So I am only addressing the Button event.
Both commands and connections need to be closed and disposed. Using...End Using blocks do this for you. (BTW Stream objects should be in Using blocks also.) Database objects should be local to the method where they are used. If you .Dispose a connection how do you expect to .Open it later? The command and parameters collection are only created once outside the loop. Just the .Value changes inside the loop.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using connection As New MySqlConnection(ConStr),
cmd As New MySqlCommand("INSERT INTO tbl_handling(tbl_docnumber,tbl_bpref,tbl_cname) values (#docnumber,#bref,#cname)", connection)
cmd.Parameters.Add("#docnumber", MySqlDbType.Int64)
cmd.Parameters.Add("#bref", MySqlDbType.VarChar)
cmd.Parameters.Add("#cname", MySqlDbType.VarChar)
connection.Open()
For i = 0 To DataGridView1.Rows.Count - 2
cmd.Parameters("#docnumber").Value = CLng(DataGridView1.Rows(i).Cells(0).Value)
cmd.Parameters("#bref").Value = DataGridView1.Rows(i).Cells(1).Value.ToString
cmd.Parameters("#cname").Value = DataGridView1.Rows(i).Cells(2).Value.ToString
cmd.ExecuteNonQuery()
Next
End Using
MessageBox.Show("Data All Uploaded")
End Sub
I am a bit worried that tbl_docnumber is an auto-number (identity) primary key in the database. If this is so, then this field should be omitted from the Insert.
This operation would be easier if you filled a DataTable instead of a DataGridView. You could then use a DataAdapter to update the database.

How to fix an empty .csv file export from vb.net using MySQL?

im trying to export a data table to a .csv file in vb.net Ive written code that opens a save file dialogue and successfully saves the .csv file but the file is 0 bytes and contains no data. I'm using MySQL database, the database name is "tickedoff" and the table that i want to export is "pet".
If anyone can see a mistake in my code and help me it would be greatly appreciated.. I am totally stumped at the moment.
This code is in Form1 (button click event):
Private Sub btnPetInfoExport_Click(sender As Object, e As EventArgs) Handles btnPetInfoExport.Click
Dim saveFileDialog1 = New SaveFileDialog()
Dim statement As String = "SELECT pet.petID, pet.petName, pet.species, pet.breed, " _
& "pet.DOB, pet.gender, pet.weight," _
& "CONCAT(customer.lastName, ', ', customer.firstName) AS Customer " _
& "FROM pet INNER JOIN customer ON pet.customerID = customer.customerID " _
& "ORDER BY pet.petID"
Dim petDataTable As DataTable =
DataAccessLayer.GetPetDataTableForExport(statement)
Dim saveFile As StreamWriter
Dim fileName As String = String.Empty
Dim csvBuilder As New StringBuilder()
For i = 0 To petDataTable.Columns.Count - 1
csvBuilder.Append(petDataTable.Columns(i).ColumnName + ","c)
Next
csvBuilder.Append(vbCr & vbLf)
For i = 0 To petDataTable.Rows.Count - 1
For o = 0 To petDataTable.Columns.Count - 1
csvBuilder.Append(petDataTable.Rows(i)(o).ToString().Replace(",", ";") + ","c)
Next
csvBuilder.Append(vbCr & vbLf)
Next
saveFileDialog1.Filter = "CSV files ( .csv)|.csv|ALL files (.)|. "
If saveFileDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK Then
fileName = saveFileDialog1.FileName
Try
saveFile = File.CreateText(fileName)
Catch ex As Exception
Throw ex
End Try
End If
End Sub
This function is called from the above sub and is in a separate class called "data access layer":
Public Shared Function GetPetDataTableForExport(statement As String) As
DataTable
Dim petDataTableCommand As New MySqlCommand(statement)
Dim petDataTable As New DataTable()
Dim connection As New MySqlConnection("server=localhost; Port=3306; database=tickedoff; username=root;")
Dim petDataTableAdapter As MySqlDataAdapter = New MySqlDataAdapter
petDataTableCommand.CommandType = CommandType.Text
petDataTableCommand.Connection = connection
Try
connection.Open()
petDataTableAdapter.SelectCommand = petDataTableCommand
'fill the table with the pet data from the database
petDataTableAdapter.Fill(petDataTable)
Catch ex As Exception
Throw ex
Finally
connection.Close()
petDataTableAdapter.Dispose()
connection.Dispose()
End Try
Return petDataTable
End Function

Unable to cast object of type 'System.DBNull' to type 'System.Byte[]'.

when i try to select an item in the ListView that has no image in my database this error shows Unable to cast object of type 'System.DBNull' to type 'System.Byte[]'. i tried to put up some code like isDBNull or DBNull but it's applicable.
here's my code:
Private Sub LvPeople_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LvPeople.SelectedIndexChanged
If LvPeople.SelectedItems.Count > 0 Then
Dim connstring As String = "server = localhost; user id = root; database = db; password = root"
Dim Sql As String = "select * from candidate where idn='" & LvPeople.SelectedItems(0).Text & "'"
Dim conn As New MySqlConnection(connstring)
Dim cmd As New MySqlCommand(Sql, conn)
Dim dr As MySqlDataReader = Nothing
conn.Open()
dr = cmd.ExecuteReader()
dr.Read()
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
conn.Close()
End If
End Sub
End Class
the error points here:
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
i really have no idea what to put here. just a newbie here.
Since it is possible that there is no image data previously saved for a row, you need to test for DBNull before trying to use it:
If IsDBNull(dr("photo")) = False Then
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
Else
' maybe display a "no Photo Available" stock image
End If
Note that this DBNull test is different than the one Steve is using. IsDBNull is a language function while the one he is using is a method of the DataReader object, which is also why there are different requirements. Yet a third way would be to compare it to System.DbNull:
If DBNull.Value.Equals(dr("photo")) = False Then
...
End If
Use the DataReader method IsDBNull, but this method requires the position of the field in the IDataRecord used by the reader, so you need to call also GetOrdinal with the name of the field to check
(Links point to the Sql Server version but they are the same for MySql)
Private Sub LvPeople_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LvPeople.SelectedIndexChanged
If LvPeople.SelectedItems.Count > 0 Then
Dim connstring As String = "...."
Dim Sql As String = "select * from candidate where idn=#id"
Using conn = new MySqlConnection(connstring)
Using cmd = new MySqlCommand(Sql, conn)
conn.Open()
cmd.Parameters.AddWithValue("#id", LvPeople.SelectedItems(0).Text)
Using dr = cmd.ExecuteReader()
if dr.Read() Then
if Not dr.IsDbNull(dr.GetOrdinal("photo")) Then
Dim imagebytes As Byte() = CType(dr("photo"), Byte())
Using ms As New IO.MemoryStream(imagebytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
End If
End If
End Using
End Using
End Using
End If
End Sub

Why following update query always update null value?

I am trying to update a blob field based on id, with the following code but it always insert Null.
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
openconnection()
Dim cmd As New Odbc.OdbcCommand("UPDATE blob_table SET image=#PictureBox1 WHERE id='6'", myconnection)
Dim fs As New System.IO.FileStream("E:\Untitled.png", IO.FileMode.Open, IO.FileAccess.Read)
Dim b(fs.Length() - 1) As Byte
fs.Read(b, 0, b.Length)
fs.Close()
Dim P As Odbc.OdbcParameter = New Odbc.OdbcParameter("#PictureBox1", Odbc.OdbcType.Image, b.Length, ParameterDirection.Input, True, 0, 0, Nothing, DataRowVersion.Current, b)
cmd.Parameters.Add(P)
openconnection()
cmd.ExecuteNonQuery()
closeconnection()
End Sub
I check the connection, it is properly working,
The image path is a valid path. anyone can help me to find the mistake in the query?
I think you need to set the value of #PictureBox1 to a byte array - e.g. byte[] as I understand that's what the image blob type maps to instead of byte.
Try using a BinaryReader to populate your b byte array:
something like:
Dim b As Byte()
Dim br As New BinaryReader(fs)
b = br.ReadBytes(CInt(fs.Length))
br.Close()
fs.Close()
you have to do something like this to insert image to DB
Using pgFileStream As FileStream = New FileStream(productImageFilePath, FileMode.Open, FileAccess.Read)
Using pgReader As BinaryReader = New BinaryReader(New BufferedStream(pgFileStream))
Dim pgByteA As Byte() = pgReader.ReadBytes(CInt(pgFileStream.Length))
command.CommandText = " update gtab82 set memphoto=#Image where memuuid ='" & txtmemuid.Text & "' "
command.Parameters.AddWithValue("#Image", pgByteA)
command.ExecuteNonQuery()
End Using
End Using
am using PostgreSQL databse and my image field is bytea

updating fields in microsoft access 2000 thru visual basic

i created a program that add and returns equipment, my problem is, its because my borrowing table and my return equipments table are in one table only..representing these fields
"productnumber"
"productname"
"dateborrowed"
"datereturned"
"borrowername"
"status"
what i want to do here is when a user returns an equipment, entering the same data on the fields would make errors on my database..especially on my productnumber because that is my primary key, so i decided to have a data grid in my return equipment form, so if a user return an equipment, all i will do is to update the datereturned field in my database..guys? can you help me with the codes?
As you have not indicated what it you specifically you need help with, I'll start by giving you the simple query to perform the update then I am going on to show you how to interact with Access.
The query to update datereturned:
str = "UPDATE 'Your Table Name' SET datereturned = " & now ' This is your update query.
First thing to do is create a connection the the Access Database:
Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0; Ole DB Services=-4; Data Source=D:\Tecnical Stu"& _
"dy\Complete_Code\Ch08\data\NorthWind.mdb"
Dim dbConnection As System.Data.IDbConnection = New System.Data.OleDb.OleDbConnection(connectionString )
Found at:
http://p2p.wrox.com/ado-net/28703-how-vbulletin-net-connect-access-database.html
Next you should perform the update:
dbConnection .Open()
str = "UPDATE 'Your Table Name' SET datereturned = " & now ' This is your update query.
'string stores the command and CInt is used to convert number to string
cmd = New OleDbCommand(str, cn)
icount = cmd.ExecuteNonQuery
Here is a class that will allow you to perform the interactions, easily and simply.
Imports System.Data.OleDb
Public Class Form1 Inherits System.Windows.Forms.Form
Dim cn As OleDbConnection
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e as _
System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As_
System.EventArgs) Handles Button1.Click
Try
cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;_
Data Source=C:\emp.mdb;")
'provider to be used when working with access database
cn.Open()
cmd = New OleDbCommand("select * from table1", cn)
dr = cmd.ExecuteReader
While dr.Read()
TextBox1.Text = dr(0)
TextBox2.Text = dr(1)
TextBox3.Text = dr(2)
' loading data into TextBoxes by column index
End While
Catch
End Try
dr.Close()
cn.Close()
End Sub
End Class
When you run the code and click the Button, records from Table1 of the Emp database will be displayed in the TextBoxes.
Retrieving records with a Console Application
Imports System.Data.OleDb
Imports System.Console
Module Module1
Dim cn As OleDbConnection
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
Sub Main()
Try
cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\emp.mdb;_
Persist Security Info=False")
cn.Open()
cmd = New OleDbCommand("select * from table1", cn)
dr = cmd.ExecuteReader
While dr.Read()
WriteLine(dr(0))
WriteLine(dr(1))
WriteLine(dr(2))
'writing to console
End While
Catch
End Try
dr.Close()
cn.Close()
End Sub
End Module
Code for Inserting a Record
Imports System.Data.OleDb
Public Class Form2 Inherits System.Windows.Forms.Form
Dim cn As OleDbConnection
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
Dim icount As Integer
Dim str As String
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As_
System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As_
System.EventArgs) Handles Button2.Click
Try
cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\emp.mdb;")
cn.Open()
str = "insert into table1 values(" & CInt(TextBox1.Text) & ",'" & TextBox2.Text & "','" &_
TextBox3.Text & "')"
'string stores the command and CInt is used to convert number to string
cmd = New OleDbCommand(str, cn)
icount = cmd.ExecuteNonQuery
MessageBox.Show(icount)
'displays number of records inserted
Catch
End Try
cn.Close()
End Sub
End Class
Found at:
http://www.startvbdotnet.com/ado/msaccess.aspx
You need to split the product and borrow/return data into two tables:
product:
"productnumber"
"productname"
borrowed:
borrowedID (use a simple autonumber)
productnumber (foreign key linked to productnumber in the product table)
"dateborrowed"
"datereturned"
"status"
borrowerID (foreign key linked to borrower table)
a third table for borrowers/customers would also be in order
borrowers:
borrowerID
"borrowername"