Excel to Sql adding certain rows to sql server - sql

cmd.CommandText = (Convert.ToString("SELECT * From [") & excelSheet) & "] Order By" & columnCompany & "OFFSET 0 ROWS FETCH NEXT 100000 ROWS ONLY "
I am trying to map data form excel to an sql table but the excel table has a lot of records in it, so I run out of memory if I try to add all of the records at once. So what I am trying to do is use this line of code
cmd.CommandText = (Convert.ToString("SELECT * From [") & excelSheet) & "] Order By B OFFSET 0 ROWS FETCH NEXT 100000 ROWS ONLY "
So that 100000 row will be added. Then I intend to clear the data table and do the same only from 100001 to 200000 and so on.
But I cant get this to work correctly, it works fine when it is just SELECT TOP 100000 FROM... but then I dont know how to get the next 100000 record. I think the Order By is where the issue is as I'm not sure how to get the correct column.
Here is my code Below
Private Sub btnMap_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMap.Click
'Allows columns to be moved mapped in the correct order
Dim nbColumnsToTransfer As Integer = dgvMapped.Columns.GetColumnCount(1)
Dim indexes As List(Of Integer) = (From column As DataGridViewColumn In dgvLoadedata.Columns.Cast(Of DataGridViewColumn)() _
Take nbColumnsToTransfer _
Order By column.DisplayIndex _
Select column.Index).ToList()
Dim columnCompany As Integer = indexes(0)
Dim columnEmail As Integer = indexes(1)
Dim columnFirstName As Integer = indexes(2)
Dim columnSurname As Integer = indexes(3)
Dim columnPostCode As Integer = indexes(4)
Dim columnTelephone As Integer = indexes(5)
Dim columnEmployeeBand As Integer = indexes(6)
Dim DeleteConnection As New Data.SqlClient.SqlConnection
DeleteConnection.ConnectionString = "Data Source=DC01\SQLEXPRESS;Initial Catalog=YCM;User ID=sa;Password=S0rtmypc!"
DeleteConnection.Open()
Dim sqlDTM As String = "Delete From TempMapped"
Dim command As New SqlCommand(sqlDTM, DeleteConnection)
command.ExecuteNonQuery()
Dim sqlDTSR As String = "Delete From TempSplitReq"
command = New SqlCommand(sqlDTSR, DeleteConnection)
command.ExecuteNonQuery()
DeleteConnection.Close()
If chkContactSplitReq.Checked = True Then
Dim dt As New DataTable()
Using con As New OleDbConnection(conString)
Using cmd As New OleDbCommand()
Using oda As New OleDbDataAdapter()
cmd.CommandText = (Convert.ToString("SELECT * From [") & excelSheet) & "] Order By" & columnCompany & "OFFSET 0 ROWS FETCH NEXT 100000 ROWS ONLY ""
cmd.Connection = con
con.Open()
oda.SelectCommand = cmd
oda.Fill(dt)
con.Close()
End Using
End Using
End Using
Dim connection As String = "Data Source=DC01\SQLEXPRESS;Initial Catalog=YCM;User ID=sa;Password=S0rtmypc!"
Using cn As New SqlConnection(connection)
cn.Open()
Using copy As New SqlBulkCopy(cn)
copy.ColumnMappings.Add(columnCompany, 0)
copy.ColumnMappings.Add(columnEmail, 1)
copy.ColumnMappings.Add(columnFirstName, 2)
copy.ColumnMappings.Add(columnPostCode, 3)
copy.ColumnMappings.Add(columnTelephone, 4)
copy.DestinationTableName = "TempSplitReq"
copy.WriteToServer(dt)
End Using
End Using
Dim SplitConnection As New Data.SqlClient.SqlConnection
SplitConnection.ConnectionString = "Data Source=DC01\SQLEXPRESS;Initial Catalog=YCM;User ID=sa;Password=S0rtmypc!"
SplitConnection.Open()
Dim sqlSplit As String = "TempSplitReq_SaveToMapped"
Dim commandSplit As New SqlCommand(sqlSplit, SplitConnection)
commandSplit.ExecuteNonQuery()
SplitConnection.Close()
Else
Dim dt As New DataTable()
Using con As New OleDbConnection(conString)
Using cmd As New OleDbCommand()
Using oda As New OleDbDataAdapter()
cmd.CommandText = (Convert.ToString("SELECT * From [") & excelSheet) + "] "
cmd.Connection = con
con.Open()
oda.SelectCommand = cmd
oda.Fill(dt)
con.Close()
End Using
End Using
End Using
Dim connection As String = "Data Source=DC01\SQLEXPRESS;Initial Catalog=YCM;User ID=sa;Password=S0rtmypc!"
Using cn As New SqlConnection(connection)
cn.Open()
Using copy As New SqlBulkCopy(cn)
copy.ColumnMappings.Add(columnCompany, 0)
copy.ColumnMappings.Add(columnEmail, 1)
copy.ColumnMappings.Add(columnFirstName, 2)
copy.ColumnMappings.Add(columnSurname, 3)
copy.ColumnMappings.Add(columnPostCode, 4)
copy.ColumnMappings.Add(columnTelephone, 5)
copy.DestinationTableName = "TempMapped"
copy.WriteToServer(dt)
End Using
End Using
End If
MsgBox("Data Mapping Complete")
End Sub

A SqlBulkCopy object has a BatchSize property. I have a similar situation and set
copy.BatchSize = 1000
And mine works with a large spreadsheet import. Adjust this property in your environment for better performance.

Related

My SQL select query with condition using list in VB.net

I have a MySQL table (variable- exchange) with a column name "symbol" and I have a list of string named "listfinalselection". I want to select all rows where the list contains the cell value of column "symbol". But I got a error that there is an error in my SQL syntax. I can't understand that error. Please help. `
Dim mysqlconn As MySqlConnection
mysqlconn = New MySqlConnection
mysqlconn.ConnectionString = "server=localhost;user id=root;password=1234;database=Share"
mysqlconn.Open()
Dim sql As String = "SELECT * FROM " & exchange & " WHERE Symbol in (" & String.Concat(",", listfinalselection.Select(Function(i) $"'{i}'").ToArray()) & ");"
Dim adapter As New MySqlDataAdapter(sql, mysqlconn)
Dim datatable As New DataTable()
adapter.Fill(datatable)
DataGridView1.DataSource = datatable
DataGridView1.Refresh()
Dim ii As Integer = 0
For Each rw As DataGridViewRow In DataGridView1.Rows
Try
DataGridView1.Rows(ii).Cells(11).Value = listeleventh(listsymbol.IndexOf(DataGridView1.Rows(ii).Cells(3).Value.ToString))
Catch
End Try
ii = ii + 1
Next
End Sub `
Here's how we can properly and securely query MySQL for a list of values:
Dim con = New MySqlConnection("server=localhost;user id=root;password=1234;database=Share")
'NOTE WELL: you still have to make sure that exchange contains no SQL!
Dim cmd As New MySqlCommand("SELECT * FROM " & exchange & " WHERE Symbol in (", con)
For i as Integer = 0 to listfinalselection.Count - 1
cmd.Parameters.AddWithValue("#p" & i, listfinalselection(i))
cmd.CommandText &= "#p" & i & ","
Next i
cmd.CommandText = cmd.CommandText.TrimEnd(","c) & ")"
Dim adapter As New MySqlDataAdapter(cmd)
Dim dt as New DataTable
adapter.Fill(dt)
Please note, before someone quotes the "Can we stop using AddWithValue already" blog, it's irrelevant to mysql

I want to query between two dates in sqlite with two textbox(textbox4.text and textbox5.text = variable) in form

Dim query As String = "select * from mytable where strftime('%Y-%m-%d',tarih) between 'TextBox4.text' and 'TextBox5.text' "
Can not assign query variable ?
Datagridview result = empty
info :Datagridview date format = 2018-01-01 17:42:24
Dim btarihyil As String
btarihyil = DateTimePicker2.Value.ToString.Substring(6, 4)
Dim btarihay As String
btarihay = DateTimePicker2.Value.ToString.Substring(3, 2)
Dim btarihgun As String
btarihgun = DateTimePicker2.Value.ToString.Substring(0, 2)
TextBox4.Text = btarihyil & "-" & btarihay & "-" & btarihgun
Dim bttarihyil As String
bttarihyil = DateTimePicker3.Value.ToString.Substring(6, 4)
Dim bttarihay As String
bttarihay = DateTimePicker3.Value.ToString.Substring(3, 2)
Dim bttarihgun As String
bttarihgun = DateTimePicker3.Value.ToString.Substring(0, 2)
TextBox4.Text = btarihyil & "-" & btarihay & "-" & btarihgun
TextBox5.Text = bttarihyil & "-" & bttarihay & "-" & bttarihgun
Dim Yol As String = "Data Source=database1.s3db;version=3;new=False"
Using MyConn As New SQLiteConnection(Yol)
If (MyConn.State = ConnectionState.Closed) Then
MyConn.Open()
End If
Dim Sorgu As String = "select * from mytable where strftime('%Y-%m-%d',tarih) between 'TextBox4.text' and 'TextBox5.text' "
Using MyCmd As New SQLiteCommand(Sorgu, MyConn)
Dim Da As New SQLiteDataAdapter(MyCmd)
Dim Ds As New DataSet
Dim Dt As New DataTable
Ds.Reset()
Da.Fill(Ds)
Dt = Ds.Tables(0)
Dim Bs As New BindingSource With {.DataSource = Dt}
DataGridView1.DataSource = Bs
Bs.MoveLast()
MyConn.Close()
MyCmd.Dispose()
MyConn.Dispose()
End Using
End Using
End Sub
You are using "TextBox4.Text" and "TextBox5.Text" literally in the query. That will not pass the values of textboxes to the query. So it will result in error.
Also you need to use parameterized query to avoid syntax errors.
Also I am not sure why you are using strftime function. That function is used just for formatting.
Following the code I re-written using parameterzied query approach.
Dim Yol As String = "Data Source=database1.s3db;version=3;new=False"
Using MyConn As New SQLiteConnection(Yol)
If (MyConn.State = ConnectionState.Closed) Then
MyConn.Open()
End If
Dim Sorgu As String = "select * from mytable where tarih between #startDate and #endDate "
Using MyCmd As New SQLiteCommand(Sorgu, MyConn)
Dim startDate as new SQLiteParameter("#startDate")
startDate.Value = DateTimePicker2.Value
Dim endDate as new SQLiteParameter("#endDate")
endDate.Value = DateTimePicker3.Value
MyCmd.Parameters.Add(startDate)
MyCmd.Parameters.Add(endDate)
Dim Da As New SQLiteDataAdapter(MyCmd)
Dim Ds As New DataSet
Dim Dt As New DataTable
Ds.Reset()
Da.Fill(Ds)
Dt = Ds.Tables(0)
Dim Bs As New BindingSource With {.DataSource = Dt}
DataGridView1.DataSource = Bs
Bs.MoveLast()
MyConn.Close()
MyCmd.Dispose()
MyConn.Dispose()
End Using
End Using
This should help you resolve your issue.

vb.net Using SqlConnection doesn't free the file from use

I am working with a local .mdf file and I execute some queries to the database and I am using USING blocks to make sure the SqlConnection and SqlReader are disposed of correctly.
I then try to read the data of the file to generate a MD5 Hash of the file but it says the file is still in use.
The code isn't the cleanest it is my first time working with the Sql in a VB.NET app.
SQL Insert:
Dim finalW As String = ""
Dim finalO() As String
Dim currentcounter As Integer = 0
For Each Dir As String In System.IO.Directory.GetDirectories(Pathfinder)
Dim dirInfo As New System.IO.DirectoryInfo(Dir)
Dim temp As New List(Of String)
For Each currentFile In Directory.GetFiles(Pathfinder & "\" & dirInfo.Name & "\", "*.png", SearchOption.TopDirectoryOnly)
temp.Add(Path.GetFileName(currentFile))
Next
If temp.Count <> 0 Then
finalW = temp.Find(AddressOf GetNewIcon)
finalO = temp.FindAll(AddressOf GetOldIcon).ToArray
If finalW <> "" Then
Using con As New SqlClient.SqlConnection("Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=""" & PathFinal & "ImaginiDB.mdf"";Integrated Security=True")
con.Open()
Using cmd = con.CreateCommand()
cmd.CommandType = CommandType.Text
cmd.CommandText = "INSERT NewIcon (Name) VALUES ('" & finalW.Trim() & "')"
cmd.Connection = con
cmd.ExecuteNonQuery()
End Using
currentcounter = currentcounter + 1
Dim Id As String = ""
Using command = con.CreateCommand()
command.CommandType = CommandType.Text
command.CommandText = "SELECT * FROM NewIcon WHERE Name='" & finalW & "'"
Using reader As SqlDataReader = command.ExecuteReader()
While reader.Read()
Id = reader(0)
End While
End Using
End Using
For Each item As String In finalO
Using cmd2 = con.CreateCommand()
cmd2.CommandType = CommandType.Text
cmd2.CommandText = "INSERT OldIcon (NID,Name) VALUES ('" & Id & "','" & item.ToString.Trim() & "')"
cmd2.Connection = con
cmd2.ExecuteNonQuery()
End Using
currentcounter = currentcounter + 1
Next
Dim cur As Long = currentcounter * 100 / counter
SetProgress(cur)
End Using
End If
End If
Next
GC.Collect()
GC.WaitForPendingFinalizers()
SetLabel4Text("FINISHED IMPORT", Color.Red)
MD5 Generation ran after this process is finished:
Public Function GenMD5(ByVal Filename As String) As String
Dim MD5 = System.Security.Cryptography.MD5.Create
Dim Hash As Byte()
Dim sb As New System.Text.StringBuilder
Using st As New IO.FileStream(Filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Hash = MD5.ComputeHash(st)
End Using
For Each b In Hash
sb.Append(b.ToString("X2"))
Next
Return sb.ToString
End Function
So as mentioned in the comment by #jmcilhinney
Different connections use different pool as the MSDN says:
When a connection is first opened, a connection pool is created based
on an exact matching algorithm that associates the pool with the
connection string in the connection.
Thus I decided to implement the method:
SqlConnection.ClearPool(connection As SqlConnection)
I placed this just before my END USING:
Dim cur As Long = currentcounter * 100 / counter
SetProgress(cur)
SqlConnection.ClearPool(con)
End Using

VB.NET update same table inside a DataReader loop

I'm reading from a SQL database and depending on the fields I check I need to update a different field in that same table. I'm looping through the dataset and trying to send an UPDATE back while looping. It worked on my TEST table but isn't working for my production table. When I execute the "ExecuteNonQuery" command, I get a timeout expired error. If I actually close the first connection and then call the ExecuteNonQuery it runs instantly.
Here's the code...
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim sqlConn As New SqlConnection
Dim sqlComm As New SqlCommand
Dim sqlDR As SqlDataReader
sqlConn.ConnectionString = "Data Source=10.2.0.87;Initial Catalog=Inbound_Orders_DB;User ID=xxxxx;Password=xxxxxx;"
sqlConn.Open()
sqlComm.CommandText = "SELECT * FROM RH_Orders where Order_DateTime is NULL ORDER by Order_Date DESC"
sqlComm.Connection = sqlConn
sqlDR = sqlComm.ExecuteReader
If sqlDR.HasRows Then
While sqlDR.Read
If Trim(sqlDR("Order_Date")) <> "" Then
Dim order_Date As String = Trim(sqlDR("Order_Date"))
Dim order_DateTime As String = ""
If Len(order_Date) = 14 Then
order_DateTime = order_Date.Substring(0, 4) & "-" & order_Date.Substring(4, 2) & "-" & order_Date.Substring(6, 2) & " "
order_DateTime = order_DateTime & order_Date.Substring(8, 2) & ":" & order_Date.Substring(10, 2) & ":" & order_Date.Substring(12, 2)
Dim myId As String = sqlDR("ID")
Dim sqlConn2 As New SqlConnection
Dim sqlComm2 As New SqlCommand
sqlConn2.ConnectionString = "Data Source=10.2.0.87;Initial Catalog=Inbound_Orders_DB;User ID=xxxx;Password=xxxx;"
sqlConn2.Open()
sqlComm2.CommandText = "UPDATE [RH_Orders] SET order_DateTime = '" & order_DateTime & "' WHERE ID=" & myId
sqlComm2.Connection = sqlConn2
sqlComm2.ExecuteNonQuery()
sqlConn2.Close()
End If
End If
End While
End If
End Sub
End Class
Use parametrized queries and don't concatenate strings, then use a SqlParameter with SqlDbType.Datetime and assign a real DateTime instead of a formatted string.
But maybe it would be more efficient here to fill a DataTable with SqlDataAdapter.Fill(table), loop the table's Rows, change each DataRow and use SqlDataAdapter.Update(table) to send all changes in one batch after the loop. No need for the SqlDataReader loop.
For example (untested):
Using con = New SqlConnection("Data Source=10.2.0.87;Initial Catalog=Inbound_Orders_DB;User ID=xxxxx;Password=xxxxxx;")
Using da = New SqlDataAdapter("SELECT * FROM RH_Orders where Order_DateTime is NULL ORDER by Order_Date DESC", con)
da.UpdateCommand = New SqlCommand("UPDATE RH_Orders SET order_DateTime = #order_DateTime WHERE ID = #Id", con)
da.UpdateCommand.Parameters.Add("#order_DateTime", SqlDbType.DateTime).SourceColumn = "order_DateTime"
Dim table = New DataTable()
da.Fill(table)
For Each row As DataRow In table.Rows
Dim orderDate = row.Field(Of String)("Order_Date")
Dim orderDateTime As DateTime
If DateTime.TryParse(orderDate.Substring(0, 4) & "-" & orderDate.Substring(4, 2) & "-" & orderDate.Substring(6, 2), orderDateTime) Then
row.SetField("order_DateTime", orderDateTime)
End If
Next
da.Update(table)
End Using
End Using
Side-note: Instead of building a new string "2017-01-31" from "20170131" you could also use DateTime.TryParseExact:
DateTime.TryParseExact("20170131", "yyyyMMdd", nothing, DateTimeStyles.None, orderDateTime)

How to create a query in Visual Studio 2013 using Visual Basic

I have the following code and through debugging the problem begins at the While loop. I am trying to retrieve information from 2 tables and insert it into the table created. The information is not being inserted into the table and I am getting blank rows.
Imports System.Data.OleDb
Public Class RouteToCruise
Private Sub RouteToCruise_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Route_Btn_Click(sender As Object, e As EventArgs) Handles Route_Btn.Click
Dim row As String
Dim connectString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=M:\ICT-Group-Project\DeepBlueProject\DeepBlueProject\DeepBlueTables.mdb"
Dim cn As OleDbConnection = New OleDbConnection(connectString)
cn.Open()
Dim CruiseQuery As String = "SELECT CruiseID, RouteID FROM Cruise WHERE CruiseID =?"
Dim RouteQuery As String = "SELECT RouteName FROM Route WHERE RouteID =?"
Dim cmd As OleDbCommand = New OleDbCommand(CruiseQuery, cn)
Dim cmd2 As OleDbCommand = New OleDbCommand(RouteQuery, cn)
cmd.Parameters.AddWithValue("?", Route_Txt.Text)
Dim reader As OleDbDataReader
reader = cmd.ExecuteReader
'RCTable.Width = Unit.Percentage(90.0)
RCTable.ColumnCount = 2
RCTable.Rows.Add()
RCTable.Columns(0).Name = "CruiseID"
RCTable.Columns(1).Name = "Route"
While reader.Read()
Dim rID As String = reader("RouteID").ToString()
cmd2.Parameters.AddWithValue("?", rID)
Dim reader2 As OleDbDataReader = cmd2.ExecuteReader()
'MsgBox(reader.GetValue(0) & "," & reader.GetValue(1))
row = reader("CruiseID") & "," & reader2("RouteName")
RCTable.Rows.Add(row)
cmd.ExecuteNonQuery()
reader2.Close()
End While
reader.Close()
cn.Close()
End Sub
End Class
If I understand your tables structure well then you could just run a single query extracting data from the two table and joining them in a new table returned by the query
Dim sql = "SELECT c.CruiseID c.CruiseID & ',' & r.RouteName as Route " & _
"FROM Cruise c INNER JOIN Route r ON c.RouteID = c.RouteID " & _
" WHERE c.CruiseID = #cruiseID"
Dim cmd As OleDbCommand = New OleDbCommand(sql, cn)
cmd.Parameters.Add("#cruiseID", OleDbType.Int).Value = Convert.ToInt32(Route_Txt.Text)
Dim RCTable = new DataTable()
Dim reader = cmd.ExecuteReader()
reader.Load(RCTable)
At this point the RCTable is filled with the data coming from the two tables and selected using the Route_Txt textbox converted to an integer. If the CruiseID field is not a numeric field then you should create the parameter as of type OleDbType.VarWChar and remove the conversion to integer
Try simplifying your query.
Dim CruiseRouteQuery As String = "SELECT C.CruiseID, C.RoutID, R.Routename FROM Cruise C LEFT JOIN Route R ON C.RouteID = R.RoutID WHERE CruiseID =?"
Also, please let us know what errors you are getting.