Microsoft SQL Server SELECT statement - sql-server

I need help retrieving ReceiptNO column from a database table and saving it into a TextBox or Label for referencing.
CODE:
Dim da2 As New SqlDataAdapter
da2.SelectCommand = New SqlCommand("SELECT RecepitNO FROM Receipt WHERE (PaidFor=#PaidFor AND RegNO=#RegNO)")
da2.SelectCommand.Parameters.Add("#paidFor", SqlDbType.VarChar).Value = cbMonth.Text
da2.SelectCommand.Parameters.Add("#RegNO", SqlDbType.Int).Value = lblRegNO.Text
cn.Open()
da2.Update(ds.Tables("Receipt"))
'da2.SelectCommand.ExecuteNonQuery()
da2.SelectCommand.ExecuteReader()
cn.Close()

You need to use a SqlDataReader, and then start a loop to read the values returned
This example will work assuming the ReceiptNO is a text field
cn.Open()
Dim reader = da2.SelectCommand.ExecuteReader()
while reader.Read()
textBox1.Text = reader("ReceiptNO").ToString()
End While
In alternative, if you are sure that your query returns zero or just one record and you are interested only in the ReceiptNO field, then you can use ExecuteScalar
Dim cmd = New SqlCommand("SELECT RecepitNO FROM Receipt WHERE (PaidFor=#PaidFor AND RegNO=#RegNO)")
cmd.Connection = cn
cmd.Parameters.Add("#paidFor", SqlDbType.VarChar).Value = cbMonth.Text
cmd.Parameters.Add("#RegNO", SqlDbType.Int).Value = lblRegNO.Text
cn.Open()
Dim result = cmd.ExecuteScalar()
if result IsNot Nothing Then
textBox1.Text = result.ToString()
End If
Here the MSDN docs on ExecuteScalar

Related

Error when trying to insert data from vb.net datagridview into SQL Server table

I get this error when I run the code. The records are inserted into the table, but the program stops at the error.
The parameterized query '(#EmpName varchar(8000),#USDBasic varchar(8000),#OtherUSDEarning' expects the parameter '#EmpName', which was not supplied.
Code:
Dim connetionString As String
Dim cnn As SqlConnection
connetionString = "Data Source=Server\SQlExpress;Initial Catalog=CreSolDemo;User ID=sa;Password=Mkwn#011255"
cnn = New SqlConnection(connetionString)
If DataGridView1.Rows.Count > 0 Then
Dim cmd As New Data.SqlClient.SqlCommand
cmd.CommandText = " INSERT INTO TempPeriodTrans (EmpName, USDBasic, OtherUSDEarnings, ZDollarBasic, OtherZDEarnings) VALUES (#EmpName, #USDBasic, #otherUSDEarnings, #ZDollarBasic, #OtherZDEarnings) "
cmd.Parameters.Add("#EmpName", SqlDbType.VarChar)
cmd.Parameters.Add("#USDBasic", SqlDbType.VarChar)
cmd.Parameters.Add("#OtherUSDEarnings", SqlDbType.VarChar)
cmd.Parameters.Add("#ZDollarBasic", SqlDbType.VarChar)
cmd.Parameters.Add("#OtherZDEarnings", SqlDbType.VarChar)
cmd.Connection = cnn
cnn.Open()
For i As Integer = 0 To DataGridView1.Rows.Count - 1
cmd.Parameters(0).Value = DataGridView1.Rows(i).Cells(0).Value
cmd.Parameters(1).Value = DataGridView1.Rows(i).Cells(1).Value
cmd.Parameters(2).Value = DataGridView1.Rows(i).Cells(2).Value
cmd.Parameters(3).Value = DataGridView1.Rows(i).Cells(3).Value
cmd.Parameters(4).Value = DataGridView1.Rows(i).Cells(4).Value
cmd.ExecuteNonQuery()
Next
cnn.Close()
End If
MsgBox("Record saved")
End Sub
There seem to be a few things here.
As a rule, any time you open a connection to your data base it should be wrapped in a Using block so that that connection gets closed and disposed before you exit that block
You have a lot of params that are being set as SqlDbType.varchar where you should probably have other types. (SqlDbType.Money in particular)
When you are working with sqlcommand, it is worth wrapping it in a using block as well and creating a new one as you need it.
There is some memory to it where it will try not to reuse parameters in subsequent queries. Instead of just changing the value of the param, throw that sqlCommand in the trash bin each time and grab a new one. This is where I believe your problem is. I moved the sqlcommand creation into your loop and declare the values in-line below.
Also, protip, avoid including your actual password in the connetion string on Stack Overflow
Dim connectionString As String = "yourConnectionString"
Using cnn As new SqlConnection(connectionString)
cnn.Open()
For Each row in DataGridView1.Rows
Using cmd As New Data.SqlClient.SqlCommand("INSERT INTO TempPeriodTrans (EmpName, USDBasic, OtherUSDEarnings, ZDollarBasic, OtherZDEarnings) Values (#EmpName, #USDBasic, #otherUSDEarnings, #ZDollarBasic, #OtherZDEarnings) ", cnn)
cmd.Parameters.Add("#EmpName", SqlDbType.VarChar).value = row.Cells(0).Value
cmd.Parameters.Add("#USDBasic", SqlDbType.VarChar).value = row.Cells(1).Value
cmd.Parameters.Add("#OtherUSDEarnings", SqlDbType.VarChar).value = row.Cells(2).Value
cmd.Parameters.Add("#ZDollarBasic", SqlDbType.VarChar).value = row.Cells(3).Value
cmd.Parameters.Add("#OtherZDEarnings", SqlDbType.VarChar).value = row.Cells(4).Value
cmd.ExecuteNonQuery()
End using
Next
End using
MsgBox("Record Saved")
End Sub

How to detect it was duplicate entry on VB.NET?

I have a problem on making avoid or detect duplicate data entry in VB.NET using SQL Server, and also pop up message when there is duplicate entry.
This is my add button code:
Dim sql = "INSERT INTO studentAttendence(studentID, date, time, subject, attendence) " &
"VALUES(#studentID, #date, #time, #subject, #attendence)" &
"WHERE NOT EXISTS(SELECT * FROM studentAttendence WHERE studentID = #studentID)"
Using cn As New SqlConnection("My sql Connection string")
Dim commands As SqlCommand = New SqlCommand(sql, cn)
commands.Parameters.Add("#studentID", SqlDbType.NVarChar).Value = TextBox1.Text
commands.Parameters.Add("#date", SqlDbType.NVarChar).Value = DateTimePicker1.Text
commands.Parameters.Add("#time", SqlDbType.NVarChar).Value = DateTimePicker2.Text
commands.Parameters.Add("#subject", SqlDbType.NVarChar).Value = ComboBox1.Text
commands.Parameters.Add("#attendence", SqlDbType.NVarChar).Value = ComboBox2.Text
commands.ExecuteNonQuery()
End Using
Or is there any other methods for making avoid duplicate entries. I just want to avoid same date and subject of a student to add. So I can only add subject on the next date if I already add subject on today's date of studentID.
You can use If Not Exists before the insert. This method only requires a single hit on the database. Add a comman at the end of the first line of the Using block, then delete Dim before commands. This will include commands in the Using block.
Private Function InsertAttendance() As Integer
Dim sql = "If Not Exists (Select 1 From studentAttendence
Where studnetID = #studentID And date = #date And subject = #subject)
INSERT INTO studentAttendence(studentID, date, time, subject, attendence)
VALUES(#studentID, #date, #time, #subject, #attendence);"
Dim NumRowsAffected As Integer
Using cn As New SqlConnection("My sql Connection string"),
commands As SqlCommand = New SqlCommand(sql, cn)
commands.Parameters.Add("#studentID", SqlDbType.NVarChar).Value = TextBox1.Text
commands.Parameters.Add("#date", SqlDbType.NVarChar).Value = DateTimePicker1.Text
commands.Parameters.Add("#time", SqlDbType.NVarChar).Value = DateTimePicker2.Text
commands.Parameters.Add("#subject", SqlDbType.NVarChar).Value = ComboBox1.Text
commands.Parameters.Add("#attendence", SqlDbType.NVarChar).Value = ComboBox2.Text
cn.Open()
NumRowsAffected = commands.ExecuteNonQuery()
End Using
Return NumRowsAffected
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
If InsertAttendance() = 1 Then
MessageBox.Show("Success")
Else
MessageBox.Show("Duplicate Entry")
End If
Catch ex As Exception
MessageBox.Show($"Error Entering Attendance {ex.Message}")
End Try
End Sub
Be sure to check the datatypes of your parameters with the database.
You should create a function that queries your data table to return the row count where the Date, Subject, and StudentId match what you're wanting to insert. If the returned result is greater than 0 then display the message.
Here is a function that returns -1 if something went wrong or the row count:
Private Function GetRowCount(ByVal studentIdParameter As String, ByVal dateParameter As DateTime, ByVal subjectParameter As String) As Integer
'Declare the object to return
Dim count As Integer = -1
'Declare the connection object
Dim con As OleDbConnection
'Wrap code in Try/Catch
Try
'Set the connection object to a new instance
'TODO: Change "My Connection String Here" with a valid connection string
con = New OleDbConnection("My Connection String Here")
'Create a new instance of the command object
'TODO: Change [ID] to a valid column
Using cmd As OleDbCommand = New OleDbCommand("SELECT Count([ID]) FROM [MyTable] WHERE studentID=#studentId, AND date=#date AND subject=#subject", con)
'Parameterize the query
cmd.Parameters.Add("#studentId", OleDbType.NVarChar).Value = studentIdParameter
cmd.Parameters.Add("#date", OleDbType.DBDate).Value = dateParameter.Date
cmd.Parameters.Add("#subject", OleDbType.NVarChar).Value = subjectParameter
'Open the connection
con.Open()
'Use ExecuteScalar to return a single value
count = Convert.ToInt32(cmd.ExecuteScalar())
'Close the connection
con.Close()
End Using
Catch ex As Exception
'Display the error
Console.WriteLine(ex.Message)
Finally
'Check if the connection object was initialized
If con IsNot Nothing Then
If con.State = ConnectionState.Open Then
'Close the connection if it was left open(exception thrown)
con.Close()
End If
'Dispose of the connection object
con.Dispose()
End If
End Try
'Return the row count
Return count
End Function
To implement it, you'd do something like:
Dim rowCount = GetRowCount(TextBox1.Text, DateTimePicker1.Value, ComboBox1.Text)
If (rowCount = -1) Then
MessageBox.Show("Something went wrong checking for duplicates")
ElseIf (rowCount = 0) Then
' Insert record
Else
MessageBox.Show("A record already exists with this studentId, date, and subject.")
End If

SqlParameter not supplied when using Parameters.AddWithValue

This is how I set up my command. It stops with the first parameter, UpdateType. This code is being updated from VB.NET 2008 version.
Dim db As New DB()
Dim cmd As SqlCommand = New SqlCommand()
'Put into an object, and use AddWithValue due to Parameters.Add being deprecated.
Dim UpdateType As String = "PARAMETERS"
If IsNewJob Then
cmd.CommandText = "sp_MB_AddJob"
Else
cmd.CommandText = "sp_MB_UpdateJob"
cmd.Parameters.AddWithValue("#UpdateType", SqlDbType.NVarChar).Value = UpdateType
cmd.Parameters.AddWithValue("#OrigJobName", OrigJobName.ToString)
End If
cmd.Parameters.AddWithValue("#UserID", CInt(Utils.GetLoggedInUserID))
cmd.Parameters.AddWithValue("#ProjectName", ProjectName.ToString)
You should use .Add instead with the type and for NVARCHAR, VARCHAR, or VARBINARY
with the length. Here I show how to do the tings you have in the question, I made up lengths just for the example. Using AddWithValue can have negative impact on SQL performance and other things.
Some information to help you can be found in many places including here https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/configuring-parameters-and-parameter-data-types
Dim db As New DB()
Dim cmd As SqlCommand = New SqlCommand()
Dim UpdateType As String = "PARAMETERS"
cmd.CommandType = CommandType.StoredProcedure
If IsNewJob Then
cmd.CommandText = "sp_MB_AddJob"
Else
cmd.CommandText = "sp_MB_UpdateJob"
cmd.Parameters.Add("#UpdateType", SqlDbType.NVarChar, 10).Value = UpdateType
cmd.Parameters.Add("#OrigJobName", SqlDbType.NVarChar, 50).Value = OrigJobName.ToString
End If
cmd.Parameters.Add("#UserID", SqlDbType.Int).Value = CInt(Utils.GetLoggedInUserID)
cmd.Parameters.Add("#ProjectName", SqlDbType.NVarChar, 30).Value = ProjectName.ToString
Keep your database objects local to the method where they are used so you can control that they are closed and disposed. `Using...End Using blocks take care of this for you. Note a single Using block is handling both the connection and the command.
The .Add method is NOT being deprecated. What is obsolute is the .Add(String, Object) overload. `.AddWithValue is certainly out of favor. See http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
Here is another
https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html
I had to guess at the datatype and column size of your parameters. Check your database for the actual values and correct the code accordingly.
Private Sub OpCode()
Dim UpdateType As String = "PARAMETERS"
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand()
cmd.Connection = cn
If IsNewJob Then
cmd.CommandText = "sp_MB_AddJob"
Else
cmd.CommandText = "sp_MB_UpdateJob"
cmd.Parameters.Add("#UpdateType", SqlDbType.NVarChar, 50).Value = UpdateType
cmd.Parameters.Add("#OrigJobName", SqlDbType.NVarChar, 200).Value = OrigJobName.ToString
End If
cmd.Parameters.Add("#UserID", SqlDbType.Int).Value = CInt(Utils.GetLoggedInUserID)
cmd.Parameters.Add("#ProjectName", SqlDbType.NVarChar, 200).Value = ProjectName.ToString
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Sub

VB.Net fires error on saving data to SQL Server

I am creating a LMS in VB.Net and SQL Server. The book adding form contains text boxes combo boxes and picture box. When I click the save button It says the following error message
Conversion failed when converting the varchar value 'Saman' to data type int.
On the form load the combo boxes populate the data from the entire tables.
Tables and relationship
Data to be inserted
Tables with data type
Error message on saving
I tried with the following coding
Form load coding
Private Sub frmAddBook_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'To load Author details
Using com As New SqlCommand("SELECT * FROM tblBookAuthor", con)
Dim dt As New DataTable()
dt.Load(com.ExecuteReader)
cmbAuthor.DataSource = dt
cmbAuthor.DisplayMember = "authorFirstName"
cmbAuthor.ValueMember = "authorFirstName"
' con.Close()
End Using
'To load Publisher details
Using com2 As New SqlCommand("SELECT * FROM tblPublisher", con)
Dim dt As New DataTable()
dt.Load(com2.ExecuteReader)
cmbPub.DataSource = dt
cmbPub.DisplayMember = "publisherName"
cmbPub.ValueMember = "publisherName"
' con.Close()
End Using
'To load Class details
Using com3 As New SqlCommand("SELECT * FROM tblBookClass", con)
Dim dt As New DataTable()
dt.Load(com3.ExecuteReader)
cmbClass.DataSource = dt
cmbClass.DisplayMember = "classDetail"
cmbClass.ValueMember = "classDetail"
' con.Close()
End Using
'To load bookshelf details
Using com4 As New SqlCommand("SELECT * FROM tblBookShelfDetail", con)
Dim dt As New DataTable()
dt.Load(com4.ExecuteReader)
cmbBookShelf.DataSource = dt
cmbBookShelf.DisplayMember = "shelfDetail"
cmbBookShelf.ValueMember = "shelfDetail"
con.Close()
End Using
End Sub
Save button coding
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
sql = "INSERT INTO tblBookDetail (accessionNo, authorId, title, pages, price, ISBN, noOfCopies, pubId, classId, source, bookShelfNo,bookEdition, bookCoverImg) VALUES (#accNo, #auID, #title, #pages, #price, #ISBN, #noOfCopies, #pubID, #classID, #src, #shlfNo, #edition, #img)"
Dim ms As New MemoryStream()
picPhoto.Image.Save(ms, picPhoto.Image.RawFormat)
con.Open()
cmd = New SqlCommand(sql, con)
cmd.Parameters.Add("#accNo", SqlDbType.Int).Value = txtBookID.Text
cmd.Parameters.Add("#auID", SqlDbType.VarChar).Value = cmbAuthor.Text
cmd.Parameters.Add("#title", SqlDbType.VarChar).Value = txtEdition.Text
cmd.Parameters.Add("#pages", SqlDbType.Int).Value = txtPageNo.Text
cmd.Parameters.Add("#price", SqlDbType.Decimal).Value = txtPrice.Text
cmd.Parameters.Add("#ISBN", SqlDbType.Int).Value = txtISBN.Text
cmd.Parameters.Add("#noOfCopies", SqlDbType.Int).Value = txtNoOfCopies.Text
cmd.Parameters.Add("#pubID", SqlDbType.VarChar).Value = cmbPub.Text
cmd.Parameters.Add("#classID", SqlDbType.VarChar).Value = cmbClass.Text
cmd.Parameters.Add("#src", SqlDbType.VarChar).Value = cmbSrc.Text
cmd.Parameters.Add("#shlfNo", SqlDbType.VarChar).Value = cmbBookShelf.Text
cmd.Parameters.Add("#edition", SqlDbType.Int).Value = txtEdition.Text
cmd.Parameters.Add("#img", SqlDbType.Image).Value = ms.ToArray
cmd.ExecuteNonQuery()
MsgBox("SUCCESS")
con.Close()
End Sub
Program Error :
Conversion failed when converting the varchar value 'Saman' to data
type int.
Here, you are having column authorID as datatype integer, then how come you will be able to insert varchar, i.e Name 'Saman' into it !
Line of Code that trigger this error :
cmd.Parameters.Add("#auID", SqlDbType.VarChar).Value = cmbAuthor.Text
Make sure table column is not integer or change accordingly.
Edit :
If want to insert id then :
replace text with SelectedValue in combobox
Hope you got the point. Thanks

how to get each unique value from access database column and add to combobox items

I am not professional but i am trying to learn VB.net. I am making a project where i am stuck where i want to get each unique value from a column in access database and add it to my combobox. Can anybody help me ??
Private Sub showItems()
Dim comm As OleDbCommand
Dim commStr As String = "SELECT Item_Name FROM Add_Items WHERE (Item_Name <> '"
Dim RD As OleDbDataReader
conn = New OleDbConnection(connStr)
conn.Open()
If cbItemname.Items.Count = 0 Then
comm = New OleDbCommand("Select Item_Name from Add_Items", conn)
RD = comm.ExecuteReader
While RD.Read
cbItemname.Items.Add(RD.GetString(0))
End While
End If
For Each i As Object In cbItemname.Items
comm = New OleDbCommand(commStr & i & "')", conn)
RD = comm.ExecuteReader
While RD.Read
cbItemname.Items.Add(RD.GetString(0))
Exit While
End While
Next
conn.Close()
End Sub
comm = New OleDbCommand("Select DISTINCT Item_Name from Add_Items", conn)
http://office.microsoft.com/en-in/access-help/HV080760568.aspx
You can get this error because your database table name is incorrect. Make sure you are in the Tables tab and check the name of the table. DISTINCT and UNIQUE(for MySQL) is correct solution for this.
I followed instructions given by vipul. It was working nicely and i made some more private subs for brands and Models and it suddenly stopped working. Now, when my form loads from previous parent form it hangs.
Private Sub showItems()
Dim comm As OleDbCommand
Dim commStr As String = "SELECT DISTINCT Item_Name from Add_Items"
Dim ReadData As OleDbDataReader
itemnamecombo.Items.Clear()
ItemChkboxList.Items.Clear()
Try
conn = New OleDbConnection(ConnStr)
conn.Open()
comm = New OleDbCommand(commStr, conn)
ReadData = comm.ExecuteReader
While ReadData.Read
itemnamecombo.Items.Add(ReadData.GetString(0))
ItemChkboxList.Items.Add(ReadData.GetString(0))
End While
Catch ex As Exception
'MessageBox.Show(ex.Message)
Finally
conn.Dispose()
End Try
If itemnamecombo.Items.Count <> 0 Then
itemnamecombo.SelectedIndex = 0
End If
End Sub

Resources