Oledb Connection Hangs VB.Net - vb.net

I am using an OledbConnection to an AS400 computer. When I have a SQL statement that will return nothing, it just hangs on the adapter command Fill.
Function ExecuteOLEDBQuery(ByVal cmdtext As String) As DataTable
Try
Dim connString As String = "Provider=IBMDA400;Persist Security Info=True;User ID=##USERID;Password=##PASSWORD;Data Source=##SYSTEM"
Dim as400 As New OleDb.OleDbConnection(connString)
Dim cmd As New OleDb.OleDbCommand(cmdtext, as400)
Dim adapter As New OleDb.OleDbDataAdapter(cmd)
cmd.CommandTimeout = 60 'Doesn't work. It never times out.
Dim dt As New DataTable
as400.Open()
adapter.Fill(dt) 'This is where it hangs
as400.Close()
adapter.Dispose()
cmd.Dispose()
Return dt
Catch ex As Exception
Return Nothing
End Try
End Function
Any ideas?

It may be the connection to the AS400 itself. Try this version which disposes of the object in a slightly different order:
Function ExecuteOLEDBQuery(cmdtext As String) As DataTable
Using cn = New OleDbConnection("Provider=IBMDA400;Persist Security Info=True;User ID=##USERID;Password=##PASSWORD;Data Source=##SYSTEM")
cn.Open()
Using da = New OleDbDataAdapter(cmdtext, cn)
Dim dt = New DataTable
da.Fill(dt)
Return dt
End Using
End Using
End Function

Related

Trying to convert Excel file into a Datatable and afterwards into a List of objects

I'm trying to convert a Excel-File into a DataTable and then into a List of Objects. My problem is, that the datatable is always empty, here is what i have tried:
First build the connection String
Public Function BuildConnectionString(excelPath As String) As String
If excelPath.Substring(excelPath.LastIndexOf(".")).ToLower = ".xlsx" Then
Return "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & excelPath & ";Excel 12.0;HDR=YES;IMEX=1"
Else
Return "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & excelPath & ";Excel 8.0;HDR=YES;IMEX=1"
End If
End Function
Convert Excel to Datatable (doesn't Work)
Private Function ConvertCSVToDataTable(ByVal path As String) As DataTable
Dim dt As DataTable = New DataTable()
Using con As OleDb.OleDbConnection = New OleDb.OleDbConnection()
Try
con.ConnectionString = String.Format(BuildConnectionString(path))
Using cmd As OleDb.OleDbCommand = New OleDb.OleDbCommand("SELECT * FROM [Sheet1$]", con)
Using da As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(cmd)
con.Open()
da.Fill(dt)
con.Close()
End Using
End Using
Catch ex As Exception
Console.WriteLine(ex.ToString())
Finally
If con IsNot Nothing AndAlso con.State = ConnectionState.Open Then
con.Close()
End If
End Try
End Using
Return dt
End Function
Convert DataTable to List of Objects
Private Function ConvertDataTableToCSVListOfISAACService(dt As DataTable, lst As List(Of ISAACServiceExcel)) As List(Of ISAACServiceExcel)
For Each row As DataRow In dt.Rows
Dim AnzahlParse As Double
Double.TryParse(row(Anzahl), AnzahlParse)
Dim EinzelkostenParse As Double
Double.TryParse(row(Einzelkosten), EinzelkostenParse)
Dim TotalParse As Double
Double.TryParse(row(Total), TotalParse)
Dim ISAAC As New ISAACServiceExcel(row(Leistungscode).ToString, row(KostenArt).ToString, row(UANR).ToString, row(Ueberbegriff).ToString, row(Benennung).ToString, AnzahlParse, row(Einheit).ToString, EinzelkostenParse, row(Summencode).ToString, row(AufPos).ToString, row(Komponente).ToString, row(Projektbeteiligter).ToString, row(Chefblattposition).ToString, TotalParse)
lst.Add(ISAAC)
Next
Return lst
End Function
You can also write code in C#, if thats easier for you. Thank you in advance!
I have a function that does this and is working fine.
Public Function loadExcelData(filename As String) As DataTable
Dim dt As DataTable = New DataTable
Using cn As New OleDbConnection
cn.ConnectionString = connString(filename)
Using cmd As New OleDbCommand
cmd.Connection = cn
cmd.CommandText = "SELECT * FROM [Plan1$]"
cn.Open()
Try
dt.Load(cmd.ExecuteReader)
Catch ex As Exception
MsgBox(ex.Message & vbCrLf & vbCrLf & ex.StackTrace, MsgBoxStyle.Critical)
Return Nothing
End Try
End Using
End Using
Return dt
End Function
But, in my case, I'm importing XLSX and XLS files, for CSV you can probably use something for a plain text, as you can find in this answer.

Why is my VB program throwing an exception complaining that a OleDbDataReader is closed, when it should absolutely be open?

I am trying to use OleDB and SQLBulkCopy to pull data off an excel spreadsheet, into an SQL database. When I try and run my code, I get the following exception, triggered by
"bulkCopy.WriteToServer(objDR)" (which is also described in the question title): exception data
OleDB successfully reads the excel sheet which is then populated properly in the DataGridView I created within a WinForm for debugging purposes.
Below is a snippet of the relevant code.
Dim ExcelConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=\\damon\Everyone\sheet1erictest.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=Yes""")
ExcelConnection.Open()
Dim sheet As String = "Sheet5$"
Dim expr As String = "SELECT * FROM [" + sheet + "]"
Dim objCmdSelect As OleDbCommand = New OleDbCommand(expr, ExcelConnection)
Dim objDR As OleDbDataReader
Dim SQLconn As New SqlConnection()
Dim ConnString As String = "SERVER=SqlDEV;DATABASE=Freight;Integrated Security=True"
SQLconn.ConnectionString = ConnString
SQLconn.Open()
Using bulkCopy As SqlBulkCopy = New SqlBulkCopy(SQLconn)
bulkCopy.DestinationTableName = "dbo.test"
Try
objDR = objCmdSelect.ExecuteReader
Dim dt = New DataTable()
dt.Load(objDR)
DataGridView1.AutoGenerateColumns = True
DataGridView1.DataSource = dt
DataGridView1.Refresh()
bulkCopy.WriteToServer(objDR)
objDR.Close()
SQLconn.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Using
End Sub
Your reader object is being used by the DataTable, so comment out those lines and run them separately later with a new instance:
objDR = objCmdSelect.ExecuteReader
'Dim dt = New DataTable()
'dt.Load(objDR)
'DataGridView1.AutoGenerateColumns = True
'DataGridView1.DataSource = dt
'DataGridView1.Refresh()
bulkCopy.WriteToServer(objDR)

VB.NET - Key word is not supported: provider

When I try to connect to AcessDB, I get the error
"Keyword is not supported: provider".
When I try to change provider, I get another error. When I delete provider tag, I also get an error.
Dim Exists As Boolean = False
Dim ConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Name\Documents\Visual Studio 2010\Projects\datagrid\datagrid\pokus.accdb;Persist Security Info=False;"
Dim connection As New SqlConnection(ConnectionString)
Try
connection.Open()
Dim command As SqlCommand = connection.CreateCommand
command.CommandText = "SELECT * FROM studenti"
Dim reader As SqlDataReader = command.ExecuteReader
If reader.HasRows Then
Exists = True
Else
Exists = False
End If
reader.Close()
command.Dispose()
Catch ex As Exception
Console.Write(ex.Message)
Finally
connection.Close()
End Try
SqlConnection, SqlCommand, etc. are SQL Server-specific classes. You can't use them to connect to MS Access.
The documentation for SqlConnection makes this very clear:
Represents an open connection to a SQL Server database.
Consider using the OldDbConnection and related classes instead.
I always write wrapper classes for database connections, and I always recommend the same.
Dim sConnectionString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Name\Documents\Visual Studio 2010\Projects\datagrid\datagrid\pokus.accdb;Persist Security Info=False;"
Dim Conn As New OleDbConnection
Conn.ConnectionString = sConnectionString
Conn.Open()
Dim sQuery As String = "SELECT * FROM studenti"
Dim da As New OleDbDataAdapter(sQuery, Conn)
Dim dt As New DataTable
da.Fill(dt)
Conn.Close()

how can i use parameters to avoid sql attacks

I have a project without any parameters used in SQL queries.
Is there any solution so that i don't have to change the function and validate parameters from the Query string itself?
Query = "select * from tbl_Users where userName='"& textbox1.text &"' and password='"& textbox2.text &"' "
ds = obj.ExecuteQueryReturnDS(Query)
Function where query is passed:
Public Function ExecuteQueryReturnDS(ByVal stQuery As String) As DataSet
Try
Dim ds As New DataSet
Using sqlCon As New SqlConnection(connStr)
Dim sqlCmd As New SqlCommand(stQuery, sqlCon)
Dim sqlAda As New SqlDataAdapter(sqlCmd)
sqlCmd.CommandType = CommandType.Text
sqlAda.Fill(ds)
End Using
Return ds
Catch ex As Exception
End Try
End Function
I tried passing parameters into the function but the function is used in for other queries as well hence i cannot define the parameters inside the function .
Is there any work around
I think the only solution is create a new function and gradually migrate to it.
Public Function ExecuteQueryReturnDS(ByVal cmdQuery As SqlCommand) As DataSet
Try
Dim ds As New DataSet
Using sqlCon As New SqlConnection(connStr)
cmdQuery.Connection = sqlCon
Dim sqlAda As New SqlDataAdapter(cmdQuery)
sqlAda.Fill(ds)
End Using
Return ds
Catch ex As Exception
End Try
End Function
cmdQuery is intended to be an SqlCommand to which you already added all the parameters you need.
As an intermediate step before switching to a full parameterized application you could change your actual method to be able to receive an optional argument.
This optional argument will be your SqlParameter array defined in the point where you call this query
Public Function ExecuteQueryReturnDS(ByVal stQuery As String, Optional ByVal prms As SqlParameter() = Nothing) As DataSet
Try
Dim ds As New DataSet
Using sqlCon As New SqlConnection(connStr)
Dim sqlCmd As New SqlCommand(stQuery, sqlCon)
if Not prms Is Nothing Then
sqlCmd.Parameters.AddRange(prms)
End if
Dim sqlAda As New SqlDataAdapter(sqlCmd)
sqlCmd.CommandType = CommandType.Text
sqlAda.Fill(ds)
End Using
Return ds
Catch ex As Exception
End Try
End Function

SQLXML Import/Export

I have a SQL DB from which I export data as XML using VB.Net code. The code is relatively simple, works quickly, and formats the XML beautifully. The code is:
Dim connetionString As String
Dim connection As SqlConnection
Dim adapter As SqlDataAdapter
Dim ds As New DataSet
Dim sql As String
connetionString = "**connectionstring**"
connection = New SqlConnection(connetionString)
sql = "select * from costdata"
Try
connection.Open()
adapter = New SqlDataAdapter(sql, connection)
adapter.Fill(ds)
connection.Close()
ds.WriteXml("**PATH**")
MsgBox("Done")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
The problem I'm having is loading this data back in. It seems like it should be as easy as the above, but I can't seem to get a simple way to do it.
It's my understanding that I can use an XMLReader coupled with ADO.NET, but in that case I need to define the columns for the DataTable to insert the XML Data into before I import it all into the DB.
Is there any way to keep from having to hard-code column values in the DataTable, and have the exported XML data import in similar fashion to the above?
Though it's not automated by column name, I decided that hardcoding the mappings wasn't too big a hassle. I'm all ears for an automated way, however. My solution:
Dim connectionString As String = "Data Source=(localdb)\v11.0;Initial Catalog=localACETest;Integrated Security=True"
Try
Using sqlconn As New SqlConnection(connectionString)
Dim ds As New DataSet()
Dim sourcedata As New DataTable()
ds.ReadXml("C:\Users\coopere.COOPERE-PC\Desktop\Test.xml")
sourcedata = ds.Tables(0)
sqlconn.Open()
Using bulkcopy As New SqlBulkCopy(sqlconn)
bulkcopy.DestinationTableName = "ScheduleData"
bulkcopy.ColumnMappings.Add("Id", "Id")
bulkcopy.ColumnMappings.Add("Period", "Period")
...
bulkcopy.WriteToServer(sourcedata)
End Using
sqlconn.Close()
End Using
MsgBox("Done")
Catch ex As Exception
MsgBox(ex.ToString)
End Try
Here is a way to automate column mappings ... it assumes the table exists with the same structure in the target database. Cheers :-)
Public Shared Function BulkCopyXML( _
path_ As String, _
connection_string_ As String, _
messages_ As List(Of String), _
exceptions_ As List(Of Exception) _
) As Boolean
Dim result_ As Boolean = False
Try
Dim dataset_ As New DataSet()
dataset_.ReadXml(path_)
Dim datatable_ As DataTable = Nothing
Using connection_ As SqlClient.SqlConnection = New SqlClient.SqlConnection(connection_string_)
connection_.Open()
Using bulkCopy_ As SqlClient.SqlBulkCopy = New SqlClient.SqlBulkCopy(connection_)
For Each datatable_ In dataset_.Tables()
messages_.Add(datatable_.TableName)
bulkCopy_.DestinationTableName = datatable_.TableName
bulkCopy_.ColumnMappings.Clear()
For Each dataColumn_ As DataColumn In datatable_.Columns
bulkCopy_.ColumnMappings.Add(dataColumn_.ColumnName, dataColumn_.ColumnName)
Next
bulkCopy_.WriteToServer(datatable_)
Next
End Using
End Using
result_ = True
Catch exception_ As Exception
If exceptions_ Is Nothing Then
Throw exception_
Else
exceptions_.Add(exception_)
End If
Finally
End Try
Return result_
End Function