Determining data types using ADO.NET in VB.NET - vb.net

In the past I have used the code below to find out what datatypes the columns of a table. Now that I am using ADO.NET, I cannot a find a way of doing that with VB.NET and ADO.NET. How would I do it using ADO.NET? Do I have to enumerate all the data types or is there a "isnumeric" or a "isstring" type function?
Select Case rs(sColumnName).Type
Case ADODB.DataTypeEnum.adUnsignedSmallInt, ADODB.DataTypeEnum.adUnsignedTinyInt, ADODB.DataTypeEnum.adUnsignedBigInt, ADODB.DataTypeEnum.adUnsignedInt, ADODB.DataTypeEnum.adSingle, ADODB.DataTypeEnum.adTinyInt, ADODB.DataTypeEnum.adSmallInt, ADODB.DataTypeEnum.adInteger, ADODB.DataTypeEnum.adBigInt, ADODB.DataTypeEnum.adDecimal, ADODB.DataTypeEnum.adDouble, ADODB.DataTypeEnum.adNumeric, ADODB.DataTypeEnum.adCurrency '
sType="NUMERIC"
Case ADODB.DataTypeEnum.adVarChar, ADODB.DataTypeEnum.adLongVarChar, ADODB.DataTypeEnum.adLongVarWChar, ADODB.DataTypeEnum.adVarWChar, ADODB.DataTypeEnum.adWChar, ADODB.DataTypeEnum.adChar ' ADD ALL THE STRING TYPES
sType="STRING"
End Select

You can use GetDataTypeName from SqlDataReader class.
Example:
Dim con As New SqlConnection("Data Source=(local);Database=mydb;Integrated Security=SSPI;")
Dim reader As SqlDataReader
Dim cmd As New SqlCommand
cmd.CommandText = "select * from table1"
cmd.Connection = con
reader = cmd.ExecuteReader
MessageBox.Show(reader.GetDataTypeName(1))

Related

Two Connections types in one method (SQL and OLEDB)

I have two connections types to be used in my app. One is SQL Server, using the SqlClient.Connection type. The other one uses the OleDb.Connection type.
The question is, when using a DataAdapter, DataReader, and Command, how can I use one reference for each with both connections?
As an example, I want to use a reader like this:
Dim MyReader As OleDb.OleDbDataReader
to check my data with an OleDbConnection, and then use same reader to check data from the second SqlClient connection. That is, I want to do something like this (pseudocode):
Dim con
Dim MyReader
con = oledb.connection
MyReader = mymethod(con)
con = sql.sqlclient.conection
MyReader = mymethod2(con)
How can I do this in real code?
I need help in how to declare data components for two different connection types inside the same method or function.
You should declare multiple variables. It's really not a big deal to do so.
But, if you really want to do this (again: not the best idea) one thing you can keep in mind is these objects all inherit from a common set of types in the System.Data.Common namespace. So it possible to write code like this:
Dim con As System.Data.Common.DbConnection = New OleDbConnection("connection string here")
Dim cmd As System.Data.Common.DbCommand = New OleDbCommand("SELECT * ... ", con)
con.Open()
Dim rdr As System.Data.Common.DbDataReader = con.ExecuteReader()
While rdr.Read()
' ...
End While
con.Close()
con = New SqlClient.SqlConnection("connection string here")
cmd = New SqlClient.SqlCommand("SELECT * ...", con)
con.Open()
rdr = cmd.ExecuteReader()
While rdr.Read()
' ...
End While
But again: you really are better off using separate variables.

What would cause my dataset to drop a row?

I have a SQL statement that, when ran in SSMS, returns 6 rows. After attaching the statement to the command text of a VB.NET SQLCommand with a command type of Text, reading it with a SqlDataReader, and attaching it to a dataset, the returned dataset only has 5 rows.
At first, I assumed it was an issue with the data. However, after several bouts of removing and adding rows to the source table with varying data, it was obvious that I was always getting the total row count - 1. I then decided to just use a SQLDataAdapter to populate the DataSet and the proper number of rows was returned.
Dim ds As New DataSet
Dim sqlCmd as New SqlCommand
Dim sqlCn As New SqlConnection
Dim sqlR As New SqlCommand
sqlCn.ConnectionString = "SomeConnectionString"
With sqlCmd.CommandText = "Select * from DummyTable"
.CommandType = CommandType.Text
.Connection = sqlCn
End With
sqlCn.Open()
sqlR = sqlCmd.ExecuteReader
sqlR.Read()
If sqlR.HasRows() Then
ds.Tables.Add("DummyTable")
ds.Tables(0).Load(sqlR)
return ds
End If
From here, I'm expecting to see the 6 rows from DummyTable. Instead, I'm seeing only 5.
However, if I use the following:
Dim da as SqlDataAdapter
Using sqlCn
da.SelectCommand = New SqlCommand(sqlCmd.CommandText, sqlCn)
da.Fill(ds)
End Using
Return ds
I get the full 6 rows. Is there something I'm missing about the way a DataSet's Tables.Add(tableName) or Tables(n).Load(dataReader) works? I had never worked with SqlDataReaders prior to this and was told to stick with them as our other projects use them.
Your code is already reading the first line of the query with the line sqlR.Read(). This line is unnecessary in your code. Remove it and it will work fine.
Also SqlCommand, SqlConnection and SqlDataReader implement iDisposable, so be sure to use using-statement with them:
Using sqlCn As New SqlConnection("SomeConnectionString")
sqlCn.Open()
Using sqlCmd as New SqlCommand
With sqlCmd.CommandText = "Select * from DummyTable"
.CommandType = CommandType.Text
.Connection = sqlCn
End With
Using sqlR As SqlDataReader = sqlCmd.ExecuteReader
If sqlR.HasRows() Then
Dim ds As New DataSet
ds.Tables.Add("DummyTable")
ds.Tables(0).Load(sqlR)
return ds
End If
End Using
End Using
End Using

How to populate a combobox from two different SQL Server database tables

I am trying to create a system that will load items from a database. There are two comboboxes; combobox1 which loads items from database table 1 and combox2 which loads items from database table 2.
Both tables are in the same database.
Here is was I tried but when I run the system I get this error:
(Conversion from string "SELECT * FROM dbo.Dishes" to type 'Long' is not valid.)
Here is the code I'm using:
Dim connection As New SqlConnection("Server = DESKTOP-1373H91; Initial Catalog = MealPreOrderSystem; Integrated Security = True")
connection.Open()
Dim query As String = "SELECT * FROM dbo.Dishes" And "SELECT * FROM dbo.Desserts"
Dim cmd As SqlCommand
cmd = New SqlCommand(query, connection)
Dim reader As SqlDataReader
reader = cmd.ExecuteReader
While reader.Read
cbxType.Items.Add(reader.Item("MealName"))
cbxType.Items.Add(reader.Item("DessertName"))
End While
connection.Close()
In VB.NET,AND is an operator.It is used to perform conjunction between either Booleans or Integers/Doubles/any numeric expression.Lets take your query string as an example :
Dim query As String = "SELECT * FROM dbo.Dishes" And "SELECT * FROM dbo.Desserts"
You are using AND here to join 2 sentences/strings which wouldn't result in anything rather it is trying to cast it as a Long.
Try to execute this command in SQL and you won't find any luck :(.
Your statements are correct :
SELECT * FROM dbo.Dishes
SELECT * FROM dbo.Desserts
But the way you are trying to achieve your goals is incorrect :(.
To get the data from the database into your combobox, what you can do is either use two comboboxes with separated SQL Queries/SQL Commands or you can use one combobox where you add data from both the databases but separate them with some special characters such as a comma ,
A sample may look like :
With one combobox
Dim cmd1 as new SqlCommand("SELECT * FROM dbo.Dishes",connection)
Dim dr as SqlDatareader = cmd1.ExecuteReader
While dr.Read
mycombo1.Items.Add(dr(0)) ' Here 0 is the column count,change it as required
End while
Dim cmd2 as new SqlCommand("SELECT * FROM dbo.Desserts",connection)
Dim dr2 as SqlDatareader = cmd2.ExecuteReader
While dr2.Read
mycombo2.Items.Add(dr2(0)) ' Here 0 is the column count,change it as required
End while
With 1 combobox
Here it gets a bit complicated.Firstly you need to populate your combobox from the data received from the first dataReader.Then, when the 2nd datareader is reading the data , you need to update the existing data/Item of the combobox keeping the existing data/item but adding new data/item to each existing data/item(separating them with ,).
Sample :
Dim i as Integer
Dim cmd1 as new SqlCommand("SELECT * FROM dbo.Dishes",connection)
Dim dr as SqlDatareader = cmd1.ExecuteReader
While dr.Read
mycombo1.Items.Add(dr(0))
End while
Dim cmd2 as new SqlCommand("SELECT * FROM dbo.Desserts",connection)
Dim dr2 as SqlDatareader = cmd2.ExecuteReader
While dr2.Read
mycombo1.Items(i) = myconbo1.Items(i) & "," & dr2(0)
i = i + 1
End while
Now, NOTE THAT I AM USING MULTIPLE DATAREADERS WITH THE SAME CONNECTION ,SO YOU MAY NEED TO INCLUDE MultipleActiveResultSets=True IN YOUR CONNECTION STRING or ENCLOSE THE DATAREADERS IN USING STATEMENTS or CALL dataReader.Close AFTER EACH DATAREADER HAS COMPLETED READING FROM THE DATABASE
This will solve your issue :)
Looks like you don't know how to write SQL queries (and your VB syntax itself looks faulty - string AND string?).
Dim connection As New SqlConnection("Server = DESKTOP-1373H91; Initial Catalog = MealPreOrderSystem; Integrated Security = True")
Dim query As String = <cmdString>
SELECT MealName as Name FROM dbo.Dishes
union
SELECT DessertName as Name FROM dbo.Desserts
</cmdString>
Dim cmd As SqlCommand
Dim reader As SqlDataReader
connection.Open()
cmd = New SqlCommand(query, connection)
reader = cmd.ExecuteReader
While reader.Read
cbxType.Items.Add(reader.Item("Name"))
End While
connection.Close()
Note: You are saying 2 comboboxes but your code seemed to be loading all the items to a single combobox. If you really need 2 comboboxes then use 2 SqlCommand and Reader loops (actually it would be better if you simply have used Linq for this).
You should be a bit more specific on what columns you are pulling from the 2 tables. if they are similar, you could write a sql query to UNION ALL the fields with a simple control to identify which record came from which table.
Example of SQL command string:
"SELECT 'M' AS Ctl, MealName AS aName FROM dbo.Dishes " &
"UNION ALL " &
"SELECT 'D' AS Ctl, DessertName AS aName FROM dbo.Desserts"
As mentioned by many here already, it seems like you are referencing only 1 ControlBox to list the fields returned cbxType
below is the reader (adapted to 2 ComboBoxes):
While reader.Read
Select Case reader.Item("Ctl")
Case "M"
cbxMType.Items.Add(reader.Item("aName"))
Case "D"
cbxDType.Items.Add(reader.Item("aName"))
End Select
End While
Hope this helps

Is filling a DataTable necessary for just setting variables with 2 column values?

I am trying to improve performance of an application, I have a case where a common SPROC is being used but is it necessary to fill a DataTable just to set 2 variable values?
Is there anything more efficient?
Dim Conn As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("DB").ConnectionString)
Dim CmdUsers As SqlCommand = New SqlCommand("uspGetUsers", Conn)
CmdUsers.CommandType = CommandType.StoredProcedure
CmdUsers.Parameters.Add(New SqlParameter("#UserName", Session("UserID")))
Dim da As SqlDataAdapter = New SqlDataAdapter
Dim dtUserInfo As DataTable = New DataTable
da = New SqlDataAdapter(CmdUsers)
da.Fill(dtUserInfo)
isParent = dtUserInfo.Rows(0)("IsAdmin")
UserVal = dtUserInfo.Rows(0)("UserVal")
A SqlDataReader is the fastest way to read data from a query. Try the following:
Using conn As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("DB").ConnectionString)
conn.Open()
Using cmd As New SqlCommand("uspGetUsers", conn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("#UserName", Session("UserID"))
Using reader As SqlDataReader = cmd.ExecuteReader()
While reader.Read()
isParent = reader("IsAdmin")
UserVal = reader("UserVal")
End While
End Using
End Using
End Using
You may need to parse the data to the correct types.
Also, note the use of Using to automatically dispose of the connection, command and reader objects: http://msdn.microsoft.com/en-GB/library/htd05whh.aspx

Retrieving rows from a MS Access Database View using Vb.Net

I've managed to get the following code...
con.ConnectionString = My.Settings.dbConnection
Dim sqlCmd As System.Data.OleDb.OleDbCommand = New System.Data.OleDb.OleDbCommand()
con.Open()
sqlCmd.Connection = con
Dim schemaTable As DataTable
schemaTable = con.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Views, Nothing)
To retrieve a list of Views in my Access database, but now I want to retrieve the results based on a selected View.
Is there a correct method in doing this, or do I take the SQL Statement from the DataTable returned for each row?
Suppose you have Query1 (View) in your Access database (Database1.accdb file). The following code will output each row of the query to the console (for demo purposes):
Dim con As OleDbConnection = New OleDbConnection()
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Database1.accdb;Persist Security Info=False;"
Dim sqlCmd As OleDbCommand = New System.Data.OleDb.OleDbCommand()
sqlCmd.CommandType = CommandType.StoredProcedure
sqlCmd.CommandText = "Query1"
sqlCmd.Connection = con
con.Open()
Dim reader As OleDbDataReader
reader = sqlCmd.ExecuteReader()
If reader.HasRows Then
While reader.Read()
Console.WriteLine(reader("Column1")) 'output specific column
End While
End If
Console.ReadLine()
Hope this helps