Get number of rows in a SQL Server table in VB.NET - sql-server

There are 10 rows in primary_student_table.
When I execute the following code, the result was -1.
Dim count As Int16
con.Open()
query = "SELECT COUNT(roll) AS rollcount FROM primary_student_table WHERE admityear = 2011 AND batch = 1 "
cmd = New SqlCommand(query, con)
count = cmd.ExecuteNonQuery
MsgBox(count)
con.Close()
What's the problem in the above code?

You should be using ExecuteScalar() rather than ExecuteNonQuery() because you are fetching a value.
count = Convert.ToInt16(cmd.ExecuteScalar())
MsgBox(count.ToString())
SqlCommand.ExecuteScalar Method
For proper coding
use using statement for proper object disposal
use try-catch block to properly handle exceptions
Example Code:
Dim connStr As String = "connection string here"
Dim query As String = "SELECT COUNT(roll) AS rollcount FROM primary_student_table WHERE admityear = 2011 AND batch = 1"
Using conn As New SqlConnection(connStr)
Using cmd As New SqlCommand()
With cmd
.Connection = conn
.CommandText = query
.CommandType = CommandType.Text
End With
Try
conn.Open()
Dim count As Int16 = Convert.ToInt16(cmd.ExecuteScalar())
MsgBox(count.ToString())
Catch(ex As SqlException)
' put your exception here '
End Try
End Using
End Using

The solution is to replace
count = cmd.ExecuteNonQuery
with
count = cmd.ExecuteScalar
Like Robert Beaubien said in his comments

MysqlConn = New MySqlConnection
MysqlConn.ConnectionString = "server=localhost;userid=root;password=1234;database=dblms"
Dim READER As MySqlDataReader
Try
MysqlConn.Open()
Dim Query As String
Query = "Select * from dblms.accounts"
COMMAND = New MySqlCommand(Query, MysqlConn)
READER = COMMAND.ExecuteReader
Dim count As Integer
count = 0
While READER.Read
count = count + 1
End While
MysqlConn.Close()
Catch ex As MySqlException
MessageBox.Show(ex.Message)
Finally
MysqlConn.Dispose()
End Try
the value in count will be the number of rows in a table :) hope this helped

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

Is there any code to change value of dim function

I want to put data in SQL table through vb.net in two columns which are Txn_Amount and Post_Amount
where textbox3 = Txn_Amount
Post Amount = Textbox4 - textbox3
but I want if textbox4 = "" than Post amount should be 0
This is my code:
Call Get_TxnID()
Dim Txn_Amount As String = TextBox3.Text
Dim Post_Amount As String = Val(TextBox4.Text) - Val(TextBox3.Text)
Dim query As String = "Insert into Txn_Master values (#Txn_Amount, #Post_Amount)"
Using cmd As New SqlCommand(query, Connection)
cmd.Parameters.AddWithValue("Txn_Amount", Txn_Amount)
cmd.Parameters.AddWithValue("Post_Amount", Post_Amount)
Connection.Open()
cmd.ExecuteNonQuery()
Connection.Close()
End Using
MsgBox("Transaction Success", MsgBoxStyle.Information)
It work well when i have value in both boxes For example :- textbox3.text = 25000 and textbox4.text = 50000 then Post_Amount is 25000
but if textbox3.text = 25000 and textbox4.text = "" then it shows -25000 in post_amount but i want if textbox4 = "" then post amount should be "" or "0"
I have tried
Dim Txn_Amount As String = TextBox3.Text
If textbox4.text="" then
Dim Post_Amount As String = ""
Else
Dim Post_Amount As String = Val(TextBox4.Text) - Val(TextBox3.Text)
endif
Dim query As String = "Insert into Txn_Master values (#Txn_Amount, #Post_Amount)"
Using cmd As New SqlCommand(query, Connection)
cmd.Parameters.AddWithValue("Txn_Amount", Txn_Amount)
cmd.Parameters.AddWithValue("Post_Amount", Post_Amount)
Connection.Open()
cmd.ExecuteNonQuery()
Connection.Close()
End Using
MsgBox("Transaction Success", MsgBoxStyle.Information)
But it is now working, please help me with this
If you initialise a variable for "Post_Amount" to zero, then you can check if the appropriate TextBox has an entry before setting its value, something like this:
Dim txnAmount As Integer = 0
If Not Integer.TryParse(tbTxnAmount.Text, txnAmount) Then
' Prompt user to enter an appropriate value in the TextBox.
' Exit Sub
End If
Dim postAmount As Integer = 0
'TODO Use sensible names for tbAmountA and tbAmountB.
If Not String.IsNullOrWhiteSpace(tbAmountB.Text) Then
'TODO: Use sensible names for these variables.
Dim a = 0
Dim b = 0
If Integer.TryParse(tbAmountA.Text, a) AndAlso Integer.TryParse(tbAmountB.Text, b) Then
postAmount = b - a
End If
End If
Using conn As New SqlConnection("your connection string")
Dim sql = "INSERT INTO [Txn_Master] VALUES (#Txn_Amount, #Post_Amount)"
Using cmd As New SqlCommand(sql, conn)
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#Txn_Amount",
.SqlDbType = SqlDbType.Int,
.Value = txnAmount})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "#Post_Amount",
.SqlDbType = SqlDbType.Int,
.Value = postAmount})
conn.Open()
cmd.ExecuteNonQuery()
cmd.Clone()
End Using
End Using
I strongly recommend that you use meaningful names for the TextBoxes and variables. "tbAmountB" is your "TextBox4", but it still needs a better name.
Strictly speaking, it doesn't need the String.IsNullOrWhiteSpace test as such a string would fail the parsing, but it does leave the intent clear.
Also, to make your code easier for others to read, it is convention to use camelCase for variable names: Capitalization Conventions.

Auto generate alpha numeric in VB.NET

I'm currently working on my project for which I used VB.NET 2019 and SQL server. I need to create a function which auto generates IDs.
I want my IDs to be like these: P001, P002, P003 etc. Can someone show me how to code it? Below is my code
Private Sub Form4_Load_1(sender As Object, e As EventArgs) Handles MyBase.Load
BindData()
Dim data As String = "Data Source=LAPTOP-M8KKSG0I;Initial Catalog=Oceania;Integrated Security=True"
Dim con As New SqlConnection(data)
Try
If Con.State = ConnectionState.Closed Then
con.Open()
End If
Dim sql As String = "Select Max(PatientID) from Patient"
Dim cmd As New SqlCommand(sql, con)
Dim Max As String = cmd.ExecuteScalar
If Max > 0 Then
TextBox1.Text = Max + 1
Else
TextBox1.Text = "P01"
End If
Catch ex As Exception
MsgBox(Err.Description)
End Try
End Sub
You can try like this. Here 1 is an auto-generated number that may be an identity key column value from a table in SQL Server.
Dim number As Integer = 1
Dim numberText As String = "P" & number.ToString().PadLeft(3, "0")
Live demo
You can add a computed column like this in your table for auto-generating the sequences. This will reduce the chances of duplicate value runtime once more than one person will do the entry simultaneously.
Alter table Patient ADD PatientCode AS ('P' + Convert(Varchar(3),CONCAT(REPLICATE('0', 3 - LEN(PatientID)), PatientID)) )
To get the column value dynamically you can try the below code to generate function.
Private Sub GenerateSequnce()
Dim constring As String = "Data Source=TestServer;Initial Catalog=TestDB;User id = TestUser;password=test#123"
Using con As New SqlConnection(constring)
Using cmd As New SqlCommand("Select Top 1 ISNULL(TaxCode, 0) from Tax_Mst Order By TaxCode Desc", con)
cmd.CommandType = CommandType.Text
Using sda As New SqlDataAdapter(cmd)
Using dt As New DataTable()
sda.Fill(dt)
Dim maxNumberCode = dt.Rows(0)("TaxCode").ToString()
If (maxNumberCode = "0") Then
maxNumberCode = "1"
End If
Dim numberText As String = "P" & maxNumberCode.ToString().PadLeft(3, "0")
End Using
End Using
End Using
End Using
End Sub
Here the column TaxCode is int with identity constraint.
With the minor correction in your code, you can achieve this as shown below.
Dim data As String = "Data Source=LAPTOP-M8KKSG0I;Initial Catalog=Oceania;Integrated Security=True"
Dim con As New SqlConnection(data)
Try
If con.State = ConnectionState.Closed Then
con.Open()
End If
Dim sql As String = "Select ISNULL(Max(PatientID), 0) from Patient"
Dim cmd As New SqlCommand(sql, con)
Dim Max As String = cmd.ExecuteScalar
If (Max = "0") Then
Max = "1"
Else
Max = CInt(Max) + 1
End If
Dim numberText As String = "P" & Max.ToString().PadLeft(3, "0")
TextBox1.Text = numberText
Catch ex As Exception
MsgBox(Err.Description)
End Try
OUTPUT

Query Timeout Expired when updating SQL Server from VB,NET

I'm updating SQL Server from VB.NET and keep getting the 'Query Timeout Error', I have lot's of sub routines that I run in sequence that look like the following:
Public Shared Sub Update_DailyRatings()
Dim stallStats As String = ""
Dim win As Integer = 0
Dim mSplit As Array
Dim cn As OleDbConnection = New OleDbConnection(MainForm.connectStringPublic)
cn.Open()
Dim selectString As String = "Select * FROM DailyRatings"
Dim cmd As OleDbCommand = New OleDbCommand(selectString, cn)
Dim reader As OleDbDataReader = cmd.ExecuteReader()
While (reader.Read())
stallStats = Get_Stall_Stats(reader("Track").ToString, CInt(reader("Stall")), CDbl(reader("Distance")))
If stallStats = "" Then
MainForm.NonQuery("UPDATE DailyRatings SET StallWin = 999 WHERE Horse = '" & reader("Horse").ToString & "'")
Else
mSplit = Split(stallStats, ",")
win = mSplit(0)
MainForm.NonQuery("UPDATE DailyRatings SET StallWin = " & win & " WHERE Horse = '" & reader("Horse").ToString & "'")
End If
End While
reader.Close()
cn.Close()
End Sub
The NonQuery sub looks like this:
Public Sub NonQuery(ByVal SQL As String)
Dim query As String = SQL
Try
Dim cn3 As OleDbConnection = New OleDbConnection(connectStringPublic)
cn3.Open()
Dim cmd As OleDbCommand = New OleDbCommand(query, cn3)
cmd.CommandTimeout = 90
cmd.ExecuteNonQuery()
cn3.Close()
cn3.Dispose()
cmd.Dispose()
OleDbConnection.ReleaseObjectPool()
Catch e As System.Exception
Clipboard.SetText(query)
MsgBox(e.Message)
Finally
End Try
End Sub
As you can see I've been trying ideas to fix this that I found in other threads such as extending the timeout and using the Dispose() and ReleaseObjectPool() methods but it hasn't worked, I still get query timeout error at least once when running all my subs in sequence, it's not always the same sub either.
I recently migrated from Access, this never used to happen with Access.
If you are dealing with Sql Server why are you using OleDb? I guessed that is was really access.
While your DataReader is open, your connection remains open. With the amount of processing you have going on, it is no wonder that your connection is timing out.
To begin, connections and several other database objects need to be not only closed but disposed. They may contain unmanaged resources which are released in the .Dispose method. If you are using an object that exposes a .Dispose method use Using...End Using blocks. This will take care of this problem even if there is an error.
Actually you have 2 distinct operations going on. First you are retrieving DailyRatings and then you are updating DailyRatings base on the data retrieved. So we fill a Datatable with the first chunk of data and pass it off to the second operation. Our first connection is closed and disposed.
In operation 2 we create our connection and command objects just as before except now our command has parameters. The pattern of the command is identical for every .Execute, only the values of the parameters change. This pattern allows the database, at least in Sql Sever, to cache a plan for the query and improve performance.
Public Shared Function GetDailyRatings() As DataTable
Dim dt As New DataTable
Using cn As New OleDbConnection(MainForm.connectStringPublic),
cmd As New OleDbCommand("Select * FROM DailyRatings", cn)
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
Public Sub UpdateDailyRatings()
Dim dt = GetDailyRatings()
Using cn As New OleDbConnection(connectStringPublic),
cmd As New OleDbCommand("UPDATE DailyRatings SET StallWin = #Stall WHERE Horse = #Horse")
cmd.Parameters.Add("#Stall", OleDbType.Integer)
cmd.Parameters.Add("#Horse", OleDbType.VarChar)
cn.Open()
For Each row As DataRow In dt.Rows
cmd.Parameters("#Horse").Value = row("Horse").ToString
Dim stallStats As String = Get_Stall_Stats(row("Track").ToString, CInt(row("Stall")), CDbl(row("Distance")))
If stallStats = "" Then
cmd.Parameters("#Stall").Value = 999
Else
cmd.Parameters("#Stall").Value = CInt(stallStats.Split(","c)(0))
End If
cmd.ExecuteNonQuery()
Next
End Using
End Sub
Private Function GetStallStats(Track As String, Stall As Integer, Distance As Double) As String
Dim s As String
'Your code here
Return s
End Function
Note: OleDb does not pay attention to parameters names. It is the order that they appear in the query statement must match the order that they are added to the Parameters collection.
It's possible that OleDbDataReader is locking your table or connection as it get the data with busy connection. You can store the data in a DataTable by using OleDbDataAdapter and loop through it to run your updates. Below is the snippet how your code would look like:
Dim cmd As OleDbCommand = New OleDbCommand(selectString, cn)
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter(cmd)
Dim dt As New DataTable()
adapter.Fill(dt)
For Each reader As DataRow In dt.Rows
stallStats = Get_Stall_Stats(reader("Track").ToString, CInt(reader("Stall")), CDbl(reader("Distance")))
If stallStats = "" Then
MainForm.NonQuery("UPDATE DailyRatings SET StallWin = 999 WHERE Horse = '" & reader("Horse").ToString & "'")
Else
mSplit = Split(stallStats, ",")
win = mSplit(0)
MainForm.NonQuery("UPDATE DailyRatings SET StallWin = " & win & " WHERE Horse = '" & reader("Horse").ToString & "'")
End If
Next
cn.Close()

Microsoft SQL Server SELECT statement

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

Resources