How to insert images into SQL Server database table - sql-server

I have created a new SQL Server local database with a table called drink.
I use Microsoft Visual Studio 2008.
Inside the table I defined the following columns:
id [int], kind [varchar], year [datatime], image [image]
I would like to insert images into the image column but I don't know how to do.
I need this column, because I want to display all data in DataGridView using VB.NET
Thanks for help!

Using openrowset you can insert image into database:
insert into tableName (id,kind,ImageColumn)
SELECT 1,'JPEG',BulkColumn
FROM Openrowset( Bulk '<Path of the image>', Single_Blob) as img

This worked for me...
Imports System.Data.Sql
Imports System.IO
Imports System.drawing
Module Module1
Private Const _ConnectString As String = "your connection string here"
Sub Main()
Dim MyImage As Image = Image.FromFile("RandomImage.jpg")
Dim Id As Long = 1
SaveDrinkImage(MyImage, Id)
End Sub
Sub SaveDrinkImage(MyImage As Image, Id As Long)
Dim ImageBytes(0) As Byte
Using mStream As New MemoryStream()
MyImage.Save(mStream, MyImage.RawFormat)
ImageBytes = mStream.ToArray()
End Using
Dim adoConnect = New SqlClient.SqlConnection(_ConnectString)
Dim adoCommand = New SqlClient.SqlCommand("UPDATE [drink] SET [image]=#MyNewImage WHERE [id]=#id", adoConnect)
With adoCommand.Parameters.Add("#MyNewImage", SqlDbType.Image)
.Value = ImageBytes
.Size = ImageBytes.Length
End With
With adoCommand.Parameters.Add("#id", SqlDbType.BigInt)
.Value = Id
End With
adoConnect.Open()
adoCommand.ExecuteNonQuery()
adoConnect.close()
End Sub
End Module

There are two approaches. You can store the image as a blob in the database or you can store the path (string) to the image file. There is an answer that discusses this: Storing images in SQL Server?

Try this:
Sub SaveDrinkToDB(name As String, imageFilePath As String)
Using cn = New SqlConnection("connection string here")
cn.Open()
Using cmd = New SqlCommand("INSERT INTO Drink (Name, Image) Values(#Name,#Image)", cn)
cmd.Parameters.AddWithValue("#name", name)
cmd.Parameters.AddWithValue("#Image", File.ReadAllBytes(imageFilePath))
cmd.ExecuteNonQuery()
End Using
End Using
End Sub
Usage:
SaveDrinkToDB("Milk", "c:\drink.png")

USE [database_name]
GO
INSERT INTO [schema].[tablename]([property1],[property2],[Property3],[Image])
VALUES
('value','value','value','C:\pathname.jpg')
GO

Related

SQL Server database population pre-existing Data Table and fields (FORM). NO database file

Here is my general understanding of database from what I read so far: Save / Update / Delete to pre-existing file made that binds to form thru SQL.
Here is what I am trying to do - I have a pre-made Data Table in Form with all columns defined. Once app is closed or certain functions ran, I need that data to be saved / updated in SQL (on local). Once app is open I need all that data to be preserved.
So far I have NOT found a single solution to it anywhere most refer to binding to an existing file. When I worked with Excel data transfer cells had to be defined and referenced in form for population.
My assumption is when a database from VB.NET is used, table with values can be created automatically saved/loaded/updated. However this is only my assumption since I never worked with SQL before. I am not sure if I need to manage an actual database file I created with all the values and then bind them to data table. For example DataTable cell XX to database column XX.
Here is what I done so far I have created database and added to my project. I tried few codes and I keep getting Dataset Empty even though there is Data in Table I tried to use DataTable as well but so far nothing has worked.
Please suggest on what I am doing wrong also additional information regards to databases will be great. As per previous I do know how binding works when actual file exist. But creating and managing is confusing to me since I keep thinking there should be a binding file.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "SELECT BN FROM DataTable" ' BN is my column name and DataTable is the name of my Table where data gets populated. This is also confusing to me How does it know which value is what? Is there are space/word/characters requirements?
' adapter.TableMappings.Add("DataTable", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds)
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
Code I use to Create /Save Database. As per previous all columns/formats are pre-made, loaded.
Dim connetionString As String
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
sql = "Select BN FROM DataTable"
adapter.TableMappings.Add("BN", sql)
If DataTable.RowCount > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf DataTable.RowCount = 0 Then
MsgBox("Empty data")
End If
End Sub
Please see more info below:
Data Table columns/format are structured for visual representation.
When User start the App Database can be empty/Can contain Values.
When users Runs certain function Closes App values are save and only values.
If I would you an MS Access I would structure same table/values and cross reference it with form values. Form Values come from outside source and Format/Qty is always known.
Hope this helps to have a cleaner look at my issue. Perhaps SQL is not a right choice for me? Does SQL needs to be build before value manipulation.
UPDATE: I Got rid of the Invalid Object error. Table had to be created 1st as I originally thought. However, My DataSet always comes up as EMPTY when I try to save... Cells do contain BN data as" 1,2, ....) Even if I to remove "If" logic Save and Load table comes out as empty. Something does load because when I try to ADD BN it tells me binding bla bla bla(different issue)
CODE:
Private Sub SaveData()
Dim connetionString As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Dim sql As String = "SELECT BN FROM DataTable_d"
Dim sqlCnn As SqlConnection
Dim sqlCmd As SqlCommand
Dim adapter As New SqlDataAdapter
Dim ds As New DataSet()
adapter.TableMappings.Add("BN", sql)
If ds.Tables.Count > 0 Then
sqlCnn = New SqlConnection(connetionString)
Try
sqlCnn.Open()
sqlCmd = New SqlCommand(sql, sqlCnn)
adapter.SelectCommand = sqlCmd
adapter.Update(ds, "BN")
adapter.Dispose()
sqlCmd.Dispose()
sqlCnn.Close()
Catch ex As Exception
MsgBox("Can not open connection !" & vbCrLf & Err.Description)
End Try
ElseIf ds.Tables.Count = 0 Then
MsgBox("Empty data")
End If
End Sub
UPDATE: I got all the things working but I can't save multiple rows..... Could really use some help
In your SQL query remove WHERE DataTable ='. This statement is looking for a column name DataTable which I assume does not exist. The WHERE clause is used to help filter your query. You only use WHERE on column names in your table.
For instance:
SELECT BN FROM DataTable
will return all values from the BN column from DataTable.
Note that if you have multiple columns, the above query will still only return values from BN.
SELECT * FROM DataTable
will return every value in DataTable.
A helpful site to look at documentation for SQL is w3schools.
Let's start with just displaying some data. Add a DataGridView to a Form. You can call LoadData() from a button. I am not very sure of you connection string but give it a try.
Private dt As DataTable
Private sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Private Sub LoadData()
'***EDIT*** Add instantiation line
dt = New DataTable()
'The Using...End Using blocks will close and dispose your database objects
'even if there is an error
Using cn As New SqlConnection(sql)
'You can pass the command text and the connection directly to the constructor
'In the select statement use the actual names of the field and table as they appear in the database.
Using cmd As New SqlCommand("Select BN From [Insert the name of the table in the database]", cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dt
End Sub
This is the simplest way I can think of to display data. We will proceed with changing the data once this works. If you get an error on cn.Open() We will have to work on the connection string.
****EDIT****
Private Sub TestConnection()
Dim sql As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Data_Ant.mdf;Integrated Security=True;Connect Timeout=30"
Using cn As New SqlConnection(sql)
cn.Open()
End Using
End Sub

Import data from Excel to SQL Server using vb.net

I am importing data from Excel into a SQL Server database using vb.net. In my Excel file, in column bNumber, there are values of different types i.e some are numbers and some are text:
Telenorx
Telenorx
8
97150219924
97150219924
97150219924
97150219924
Easypayx
92
When I select the data from Excel through OleDbCommand, it retrieves numbers correctly but text values as blank.
In Excel, the column's data type is General.
This is my code to retrieve data from Excel.
excelConn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data
Source= " + OpenFileDialog1.FileName + ";Extended Properties=""Excel 12.0
Xml;HDR=Yes""")
Dim oleDbCommand As OleDbCommand = New OleDbCommand("Select bNumber from
[Sheet1$]", excelConn)
excelConn.open()
Dim dataReader = oleDbCommand.ExecuteReader
dataReader.read()
This is not necessarily a solution for your case yet would I did was created a SQL-Server table with bNumber as nvarchar, used SQL-Server Management Studio to export to Excel where I placed the Excel file in the bin\Debug folder of the project. Using the code below all rows returned properly (as we have a string column strings are returned).
The key here is using IMEX=1 in the connection string, Excel can be finicky, this may or may not resolve the issue.
Imports System.Data.OleDb
Public Class Operations
Public Function GetData(ByVal FileName As String) As List(Of String)
Dim valueList As New List(Of String)
Using cn As New OleDbConnection With
{
.ConnectionString = ConnectionString(FileName)
}
Using cmd As OleDbCommand = New OleDbCommand("SELECT bNumber FROM [Table_1$]", cn)
cn.Open()
Dim reader As OleDbDataReader = cmd.ExecuteReader
While reader.Read
valueList.Add(reader.GetString(0))
End While
End Using
End Using
Return valueList
End Function
Public Function ConnectionString(ByVal FileName As String) As String
Dim Builder As New OleDbConnectionStringBuilder
If IO.Path.GetExtension(FileName).ToUpper = ".XLS" Then
Builder.Provider = "Microsoft.Jet.OLEDB.4.0"
Builder.Add("Extended Properties", "Excel 8.0;IMEX=1;HDR=Yes;")
Else
Builder.Provider = "Microsoft.ACE.OLEDB.12.0"
Builder.Add("Extended Properties", "Excel 12.0;IMEX=1;HDR=Yes;")
End If
Builder.DataSource = FileName
Return Builder.ConnectionString
End Function
End Class
Form code
Private Sub Button3_Click(sender As Object, e As EventArgs) _
Handles Button3.Click
Dim ops As New Operations
Dim fileName As String = IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory, "Downloaded.xlsx")
Dim valueList As List(Of String) = ops.GetData(fileName)
For Each value As String In valueList
Console.WriteLine(value)
Next
End Sub
Results in the IDE Output window
Table structure
Worksheet
EDIT: The following link points to a MSDN code sample for working with SpreadSheetLight library. Once downloaded, set startup form to StackOverFlow1QuestionMixedTypesForm. Right click on the solution in solution explorer and select "Restore NuGet Packages", now build and run the project. There are two buttons on the form, first does mixed types for Sheet1 while button two is a variant of the same data laid out differently in Sheet2.
Code sample https://code.msdn.microsoft.com/Alternate-methods-to-work-4c52c4a2

How can I use a query written in TSQL in sql server as data source for my dataGridView?

I need a calculated column and to do achieve this I plan on using a query in TSQL from sql server 2014 the problem is I don't know how to use that query as data source for my dataGridView in vb.net. I'm using visual studio 2015. Can someone help point me in the right direction? I just need to display the results of my query in dataGridView. The calculated column will need data from multiple tables and the only way I can create the column is by using a TSQL query in SQL Server.
You cannot bind sql query to DataGridView.DataSource.
But you can with result of your query, for example you can get result as DataTable
Public Function GetData() As DataTable
Dim yourQuery As String = "...."
Using connection As New SqlConnection(yourConnectionString)
Using command As New SqlCommand(query, connection)
' Add parameters if you need
'command.Parameters.AddRange(arrayOfSqlParameters)
connection.Open()
Using adapter As New SqlDataAdapter(command)
Dim data As New DataTable()
adapter.Fill(data)
Return data
End Using
End Using
End Using
End Function
Then use result as DataSource
Dim data As DataTable = GetData()
myDataGridView.DataSource = data
If you don't like DataTable you can load data to the list of your classes which represent data and use it as datasource
Dim data As List<Customer> = GetCustomerData()
myDataGridView.DataSource = data
You need to create a stored procedure for your T-SQL code. And call the same stored procedure from VB.Net
Here is a good example explained for the same.
Using SQL Stored Procedures with VB.NET
Here's a variation of GetData() above. This one uses a DataReader instead which requires less overhead. There's some extra bells and whistles in there which aren't really needed - you really only need rdr = cmd.ExecuteReader()
Function GetDataTable(ByVal SQL As String, Optional ByVal ConnectString As String = "", Optional ByVal SingleRow As Boolean = False) As DataTable ' returns read only Datatable
Try
If ConnectString.Length = 0 Then ConnectString = g.OISConnectString()
Using con As New System.Data.SqlClient.SqlConnection(ConnectString)
Dim rdr As Data.SqlClient.SqlDataReader
con.Open()
Dim cmd As New SqlCommand(SQL, con)
If SingleRow Then
rdr = cmd.ExecuteReader(CommandBehavior.SingleRow Or CommandBehavior.CloseConnection)
Else
rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
End If
Dim dt As New DataTable
dt.Load(rdr)
rdr.Close()
Return dt
End Using
Catch ex As Exception
MsgBox(ex.Message, , "GetDataTable")
Return Nothing
End Try
End Function

Writing to MS-Access Database Issue using VB.NET

I'm utilizing VB.Net to try and write to a database I created (the machine that needs to be writing to the database is the owner of the database, so there should be no permission issues). I'm getting no errors on when my subs for writing to the database are run, but no new records are created in my database. I'm successfully connected to the database, as my subs for returning records work perfectly.
The Sub for writing to the database:
Public Sub LogThisCard(a As Object)
Dim con As New OleDb.OleDbConnection
Dim da As New OleDb.OleDbDataAdapter
Dim sql As New OleDb.OleDbCommand
Dim inMachine As String = "Yes"
con.ConnectionString = Connection()
con.Open()
Try
sql.Connection = con
sql.CommandText = "INSERT INTO LogTable (MSA, Foo, Bar, Jack, Rabbit, Date_/_Time, Foxtrot) VALUES (#MSA, #Foo, #Bar, #Jack, #Rabbit, #DT, #Foxtrot)"
sql.Parameters.AddWithValue("MSA", a.MSA)
sql.Parameters.AddWithValue("Foo", a.Foo)
sql.Parameters.AddWithValue("Bar", a.Bar)
sql.Parameters.AddWithValue("Jack", a.Jack)
sql.Parameters.AddWithValue("Rabbit", a.Rabbit)
sql.Parameters.AddWithValue("DT", DateTime.Now())
sql.Parameters.AddWithValue("Foxtrot", a.FoxTrot)
da.InsertCommand = sql
da.InsertCommand.ExecuteNonQuery()
Catch ex As Exception
Debug.Print(ex.ToString)
End Try
con.Close()
End Sub
The Database Design is as follows:
ID: AutoNumber (Primary Key)
MSA: Number
Foo: Number
Bar: Short Text
Jack: Short Text
Rabbit: Short Text
Date / Time:Date/Time
Foxtrot: Short Text
It could be an issue with Access and your DateTime Parameter. If DateTime allows null values, change your insert to do all except DateTime. If the Insert works then you know the issue.
I am not sure why access has issue with addwithvalue, but I see it often. I have found it better to declare a variable of parameter and set properties then add the param when it comes to date times.
Example:
Dim cmd As OleDb.OleDbCommand
Dim param As New OleDb.OleDbParameter
param.Direction = ParameterDirection.Input
param.DbType = DbType.Date
param.Value = Date.Now
cmd.Parameters.Add(param)

write result of for xml raw query to file vb.net

I have a for xml raw select query that returns a xml string in server2005 and i would like to write that string to a file using vb.net.
I found that if you fill a dataset with the result of the sql the first cell is the restult.
How slow was i?!
----------Code Below-------
Dim connection As SqlConnection
Dim adapter As SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
Dim stringxml As String
Dim SqlCon1 As String = "Data Source=SQLSERVER;Initial Catalog=DATABASE;Integrated Security=SSPI;"
connection = New SqlConnection(SqlCon1)
sql = "select * from tblProduct for xml auto"
Try
connection.Open()
adapter = New SqlDataAdapter(sql, SqlCon1)
adapter.Fill(ds)
connection.Close()
stringxml = ds.Tables(0).Rows(0).Item(0)
Using writer As StreamWriter = New StreamWriter("c:\testings\picktoday.xml")
writer.Write(stringxml)
End Using
MsgBox("Done")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Using strmWrite as System.IO.StreamWriter(filePath)
strmWrite.WriteLine(xmlString)
End Using
Obviously, just fill in the filePath variable with the directory and name of your file. The xmlString variable will be your XML.
I just want to add to the accepted answer when we have a long output we can get data in multiple rows so we can use the following code
dim xmloutput as string
For Each item As DataRow In ds.Tables(0).Rows
xmloutput += item.Item(0)
Next

Resources