Dynamic Sql - retrieve from Oracle - vb.net

I have a form with button which should find records from Oracle database. I have three Textboxes on same form, and If text matches with values in fields of DB, Datagrid should show me this records. Here is my code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'connect to oracle DB
Dim oradb As String = "Data Source=orcl;User Id=Lucky;Password=Example;"
Dim conn As New OracleConnection(oradb)
conn.Open()
Dim SQL As String
SQL = "SELECT * FROM MyTable WHERE 1=1"
'SQL statement for 1st textbox
If Not TxtName.Text = "" Then
SQL = SQL & " AND USER_NAME =" & TxtName.Text
End If
'SQL statement for 2nd textbox
If Not TxtSurname.Text = "" Then
SQL = SQL & " AND USER_SURNAME =" & TxtSurname.Text
End If
'SQL statement for 3rd textbox
If Not TxtAddress.Text = "" Then
SQL = SQL & " AND USER_ADDRESS=" & TxtAddress.Text
End If
'select SQL statements and retrieve data using ExecuteReader
Dim cmd As New OracleCommand(SQL, conn)
cmd.CommandType = CommandType.Text
Dim dr As OracleDataReader = cmd.ExecuteReader()
Dim dt As New DataTable
dt.Load(dr)
DataGridView1.DataSource = dt
End Sub
What am I doing wrong, nothing happens when button clicked?

This is a non-tested sample of the direction you could try:
Private Sub populateDataGridView()
'connect to oracle DB
Const connectionString As String = "Data Source=orcl;User Id=Lucky;Password=Example;"
Using conn As New OracleConnection(connectionString)
conn.Open()
Using cmd As New OracleCommand()
Dim SQL As String = "SELECT * FROM testtable "
Dim conjunction As String = " Where "
'SQL statement for 1st textbox
If Not TxtName.Text.Length = 0 Then
SQL = String.Concat(SQL, conjunction, " USER_NAME like :username")
cmd.Parameters.Add(New OracleParameter("username", String.Concat("%", TxtName.Text, "%")))
conjunction = " and "
End If
'SQL statement for 2nd textbox
If Not TxtSurname.Text.Length = 0 Then
SQL = String.Concat(SQL, conjunction, " user_surname like :usersurname")
cmd.Parameters.Add(New OracleParameter("usersurname", String.Concat("%", TxtSurname2.Text, "%")))
conjunction = " and "
End If
'SQL statement for 3rd textbox
If Not TxtAddress.Text.Length = 0 Then
SQL = String.Concat(SQL, conjunction, " user_address like :useraddress")
cmd.Parameters.Add(New OracleParameter("useraddress", String.Concat("%", TxtAddress.Text, "%")))
End If
'select SQL statements and retrieve data using ExecuteReader
cmd.Connection = conn
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
End Using
End Sub

Related

Using 2 combo boxes to populate a datagridview in VB.NET

I having problems understanding why my one of my comboboxes displays a filtered search but the other one doesn't, I am using the same code for both comboboxes but modified some SQL queries linked to my database. I have also noticed that when I remove or comment out the code for any one of the comboboxes the the filtered search happens for the one hasn't been commented or removed. I also used an "If, Else" statement but still doesn't work. I would also want for both comboboxes to be used to filter a datagridview. Just to keep in mind once the item is selected from the combobox a search button is pressed to filer/display data into the datagridview.
Kind Regards
Here is my code and form:
[Redundant Data being displayed] https://i.stack.imgur.com/JEQI4.png
[ComboBox Brand works as intended] https://i.stack.imgur.com/6YyBf.png
[ComboBox Category displays everything rather than displaying the category chosen] https://i.stack.imgur.com/oEfII.png
Private Sub BtnSearch_Click(sender As Object, e As EventArgs) Handles BtnSearch.Click
If Not CmbBrand.SelectedIndex & CmbCategory.SelectedIndex = Nothing Then
BrandDisplay()
ElseIf CmbBrand.SelectedIndex & Not CmbCategory.SelectedIndex = Nothing Then
CategoryDisplay()
ElseIf Not CmbBrand.SelectedIndex & Not CmbCategory.SelectedIndex = Nothing Then
If DbConnect() Then
DgvRecord.Rows.Clear()
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * " &
"From TblStock " &
"Where STCategory Like #CategorySearch"
.Parameters.AddWithValue("#CategorySearch", "%" & CmbCategory.Text & "%")
Dim rs As OleDbDataReader = .ExecuteReader()
SQLCmd.ExecuteReader()
While rs.Read
Dim NewStockRow As New DataGridViewRow()
NewStockRow.CreateCells(DgvRecord)
NewStockRow.SetValues({rs("StockID"), rs("STDateTime"), rs("STCategory"), rs("STBrand"), rs("STItemDescription"), rs("STSerialNumber"), rs("StockIn"), rs("StockOut"), rs("Stock")})
NewStockRow.Tag = rs("StockID")
DgvRecord.Rows.Add(NewStockRow)
End While
rs.Close()
If DgvRecord.Rows(0).Selected = True Then
MessageBox.Show("Please select a Category from the drop down list", "Category", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End With
End If
End If
cn.Close()
End Sub
Private Sub BrandDisplay()
If DbConnect() Then
DgvRecord.Rows.Clear()
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * " &
"From TblStock " &
"Where STBrand Like #BrandSearch"
.Parameters.AddWithValue("#BrandSearch", "%" & CmbBrand.Text & "%")
Dim rs As OleDbDataReader = .ExecuteReader()
SQLCmd.ExecuteReader()
While rs.Read
Dim NewStockRow As New DataGridViewRow()
NewStockRow.CreateCells(DgvRecord)
NewStockRow.SetValues({rs("StockID"), rs("STDateTime"), rs("STCategory"), rs("STBrand"), rs("STItemDescription"), rs("STSerialNumber"), rs("StockIn"), rs("StockOut"), rs("Stock")})
NewStockRow.Tag = rs("StockID")
DgvRecord.Rows.Add(NewStockRow)
End While
rs.Close()
If DgvRecord.Rows(0).Selected = True Then
MessageBox.Show("Please select a Brand from the drop down list", "Brand", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End With
End If
cn.Close()
End Sub
Private Sub CategoryDisplay()
If DbConnect() Then
DgvRecord.Rows.Clear()
Dim SQLCmd As New OleDbCommand
With SQLCmd
.Connection = cn
.CommandText = "Select * " &
"From TblStock " &
"Where STCategory Like #CategorySearch"
.Parameters.AddWithValue("#CategorySearch", "%" & CmbCategory.Text & "%")
Dim rs As OleDbDataReader = .ExecuteReader()
SQLCmd.ExecuteReader()
While rs.Read
Dim NewStockRow As New DataGridViewRow()
NewStockRow.CreateCells(DgvRecord)
NewStockRow.SetValues({rs("StockID"), rs("STDateTime"), rs("STCategory"), rs("STBrand"), rs("STItemDescription"), rs("STSerialNumber"), rs("StockIn"), rs("StockOut"), rs("Stock")})
NewStockRow.Tag = rs("StockID")
DgvRecord.Rows.Add(NewStockRow)
End While
rs.Close()
If DgvRecord.Rows(0).Selected = True Then
MessageBox.Show("Please select a Category from the drop down list", "Category", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End If
End With
End If
cn.Close()
End Sub
```
It is a good idea to separate your User Interface code from you database code. Your event procedure code should be rather brief.
Declare your Connections, Commands and DataReaders in the method where they are used so they can be disposed. Using...End Using blocks do this for us; they also close the connection. Pass your connection string directly to the constructor of the connection.
We have a different CommandText and ParametersCollection for each possibility. For Sql Server use the Add method rather than AddWithValue.
Private Sub BtnSearch_Click(sender As Object, e As EventArgs) Handles BtnSearch.Click
Dim dt = GetSearchData(CmbBrand.Text, CmbCategory.Text)
DGVRecord.DataSource = dt
End Sub
Private Function GetSearchData(Brand As String, Category As String) As DataTable
Dim dt As New DataTable
Dim sqlString = "Select * From From TblStock "
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand()
cmd.Connection = cn
If Not String.IsNullOrEmpty(Brand) AndAlso Not String.IsNullOrEmpty(Category) Then
cmd.CommandText = sqlString & "Where STCategory = #CategorySearch And STBrand = #BrandSearch;"
cmd.Parameters.Add("#CategorySearch", SqlDbType.VarChar).Value = Brand
cmd.Parameters.Add("#BrandSearch", SqlDbType.VarChar).Value = Category
ElseIf Not String.IsNullOrEmpty(Brand) Then
cmd.CommandText = sqlString & "Where STBrand = #BrandSearch;"
cmd.Parameters.Add("#BrandSearch", SqlDbType.VarChar).Value = Category
ElseIf Not String.IsNullOrEmpty(Category) Then
cmd.CommandText = sqlString & "Where STCategory = #CategorySearch;"
cmd.Parameters.Add("#CategorySearch", SqlDbType.VarChar).Value = Brand
Else
cmd.CommandText = sqlString & ";"
End If
cn.Open()
Using reader = cmd.ExecuteReader()
dt.Load(reader)
End Using
End Using
Return dt
End Function
For better understanding you need to change those first "if... then... else...".
If the combobox is not selected it will have value -1 so you can do it like this:
Dim bBrandIsSelected as boolean = CmbBrand.SelectedIndex <> -1
Dim bCategoryIsSelected as boolean = CmbCategory.SelectedIndex <> -1
Now you can build the code more easily like:
If bBrandIsSelected AndAlso bCategoryIsSelected then
' do something
else
if bBrandIsSelected then
BrandDisplay()
else
if bCategoryIsSelected then
CategoryDisplay()
End if
End if
End if

Database locked in vb.net when trying to update data in vb.net

Hello I have a simple method to update customer details in one of my database tables however when i try to update it an error occurs saying the database is locked. I have no idea how to fix this because my add and delete queries work just fine.
This is the error message:
System.Data.SQLite.SQLiteException: 'database is locked
database is locked'
Public Sub updateguest(ByVal sql As String)
Try
con.Open()
With cmd
.CommandText = sql
.Connection = con
End With
result = cmd.ExecuteNonQuery
If result > 0 Then
MsgBox("NEW RECORD HAS BEEN UPDATED!")
con.Close()
Else
MsgBox("NO RECORD HASS BEEN UPDATDD!")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
End Sub
Private Sub IbtnUpdate_Click(sender As Object, e As EventArgs) Handles ibtnUpdate.Click
Dim usql As String = "UPDATE Customers SET fname = '" & txtFName.Text & "'" & "WHERE CustomerID ='" & txtSearchID.Text & "'"
updateguest(usql)
End Sub
Private Sub IbtnSearch_Click(sender As Object, e As EventArgs) Handles ibtnSearch.Click
Dim sSQL As String
Dim newds As New DataSet
Dim newdt As New DataTable
Dim msql, msql1 As String
Dim con As New SQLiteConnection(ConnectionString)
con.Open()
msql = "SELECT * FROM Customers Where Fname Like '" & txtSearchName.Text & "%'"
msql1 = "SELECT * FROM Customers Where CustomerID '" & txtSearchID.Text & "'"
Dim cmd As New SQLiteCommand(msql, con)
Dim cmd1 As New SQLiteCommand(msql1, con)
Dim dt = GetSearchResults(txtSearchName.Text)
dgvCustomerInfo.DataSource = dt
Dim mdr As SQLiteDataReader = cmd.ExecuteReader()
If mdr.Read() Then
If txtSearchName.Text <> "" Then
sSQL = "SELECT * FROM customers WHERE fname LIKE'" & txtSearchName.Text & "%'"
Dim con1 As New SQLiteConnection(ConnectionString)
Dim cmd2 As New SQLiteCommand(sSQL, con1)
con1.Open()
Dim da As New SQLiteDataAdapter(cmd2)
da.Fill(newds, "customers")
newdt = newds.Tables(0)
If newdt.Rows.Count > 0 Then
ToTextbox(newdt)
End If
dgvCustomerInfo.DataSource = newdt
con1.Close()
txtSearchID.Clear()
ElseIf txtSearchID.Text <> "" Then
sSQL = "SELECT * FROM customers WHERE CustomerID ='" & txtSearchID.Text & "'"
Dim con2 As New SQLiteConnection(ConnectionString)
Dim cmd2 As New SQLiteCommand(sSQL, con2)
con2.Open()
Dim da As New SQLiteDataAdapter(cmd2)
da.Fill(newds, "customers")
newdt = newds.Tables(0)
If newdt.Rows.Count > 0 Then
ToTextbox(newdt)
End If
dgvCustomerInfo.DataSource = newdt
con2.Close()
txtSearchName.Clear()
End If
Else
MsgBox("No data found")
End If
End Sub
Private Sub IbtnDelete_Click(sender As Object, e As EventArgs) Handles ibtnDelete.Click
Dim dsql As String = "DELETE FROM customers WHERE customerid = " & txtSearchID.Text & ""
deleteme(dsql)
updatedgv(dgvCustomerInfo)
txtSearchID.Clear()
txtSearchName.Clear()
End Sub
Public Sub deleteme(ByVal sql As String)
Try
con.Open()
With cmd
.CommandText = sql
.Connection = con
End With
result = cmd.ExecuteNonQuery
If result > 0 Then
MsgBox("NEW RECORD HAS BEEN DELTED!")
con.Close()
Else
MsgBox("NO RECORD HASS BEEN DELTED!")
End If
Catch ex As Exception
MsgBox(ex.Message)
Finally
con.Close()
End Try
End Sub
You made a good start on keeping your database code separate from you user interface code. However, any message boxes should be shown in the user interface and any sql statements should be written in the data access code.
I used Using...End Using blocks to ensure that database objects are closed and disposed. I used parameters to protect against sql injection. I am not too sure of the mapping of DbType types to Sqlite types. You might have to fool with that a bit. In you original Update statement you had the ID value in quotes. This would pass a string. When you use parameters, you don't have to worry about that or ampersands and double quotes. Just one clean string.
Private ConStr As String = "Your connection string"
Public Function updateguest(FirstName As String, ID As Integer) As Integer
Dim Result As Integer
Dim usql As String = "UPDATE Customers SET fname = #fname WHERE CustomerID = #ID;"
Using con As New SQLiteConnection(ConStr),
cmd As New SQLiteCommand(usql, con)
cmd.Parameters.Add("#fname", DbType.String).Value = FirstName
cmd.Parameters.Add("#ID", DbType.Int32).Value = ID
con.Open()
Result = cmd.ExecuteNonQuery
End Using
Return Result
End Function
Private Sub IbtnUpdate_Click(sender As Object, e As EventArgs) Handles ibtnUpdate.Click
Try
Dim Result = updateguest(txtFName.Text, CInt(txtSearchID.Text))
If Result > 0 Then
MsgBox("New RECORD HAS BEEN UPDATED!")
Else
MsgBox("NO RECORD HAS BEEN UPDATDD!")
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub

Search between two dates in access database using sql

This is my code for search in access database 2010. My problem is that when I search between two datetimepicker the result is wrong in datagridview, I mean when I search from specific records between May and June it shows me records also from February.
Private Sub Search_Record()
Dim conn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim da As New OleDbDataAdapter
Dim dt As New DataTable
Dim sSQL As String = String.Empty
Dim bookdetials As New frmContactDetails
Try
'get connection string declared in the Module1.vb and assing it to conn variable
conn = New OleDbConnection(Get_Constring)
conn.Open()
cmd.Connection = conn
cmd.CommandType = CommandType.Text
sSQL = "SELECT contact_id, first_name , birth_date, book_num, send_from, no_answer, no_answer_by, rec, book_answer_name, book_answer_num, send_date, send_to, project_name FROM tblAddressBook"
If CheckBox1.Checked = True Then
sSQL = sSQL & " where project_name like '%" & Me.TextBox2.Text & "%' " & _
" AND birth_date between '" & DateTimePicker1.Text & "' AND '" & DateTimePicker2.Text & "'"
End If
cmd.CommandText = sSQL
da.SelectCommand = cmd
da.Fill(dt)
Me.dtgResult.DataSource = dt
Label4.Text = dt.Rows.Count
Catch ex As Exception
MsgBox(ErrorToString)
Finally
conn.Close()
End Try
End Sub
datepicker text should be converted to datetime format in sql
I had the same problem, the solution was too silly but it worked
use text instead of datetime in the db
make sure the datetimepicker enters "short format" data

Getting Primary key values (auto number ) VB

I have a database on Access and I want to insert into 2 tables
ReportReq
req_sysino
I want to get the last value of primary key (auto numbered) and insert it into req_sysino
, I am stuck with this code and I dont know how to proccess
Private Function InsertSysInvToDB(intSysInv As Integer) As Integer
Dim strSQLStatement As String = String.Empty
Dim intNoAffectedRows As Integer = 0
Dim con As New OleDb.OleDbConnection("PROVIDER = Microsoft.ace.OLEDB.12.0; Data Source = C:\Users\felmbanF\Documents\Visual Studio 2012\Projects\WebApplication3\WebApplication3\App_Data\ReportReq.accdb")
Dim cmd As OleDb.OleDbCommand
Dim reqnum As String = "Select ##REQ_NUM from ReportReq"
strSQLStatement = "INSERT INTO req_sysino (Req_num, sysinvo_ID)" +
" VALUES (" & reqnum & "','" & intSysInv & ")"
cmd = New OleDb.OleDbCommand(strSQLStatement, con)
cmd.Connection.Open()
intNoAffectedRows = cmd.ExecuteNonQuery()
cmd.Connection.Close()
Return intNoAffectedRows
End Function
this is my insert code that should generate autonumber
Dim dbProvider = "PROVIDER = Microsoft.ace.OLEDB.12.0;"
Dim dbSource = " Data Source = C:\Users\felmbanF\Documents\Visual Studio 2012\Projects\WebApplication3\WebApplication3\App_Data\ReportReq.accdb"
Dim sql = "INSERT INTO ReportReq (Emp_EmpID, Req_Date,Req_expecDate,Req_repnum, Req_name, Req_Descrip, Req_columns, Req_Filtes, Req_Prompts)" +
"VALUES (#reqNUM,#reqName,#reqDescrip,#reqcolumns,#reqfilters,#reqprompts)"
Using con = New OleDb.OleDbConnection(dbProvider & dbSource)
Using cmd = New OleDb.OleDbCommand(sql, con)
con.Open()
cmd.Parameters.AddWithValue("#EmpID", txtEmpID.Text)
cmd.Parameters.AddWithValue("#reqDate", DateTime.Today)
cmd.Parameters.AddWithValue("#reqExpecDate", DateTime.Parse(txtbxExpecDate.Text).ToShortDateString())
cmd.Parameters.AddWithValue("#reqNUM", txtRep_NUM.Text)
cmd.Parameters.AddWithValue("#reqName", txtRep_Name.Text)
cmd.Parameters.AddWithValue("#reqDescrip", txtbxRep_Desc.Text)
cmd.Parameters.AddWithValue("#reqcolumns", txtbxColReq.Text)
cmd.Parameters.AddWithValue("#reqfilters", txtbxFilReq.Text)
cmd.Parameters.AddWithValue("#reqprompts", txtbxPromReq.Text)
cmd.ExecuteNonQuery()
End Using
End Using
Immediately after you ExecuteNonQuery() your INSERT INTO ReportReq ... statement you need to run a
SELECT ##IDENTITY
query and retrieve its result, like this
cmd.ExecuteNonQuery() ' your existing statement to run INSERT INTO ReportReq
cmd.CommandText = "SELECT ##IDENTITY"
Dim newAutoNumberValue As Integer = cmd.ExecuteScalar()

Child list for field salesreport cannot be created

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOk.Click
Dim scan As String = "select ProductCode from products where ProductCode = '" & TextBox1.Text & "';"
connection.Open()
Dim cmd = New MySqlCommand(scan, connection)
Dim dr As MySqlDataReader = cmd.ExecuteReader
If dr.Read = True Then
MsgBox("Match found")
connection.Close()
Dim insert As String = "insert into salesreport (ProductName,ProductPrice) select products.ProductName,products.ProductPrice from products where products.ProductCode = '" & TextBox1.Text & "';"
connection.Open()
da = New MySqlDataAdapter(insert, connection)
da.Fill(ds, "salesreport")
DataGridView1.DataSource = ds
DataGridView1.DataMember = "salesreport"
connection.Close()
Else
connection.Close()
MsgBox("No match found")
TextBox1.Text = ""
TextBox1.Select()
End If
End Sub
INSERT statements doesn't return records.
There is no sense in this situation to use a DataAdapter to INSERT a record.
Use the MySqlCommand.ExecuteNonQuery method to insert your record, then read the added row with a MySqlDataAdapter
Also, do not concatenate text, typed by your user, to build and use an sql text for the database engine. Your code could be easily used to create Sql Injection Attacks.
Dim scan As String = "select ProductCode from products " +
"where ProductCode = ?prodCode"
connection.Open()
Dim cmd = New MySqlCommand(scan, connection)
cmd.Parameters.AddWithValue("?prodCode", TextBox1.Text)
..........
Dim insert As String = "insert into salesreport (ProductName,ProductPrice) " +
"select products.ProductName,products.ProductPrice from products " +
"where products.ProductCode = ?prodCode"
cmd = new MySqlCommand(insert, connection)
cmd.Parameters.AddWithValue("?prodCode", TextBox1.Text)
cmd.ExecuteNonQuery()
da = New MySqlDataAdapter(scan, connection)
da.SelectCommand.Parameters.AddWithValue("?prodCode", TextBox1.Text)
da.Fill(ds, "salesreport")
DataGridView1.DataSource = ds
DataGridView1.DataMember = "salesreport"