Dynamically retrieve Oracle data from double parameter? - vb.net

I have names and surnames to retrieve from DB, but It's not working as It should. I get names and surnames from a table where they are in separated columns. Names/surnames are displayed in combobox/textbox combination on my form. Now I need to retrieve this data, but there are only 4 fields in my DB to search, because all names/surnames are combined together in those fields (user request). My code works for 2 searches at a time, but not for all 4. Here is my code:
EDIT (this works now - I've separated parameters and added bracket in OR statements):
Using con As New OracleConnection("Data Source=myDB;User Id=Lucky;Password=MyPassword;")
con.Open()
Using cmd As New OracleCommand()
Dim SQL As String = "Select * FROM MyTable "
Dim conca As String = " Where "
Dim Person1 As String
Person1 = CmbName.Text.Trim & " " & TxtSurname.Text.Trim
If Not CmbName.Text = "" Then
SQL = String.Concat(SQL, conca, " (USER1 = :user OR USER2 = :user1)")
cmd.Parameters.Add(New OracleParameter("user", Person1))
cmd.Parameters.Add(New OracleParameter("user1", Person1))
conca = " and "
End If
Dim Person2 As String
Person2 = CmbName1.Text.Trim & " " & TxtSurname1.Text.Trim
If Not CmbName1.Text = "" Then
SQL = String.Concat(SQL, conca, " (ADMINISTRATOR1 = :admin OR ADMINISTRATOR2 = :admin1)")
cmd.Parameters.Add(New OracleParameter("admin", Person2))
cmd.Parameters.Add(New OracleParameter("admin1", Person2))
conca = " and "
End If
'Retrieve data using execute reader
cmd.Connection = con
cmd.CommandText = SQL
cmd.CommandType = CommandType.Text
Dim dr As OracleDataReader = cmd.ExecuteReader()
Dim dt As New DataTable
dt.Load(dr)
DataGridView1.DataSource = dt
End Using
I tried using brackets between "and" & "or", but this still doesn't work. Any suggestions ?

Although I don't like your approach, you should separate the queries or have one function retrieving results for you for each "Person" request. For your solution try to remove this: conca = " and " from the first and second 'if/else' statement. Add each result into your datatable and then load the gridview with the datatable.
You should call a function similar to this to get the results in a data reader and then feed your datatable. This way you can separate your queries. The tricky part is to have an elegant way to load your datagridview. My suggestion is to stop using datatables (they are very bad). You should use IEnumerable or List (Of Object) where you could add the results from each query.
Public Shared Function GetMeDatareader(yourQuery As String) As OracleDataReader
Using con As New OracleConnection("Data Source=myDB;User Id=Lucky;Password=MyPassword;")
con.Open()
Using cmd As New OracleCommand()
Dim SQL As String = yourQuery
'Retrieve data using execute reader
cmd.Connection = con
cmd.CommandText = SQL
cmd.CommandType = CommandType.Text
Dim dr As OracleDataReader = cmd.ExecuteReader()
Return dr
End Using
End Using
End Function

Related

Can't INSERT INTO access database

I can select the data from an Access database, but I tried many ways to INSERT INTO database. There is no error message, but it didn't insert the data.
Code:
Dim conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & CurDir() & "\fsDB1.accdb")
Dim cmd As OleDbCommand
Dim dr As OleDbDataReader
conn.Open()
Dim CommandString As String = "INSERT INTO tblfile(stdUname,filePw,filePath,status) VALUES('" & userName & "','" & filePw & "','" & filePath & "','A')"
Dim command As New OleDbCommand(CommandString, conn)
Command.Connection = conn
Command.ExecuteNonQuery()
I just want a simple easy way to INSERT INTO an Access database. Is it possible because of the problem of Access database? I can insert this query by running query directly in Access.
Firstly I would check the database settings. If your app copies a new copy of the database each time you run it that would explain why you can select existing data and why your new data is not being saved (Well it is being saved, but the database keeps getting replaced with the old one). Rather set it up to COPY IF NEWER.
Further, you should ALWAYS use parameterized queries to protect your data. It is also is less error prone than string concatenated commands ans is much easier to debug.
Also, I recommend using a USING block to handle database connections so that your code automatically disposes of resources no longer needed, just in case you forget to dispose of your connection when you are done. Here is an example:
Using con As New OleDbConnection
con.ConnectionString = "Provider = Microsoft.ACE.OLEDB.12.0; " & _
"Data Source = "
Dim sql_insert As String = "INSERT INTO Tbl (Code) " & _
"VALUES " & _
"(#code);"
Dim sql_insert_entry As New OleDbCommand
con.Open()
With sql_insert_entry
.Parameters.AddWithValue("#code", txtCode.Text)
.CommandText = sql_insert
.Connection = con
.ExecuteNonQuery()
End With
con.Close()
End Using
Here is an example where data operations are in a separate class from form code.
Calling from a form
Dim ops As New Operations1
Dim newIdentifier As Integer = 0
If ops.AddNewRow("O'brien and company", "Jim O'brien", newIdentifier) Then
MessageBox.Show($"New Id for Jim {newIdentifier}")
End If
Back-end class where the new primary key is set for the last argument to AddNewRow which can be used if AddNewRow returns true.
Public Class Operations1
Private Builder As New OleDbConnectionStringBuilder With
{
.Provider = "Microsoft.ACE.OLEDB.12.0",
.DataSource = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Database1.accdb")
}
Public Function AddNewRow(
ByVal CompanyName As String,
ByVal ContactName As String,
ByRef Identfier As Integer) As Boolean
Dim Success As Boolean = True
Dim Affected As Integer = 0
Try
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText = "INSERT INTO Customer (CompanyName,ContactName) VALUES (#CompanyName, #ContactName)"
cmd.Parameters.AddWithValue("#CompanyName", CompanyName)
cmd.Parameters.AddWithValue("#ContactName", ContactName)
cn.Open()
Affected = cmd.ExecuteNonQuery()
If Affected = 1 Then
cmd.CommandText = "Select ##Identity"
Identfier = CInt(cmd.ExecuteScalar)
Success = True
End If
End Using
End Using
Catch ex As Exception
Success = False
End Try
Return Success
End Function
End Class

Adding SQL Parameter fails

This is a new concept for me and I can't quite see what's causing the error
I'm attempting to populate a datagridview control from a single field in an Access database (from a combo and Text box source).
Using literals works, but not with the parameter.
Dim conn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Backend & ";Persist Security Info=False;")
Dim command As New OleDbCommand("Select Year from tblTest ", conn)
Dim criteria As New List(Of String)
If Not cboYear.Text = String.Empty Then
criteria.Add("Year = #Year")
command.Parameters.AddWithValue("#Year", cboYear.Text)
End If
If criteria.Count > 0 Then
command.CommandText &= " WHERE " & String.Join(" AND ", criteria)
End If
Dim UserQuery As New OleDbDataAdapter(command.CommandText, conn)
Dim UserRet As New DataTable
UserQuery.Fill(UserRet)
With frmDGV.DataGridView2
.DataSource = UserRet
End With
frmDGV.DataGridView2.Visible = True
frmDGV.Show()
Trying to Fill the datatable shows exception 'No value given for one or more required parameters.'
The value of command.CommandText at that point is "Select Year from tblTest WHERE Year = #Year"
Your instance of OleDbDataAdapter was created using two parameters query text and connection.
Dim UserQuery As New OleDbDataAdapter(command.CommandText, conn)
In this case DataAdapter doesn't know about parameters at all.
Instead use constructor with paremeter of type OleDbCommand.
Dim UserQuery As New OleDbDataAdapter(command)
In your code instance of OleDbCommand already associated with connection

Populate ListBox from SQL only items with condition (first character)

I've managed to put all items in a ListBox, also have the first character defined kto, how to insert only those values from List column into Listbox that begin with that character kto.
Just to mention that kto is value from 0 to 9, always a number.
Dim SqlSb As New SqlConnectionStringBuilder()
SqlSb.DataSource = ".\sqlexpress"
SqlSb.InitialCatalog = "Konta"
SqlSb.IntegratedSecurity = True
Using SqlConn As SqlConnection = New SqlConnection(SqlSb.ConnectionString)
SqlConn.Open()
Dim cmd As SqlCommand = SqlConn.CreateCommand()
cmd.CommandText = "SELECT List FROM Konta"
Dim kto = Left(Label1.Text, 1)
'Label3.Text = kto
Using reader As SqlDataReader = cmd.ExecuteReader
While (reader.Read())
Me.ListBox1.Items.Add(reader("LIST"))
End While
End Using
SqlConn.Close()
End Using
Try this
Dim SqlSb As New SqlConnectionStringBuilder()
SqlSb.DataSource = ".\sqlexpress"
SqlSb.InitialCatalog = "Konta"
SqlSb.IntegratedSecurity = True
Using SqlConn As SqlConnection = New SqlConnection(SqlSb.ConnectionString)
SqlConn.Open()
Dim cmd As SqlCommand = SqlConn.CreateCommand()
Dim kto = Left(Label1.Text, 1)
cmd.CommandText = "SELECT List FROM Konta WHERE List LIKE '" & kto.toString & "%'"
ListBox1.Items.Clear
Using reader As SqlDataReader = cmd.ExecuteReader
While (reader.Read())
Me.ListBox1.Items.Add(reader("LIST"))
End While
End Using
SqlConn.Close()
End Using
In your while loop, before adding the item in the listbox check the date type of reader("LIST") and add it only if matches the required type.
You can check the type using the following code:
reader.GetFieldType(0)

I can not read from database Visual basic

Dim conStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\databaseVB\bakery.accdb"
Dim conn As New OleDbConnection(conStr)
Dim cmd As New OleDbCommand
Dim reader As OleDbDataReader
Dim Item(5) As String
Dim key = TextBox1.Text
conn.Open()
cmd.Connection = conn
1>>>>> 'cmd.CommandText = "SELECT * FROM Member WHERE number = 3"
2>>>>> cmd.CommandText = "SELECT * FROM Member WHERE number = '" & key & "'"
MessageBox.Show(cmd.CommandText)
reader = cmd.ExecuteReader()
While reader.Read
Item(0) = reader("Number").ToString
Item(1) = reader("FirstName").ToString
Item(2) = reader("LastName").ToString
Item(3) = reader("User").ToString
Item(4) = reader("Pass").ToString
End While
MessageBox.Show(Item(1).ToString)
conn.Close()
from 1>>> I can read Item in databaes
from 2>>> I can not read Item
Try using a parameterized query string:
cmd.CommandText = "SELECT * FROM Member WHERE number = #Number"
After this add your parameters.
//cmd.Parameters.Add("#Number", SqlDbType.Int).Value = 3;
//It is better to use .TryParse(), incase your users write non numerical values in the Textbox
cmd.Parameters.Add("#Number", SqlDbType.Int).Value = (int)TextBox1.Text;
Additionally you need to watch your data types. 3 is of type int, but TextBox1.Text is of type string. You need to parse the string to int in order for it to work.
This should do the trick and prevent ugly syntax juggling, while mixing strings and variables; And prevent you from SQL Injection attacks.

Database VB.net

How to retrieve the data from Database in VB.net
I am using
SELECT* FROM tbl1 WHERE Col1 = 'Chaitra'
My requirement is there is one Textbox, I have retrieved text from that textbox & assigns to a variable called str1.
Now I have to compare this variable with database (SELECT* FROM tbl1 WHERE Col1 = str1).
Can we write like this? or is there any other way to do this?
Use parameters to prevent Sql-Injection
Dim t As New DataTable()
Using c As New SqlConnection(connectionString)
c.Open()
Using a As New SqlDataAdapter("SELECT* FROM tbl1 WHERE Col1 = #Col1", c)
'use the appropriate SqlDbType'
a.SelectCommand.Parameters.Add("#Col1", SqlDbType.NChar, 5, "Col1")
a.SelectCommand.Parameters("#Col1").Value = str1
a.Fill(t)
End Using
End Using
Return t
Edit: according to your comment that you want to query MS Access
Dim t as New DataTable
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter()
Dim command As OleDbCommand
Using connection As New OleDbConnection(connectionString)
' Create the SelectCommand.
command = New OleDbCommand("SELECT * FROM Users " & _
"WHERE UserName = ?", connection)
command.Parameters.Add("UserName", OleDbType.VarChar, 20).Value = userName 'userName is a string variable
adapter.SelectCommand = command
connection.Open()
adapter.Fill(t) 't is the DataTable that holds all columns of the User
End Using
http://msdn.microsoft.com/en-us/library/bbw6zyha.aspx