Trouble in converting an image from database to byte and back to image - vb.net

I have a button and a datagridview in my form. I need to get the image from the database and display its value in the datagrid then get the value of the image in the datagrid to copy it to another database.
Specifically, I'm copying the image (blob) from table1 of database1 to table 1 of database2.
Button1_click:
Dim img As Image
Dim bArr As Byte()
Try
Dim Sql = "Select ID, IMG from sample"
connectionOnline()
Dim cmd = New MySqlCommand(Sql, ConOnline)
Dim dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
DataGridView1.Rows.Clear()
While dr.Read = True
img = dr(1)
bArr = imgToByteArray(img)
DataGridView1.Rows.Add(dr(0), bArr)
End While
ConOnline.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try
connectionSync()
Dim a, b As String
Dim Sql = "INSERT INTO SAMPLE (ID, IMG)values(#a,#b)"
For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1
a = Me.DataGridView1.Rows(i).Cells(0).Value.ToString()
Dim img1 As Image = byteArrayToImage(bArr)
Dim cmd As New MySqlCommand(Sql, ConSync)
cmd.Parameters.AddWithValue("#a", a)
cmd.Parameters.AddWithValue("#b", img1)
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
Next
ConSync.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try
connectionSync()
Dim Sql = "INSERT INTO B.SAMPLE(ID, IMG) SELECT ID, IMG FROM C.SAMPLE WHERE not exists (SELECT 1 from B.SAMPLE WHERE B.SAMPLE.ID=C.SAMPLE.ID)"
Dim cmd = New MySqlCommand(Sql, ConSync)
With cmd
.ExecuteNonQuery()
End With
MsgBox("Success", vbInformation, "Save")
ConSync.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try
connectionOffline()
Dim Sql = "UPDATE SAMPLE SET IMG=(SELECT C.SAMPLE.NAME FROM C.SAMPLE WHERE C.SAMPLE.ID=B.SAMPLE.ID) WHERE B.SAMPLE.ID=(SELECT C.SAMPLE.ID FROM C.SAMPLE WHERE C.SAMPLE.ID=B.SAMPLE.ID)"
Dim cmd = New MySqlCommand(Sql, ConOffline)
With cmd
.ExecuteNonQuery()
End With
MsgBox("Success")
ConOffline.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
B and C are databases
While sample is the table
below are the functions i used to convert the image
Public Function imgToByteArray(ByVal img As Image) As Byte()
Using mStream As New MemoryStream()
img.Save(mStream, img.RawFormat)
Return mStream.ToArray()
End Using
End Function
Public Function byteArrayToImage(ByVal byteArrayIn As Byte()) As Image
Using mStream As New MemoryStream(byteArrayIn)
Return Image.FromStream(mStream)
End Using
End Function
The result (in the database; IMG) only shows: "System.Drawing.Bitmap" instead of the actual image

You are storing only a "Image.ToString".
Try to use a Binary parameter:
Dim yourParam As new SqlParameter("#b", System.Data.SqlDbType.Binary)
yourParam.Direction = ParameterDirection.Input
' yourParam.value= yourImage ' you can't place a system.drawin.image here
Dim ms As New MemoryStream()
yourImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
yourParam.value= ms.ToArray() ' similar to your imgToByteArray function ....
cmd.Parameters.Add(yourParam)

Related

Opening a CSV file as a OLEDB Connection converts file text to double

I'm opening up a couple of CSV files and reading them in as a DataTable per the example I found here. The issue I am running into it the basic query I'm using to import the data is converting the column of IP addresses into Doubles. So I want to read in 10.0.0.1 and it shows up as 10.001. How can I get this column to read in as a string? I would like to not double process the file if I can.
Query I'm using is basic and is as follows:
SELECT * FROM [ComputerList.csv]
Here is my function to open and read the CSV file into a DataTable
Public Function OpenFile(ByVal strFolderPath as String, ByVal strQuery as String) as DataTable
Dim strConn as String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFolderPath & ";Extended Propteries=""text; HDR=Yes;FMT=Delimited"""
Dim conn as OleDb.OleDbConnection = New OleDb.OleDbConnection(strConn)
Try
conn.Open()
Dim cmd as OleDb.OleDbCommand = New OleDb.OleDbCommand(strQuery, conn)
Dim da as OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter()
da.SelectCommand = cmd
Dim ds as DataSet = New DataSet()
da.Fill(ds)
da.Dispose()
return ds.Tables(0)
Catch
return Nothing
Finally
conn.Close()
End Try
End Function
i use this to read csv's and force all to string.
Public Function convert_csv_to_data_table(ByVal File As String, ByVal separator As String) As DataTable
Dim dt As New DataTable
Dim firstLine As Boolean = True
If IO.File.Exists(File) Then
Using sr As New StreamReader(File)
While Not sr.EndOfStream
If firstLine Then
firstLine = False
Dim cols = sr.ReadLine.Split(separator)
For Each col In cols
dt.Columns.Add(New DataColumn(col, GetType(String)))
Next
Else
Dim data() As String = sr.ReadLine.Split(separator)
dt.Rows.Add(data.ToArray)
End If
End While
End Using
End If
Return dt
End Function
EDIT:- this will only work with a separator btw
ok I tried variations of everyone's suggested and have settled on a hybrid between all of them. My goal was to read in a CSV file manipulate it in a DataTable form and them write it back out. Some of my CSV files had multiple lines with in a cell and some had deliminators within a cell. Below you can find my hybrid solution that utilized TextFieldParser to read in the file and break it up.
Public Function OpenFile(ByVal File as String, NyVal delim as String) as DataTable
Dim dt as New DataTable()
Dim firstline as Boolean = True
Using MyReader as New Microsoft.VisualBasic.FileIO.TextFieldParser(File)
MyReader.TextFieldType = FileIO.FieldType.Delimited
MyReader.SetDelimiters(delim)
Dim currentRow as String()
While Not MyReader.EndOfData
Try
currentRow = MyReader.ReadFields()
If firstline
firstline = false
For Each col in currentRow
dt.Columns.Add(New DataColumn(col.ToString(), System.Type.GetType("System.String")))
Next
Else
dt.Rows.Add(currentRow.ToArray())
End If
Catch ex as Microsoft.VisualBasic.FileIO.MalformedLineException
Console.WriteLIne("Line " + ex.Message + " is not valid and will be skipped")
End Try
End While
End Using
return dt
End Function

oracle bulkcopy from vb.net databale

I am loading the CSV file to vb.net datatable .
then I am using Bulk copy command to write to database.
The problem is if one date cell in the data table is empty, i am receiving
ORA:-01840 input value not long enough for date format.
How to resolve this.
Public Class Form1
Dim cn As New OracleConnection("Data Source =(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = ipaddressofserver)(PORT = portofserver))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = oracleservicename)) ) ; User Id=useridofdb;Password=passwordofdb")
cn.Open()
MsgBox("connection opened")
Dim dt As DataTable = ReadCSV("D:\test.csv")
DataGridView1.DataSource = dt
Try
Dim _bulkCopy As New OracleBulkCopy(cn)
_bulkCopy.DestinationTableName = "TEST_TABLE"
_bulkCopy.BulkCopyTimeout = 10800
_bulkCopy.WriteToServer(dt)
cn.Close()
cn.Dispose()
cn = Nothing
MsgBox("Finished")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Function ReadCSV(ByVal path As String) As System.Data.DataTable
Try
Dim sr As New StreamReader(path)
Dim fullFileStr As String = sr.ReadToEnd()
sr.Close()
sr.Dispose()
Dim lines As String() = fullFileStr.Split(ControlChars.Lf)
Dim recs As New DataTable()
Dim sArr As String() = lines(0).Split(","c)
For Each s As String In sArr
recs.Columns.Add(New DataColumn())
Next
Dim row As DataRow
Dim finalLine As String = ""
For Each line As String In lines
row = recs.NewRow()
finalLine = line.Replace(Convert.ToString(ControlChars.Cr), "")
row.ItemArray = finalLine.Split(","c)
recs.Rows.Add(row)
Next
Return recs
Catch ex As Exception
Throw ex
End Try
End Function
End Class

When I try to pull nvarchar column value that has an emojis stored in it, the data in VB.net it displays as '??'

When I try to pull the emoji value from the database using VB.net the emoji is displayed as '??'
Is there some sort of conversion I need to do in my stored procedure?
Private Function DisplayEmoji(input As String) As String
Dim output As New StringBuilder()
Dim enumerator = StringInfo.GetTextElementEnumerator(input)
While enumerator.MoveNext()
Dim chunk As String = enumerator.GetTextElement()
If Char.IsSurrogatePair(chunk, 0) Then
output.Append("<img src=""" + "https://abs.twimg.com/emoji/v1/72x72/" + Char.ConvertToUtf32(chunk, 0).ToString("x") + ".png"" style=""height:1.5em; width:1.5em;"">")
Else
output.Append(chunk)
End If
End While
Return output.ToString()
End Function
Or insert your image Blob type and read sql.
Dim filePath As String = Server.MapPath("APP_DATA/test.png")
Dim filename As String = Path.GetFileName(filePath)
Dim fs As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read)
Dim br As BinaryReader = New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(Convert.ToInt32(fs.Length))
br.Close()
fs.Close()
Insert to Database yor image
Dim strQuery As String = "insert into tblFiles(Name, ContentType, Data) values (#Name, #ContentType, #Data)"
Dim cmd As SqlCommand = New SqlCommand(strQuery)
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = filename
cmd.Parameters.Add("#ContentType", SqlDbType.VarChar).Value = "image/png"
cmd.Parameters.Add("#Data", SqlDbType.Binary).Value = bytes
InsertUpdateData(cmd)
InsertUpdateData
Public Function InsertUpdateData(ByVal cmd As SqlCommand) As Boolean
Dim strConnString As String = System.Configuration.
ConfigurationManager.ConnectionStrings("conString").ConnectionString
Dim con As New SqlConnection(strConnString)
cmd.CommandType = CommandType.Text
cmd.Connection = con
Try
con.Open()
cmd.ExecuteNonQuery()
Return True
Catch ex As Exception
Response.Write(ex.Message)
Return False
Finally
con.Close()
con.Dispose()
End Try
End Function

Trouble in saving a longblob image to database

I want to get the image from the datagridview then save it to the database. Can anyone help me with this? It will be so much appreciated
Below is my code in saving the image in the database. I don't know why but it doesn't actually save anything.
Try
connectionSync()
Dim a, b As String
Dim Sql = "INSERT INTO SAMPLE (ID, IMG)values(#a,#b)"
For i As Integer = 0 To Me.DataGridView1.Rows.Count - 1
a = Me.DataGridView1.Rows(i).Cells(0).Value.ToString()
Dim cmd As New MySqlCommand(Sql, ConSync)
Dim memorystream1 As New MemoryStream()
Dim filename As String = DataGridView1.Rows(i).Cells(1).Value
Dim bitmaps As New Bitmap(filename)
bitmaps.Save(memorystream1, Imaging.ImageFormat.Jpeg)
Dim pic() As Byte = memorystream1.GetBuffer()
cmd.Parameters.AddWithValue("#a", a)
cmd.Parameters.AddWithValue("#b", bitmaps)
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
Next
ConSync.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try

The process cannot access the file 'file.csv' because it is being used by another process

I have a code which process each file in a folder and send the data in the file to SQL Database and then deletes the file. But often i get this Exception "The process cannot access the file 'file.csv' because it is being used by another process." Please can anyone point me out in the right direction, will really appreciate that.
The code is shown below :
Dim dirinfo As DirectoryInfo
Dim allFiles() As FileInfo
dirinfo = New DirectoryInfo("E:\SQLUPDATE\CAC")
allFiles = dirinfo.GetFiles("*.csv")
If allFiles.Length <> 0 Then
Try
For Each fl As FileInfo In allFiles
'MsgBox(fl.FullName.ToString())
Dim con As SqlConnection = New SqlConnection(SQL_con2)
Dim sr As StreamReader = New StreamReader(fl.FullName)
Dim line As String = sr.ReadLine
Dim value() As String = line.Split(Microsoft.VisualBasic.ChrW(44))
Dim dt As DataTable = New DataTable
Dim row As DataRow
For Each dc As String In value
dt.Columns.Add(New DataColumn(dc))
Next
While Not sr.EndOfStream
value = sr.ReadLine.Split(Microsoft.VisualBasic.ChrW(44))
If (value.Length = dt.Columns.Count) Then
row = dt.NewRow
row.ItemArray = value
dt.Rows.Add(row)
End If
End While
Dim bc As SqlBulkCopy = New SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.TableLock)
bc.DestinationTableName = "[DB].[dbo].[CAC_LData]"
bc.BatchSize = dt.Rows.Count
con.Open()
bc.WriteToServer(dt)
bc.Close()
con.Close()
sr.Close()
System.IO.File.Delete(fl.FullName)
sr.Dispose()
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If