I want to get a value from a SQL Server column ID and show it on label.text with help the of following code:
Sub getID()
Dim selquery As String = ("select max(id)+1 from picture1")
Dim command As New SqlCommand(selquery, con)
con.Open()
Label1.Text = (command.ExecuteScalar)
con.Close()
End Sub
The scenario is to get maximum value from ID make it plus 1, and assign it to label.text, it works correctly when I have at least one record in my SQL Server table but if I have no record in my table picture1 then it shows error
You can leverage the ISNULL T-SQL function to deal with this:
SELECT ISNULL(MAX(id), 0) + 1 from picture1
If you have no records in your table, the max(id) part will return null, and you cannot +1 to a null.
To work around that problem use the COALESCE operator, like:
COALESCE(MAX(ID), 0) + 1
If there is a value returned from max(id) it will use that, otherwise it will return 0
The return value of command.ExecuteScalar is of type Object, so you have to check the value.
This should work:
Dim objResult As Object = command.ExecuteScalar
Dim intResult As Integer = If(TypeOf objResult Is Integer, DirectCast(objResult, Integer), 0)
Label1.Text = intResult.ToString
Also you should switch Option Strict On
Related
I wrote the function below to get the values of two columns in a database, one is composed by integers (ID) and other dates/times in DATETIME format, in SQL Server 2008 R2. It stores the two values in two distinct arrays (lists), defined here:
Dim arrPartIDs As New List(Of Integer)
Dim arrPartUMDates As New List(Of Date)
My goal is to clone the datetime value of each row to the column 'Part_Previous_UMDate', which are currently set as NULL.
However, when my code execute the line:
WinToolSQLCmd.ExecuteReader()
After
WinToolSQLCmd = New SqlCommand("UPDATE WTData.dbo.Parts SET Part_Previous_UMDate = '" & arrPartUMDates.Item(intUMDateCounter) & "' WHERE ID = " & PartID.ToString, WinToolConnection)
The application returns an exception
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
I thought that by creating the array (list) arrPartUMDates as a list of date I could simply transfer its values back to the database, but apparently they are created as strings when added to the array...
What's the best approach to clone the DATETIME value in UMDate to Part_Previous_UMDate with full precision? I need to have full precision because later I´ll compare the values of the two columns in order to determine if they need an update.
Any ideas? I've searched for this error message but could not find anything related to dealing with dates in arrays...
Image of table here: http://i.stack.imgur.com/BYT1j.png
Code:
Function MirrorUMDateInPartsTable()
Dim arrPartIDs As New List(Of Integer)
Dim arrPartUMDates As New List(Of Date)
Dim WinToolConnection As New SqlConnection(StrGlobalWinToolConnection)
Dim intUMDateCounter As Integer = 0
WinToolSQLCmd = New SqlCommand("SELECT TOP 5 ID, UMDate FROM WTData.dbo.Parts WHERE WTData.dbo.Parts.Part_Previous_UMDate IS NULL ORDER BY ID", WinToolConnection)
WinToolConnection.Open()
Dim reader = WinToolSQLCmd.ExecuteReader()
While reader.Read()
arrPartIDs.Add(reader.Item(0))
arrPartUMDates.Add(reader.Item(1))
End While
reader.Close()
WinToolSQLCmd.Dispose()
If arrPartIDs.Count > 0 Then
For Each PartID As Integer In arrPartIDs
WinToolSQLCmd = New SqlCommand("UPDATE WTData.dbo.Parts SET Part_Previous_UMDate = '" & arrPartUMDates.Item(intUMDateCounter) & "' WHERE ID = " & PartID.ToString, WinToolConnection)
WinToolSQLCmd.ExecuteReader()
Next
End If
Return Nothing
End Function
You should use SqlParameter to add values to your query (and also to guard against SQL injection). Your problem is that you convert the date to a string in the code and SQL Server treats it as a string. The error about conversion from varchar occurs because the date format is not the one SQL Server uses. If you use parameters, it knows that you pass the date value and sends it correctly - you don't need to worry about any string conversions.
WinToolSQLCmd = New SqlCommand("UPDATE WTData.dbo.Parts SET Part_Previous_UMDate = #DateParam WHERE ID = #IdParam", WinToolConnection)
WinToolSQLCmd.Parameters.Add("#DateParam", arrPartUMDates.Item(intUMDateCounter))
WinToolSQLCmd.Parameters.Add("#IdParam", PartID)
Also, it's an update query, so you should use ExecuteNonQuery to execute your query:
WinToolSQLCmd.ExecuteNonQuery()
ExecuteReader is used when you want to read the data from the database.
Edit
I'm so confused, now I changed this if statement:
If Data.Rows.Count > 0 Then
'Do all Voucher things in here
else
txtVoucher.text = "Sorry, Invalid Voucher"
end if
To display the query from the voucher checking function by outputting it as one of Voucher's string properties, like this:
else txtvoucher.text = Voucher.voucherName end if
And everything works fine! If I change it back to an error message... the datatable returns no rows. I haven't changed anything else about the code, just what goes to the textbox if the row count is 0. Shouldn't the row count be the same regardless of what I send to the textbox afterward?
End Edit
I am making a basic Online Voucher function for a webpage and am having issues with the voucher checking query.
I have this query, which checks the string entered into a textbox against the SQL table for a match.
Public Shared Function CheckForVoucher(ByVal strVoucherName As String) As DataTable
Dim connect As New SqlConnection
Dim Data As New DataTable 'Connection works, finds number of Vouchers in DB that match either code or ID. ID to be used for randomly generated vouchers.
connect.ConnectionString = "SERVER = SERVER-SQL01; Trusted_Connection=yes; DATABASE=PCSQL"
connect.Open()
Dim query As String
Dim search As String
search = strVoucherName
If search.Length >= 20 Then
query = "SELECT * from PCSQL.dbo.VOUCHER_DETAILS WHERE vID='" + search + "' "
Else
query = "SELECT * from PCSQL.dbo.VOUCHER_DETAILS WHERE voucherName='" + search + "' "
End If
Dim command = New SqlDataAdapter(query, connect)
command.Fill(Data)
connect.Close()
Return Data
End Function
The query works fine in SQL Manager, I can replace the keyword search with any of the voucher names I have in the list and it returns the correct result, same goes if I replace the search keyword in vb.net and force the query to check for a specific voucher no matter what is entered in the textbox (e.g. TestVoucher2).
I currently have the page set to check for results as below.
Protected Sub lbVoucherCheck_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lbVoucherCheck.Click
'Voucher checking code to go here
Dim Data As DataTable = Voucher.CheckForVoucher(txtVoucher.Text)
If Data.Rows.Count > 0 Then
Dim row As DataRow
row = Data.Rows(0)
'Set voucher properties in Voucher.vb using datarow result.
Voucher.VoucherID = row.Item("vID").ToString().Trim()
Voucher.VoucherName = row.Item("voucherName").ToString().Trim()
Voucher.ExpiryDate = row.Item("ExpiryDate")
Voucher.ValidUses = row.Item("ValidUses")
Voucher.CurrentUses = row.Item("CurrentUses")
Voucher.DiscountType = row.Item("DiscountType").ToString().Trim()
Voucher.AppliesTo = row.Item("AppliesTo").ToString().Trim()
Voucher.NumberOf = row.Item("NumberOf").ToString().Trim()
Voucher.Amount = row.Item("Amount")
Voucher.noOfItems = row.Item("NoOfItems")
Voucher.Category = row.Item("Category").ToString().Trim()
Voucher.FreebieID = row.Item("FreebieID").ToString().Trim()
Voucher.DiscountAmount = row.Item("DiscountAmount")
'lbVoucherCheck.Text = Data.ToString()
'Step one: Check for Expiry Date
Dim count As Int32
count = 0
Dim expiry As DateTime = Voucher.ExpiryDate
Dim today As DateTime = Date.Today()
count = ((expiry - today).Days)
If count <= -1 Then
txtVoucher.Text = "Voucher expired"
Else
txtVoucher.Text = "Expires in " + count.ToString() + " days."
End If
Else
txtVoucher.Text = Data.rows.count
End If
End Sub
When I run the query based off txtVoucher.Text input it returns "0", indicating that it hasn't found anything. But If I rig the query with a voucher name it returns the correct expiry result.
I have a strong feeling that it's not getting the right information from txtVoucher.text to my Voucher.CheckForVoucher(txtVoucher.text) function.
VB.NET 2012, ADO.NET, SQL Server 2014
I setup a parameterized query that works well. I essentially read records from a DataTable that comes from a different source than my SQL Server. It's small enough that I elected to read record by record and build a query and hit the SQL Server for a match.
However I am having trouble getting a match when one of my fields is supposed to be matched for a null. I know a record exist because I can look at it in SQL Server directly and see it. With my parameterized query somehow the null is being translated improperly. I tried manually replacing the parameter #EngSerialNo with DBNull.Value and still doesn't work. Almost seems like I need two different queries depending if my DataTable value is null.
sqQry.AppendLine("SELECT CityCode,CarNum,RegNum,Event,EngSerialNum)")
sqQry.AppendLine("FROM [MyDB].[dbo].[Events]")
sqQry.AppendLine("WHERE (CityCode=#City AND CarNum=#CarNo AND RegNum=#RegNo AND Event=#Event AND EngSerialNum=#EngSerialNo)") 'this looks for a value in EngSerialNo
'sqQry.AppendLine("WHERE (CityCode=#City AND CarNum=#CarNo AND RegNum=#RegNo AND Event=#Event AND EngSerialNum IS NULL)") 'this looks for a Null in EngSerialNo
Dim cmd As New SqlCommand
With cmd
.Connection = connMyDb
.CommandType = CommandType.Text
.CommandText = sqQry.ToString
'cycle through each DataRow in the DataTable and check for returns
Dim total As Integer = 0
For Each row As DataRow In dtMain.Rows
.Parameters.Clear()
.Parameters.AddWithValue("#City", row.Item("City"))
.Parameters.AddWithValue("#CarNo", row.Item("CarNo"))
.Parameters.AddWithValue("#RegNo", row.Item("RegNo"))
.Parameters.AddWithValue("#Event", row.Item("Event"))
.Parameters.AddWithValue("#EngSerialNo", row.Item("EngSerialNo")) 'how do I get this to look for a null value when the DataTable contains a null value?
Dim rowsAffected As Integer = .ExecuteNonQuery()
total += rowsAffected
Next row
End With
Update: I ended up creating a dynamic SQL for every DataRow. Basically for each DataRow I check key fields for NULL or an actual value and create the appropriate SQL command text. I have 4 fields that could contain a NULL but for sake of simplicity I only demonstrated one here. I think the developer can follow the example to create their own query.
Dim cmd As New SqlCommand
With cmd
.Connection = connMyDb
.CommandType = CommandType.Text
'cycle through each DataRow in the DataTable and check for returns
Dim total As Integer = 0
For Each row As DataRow In dtMain.Rows
.CommandText = BuildSql(row)
.Parameters.Clear()
.Parameters.AddWithValue("#City", row.Item("City"))
.Parameters.AddWithValue("#CarNo", row.Item("CarNo"))
.Parameters.AddWithValue("#RegNo", row.Item("RegNo"))
.Parameters.AddWithValue("#Event", row.Item("Event"))
.Parameters.AddWithValue("#EngSerialNo", row.Item("EngSerialNo"))
Dim rowsAffected As Integer = .ExecuteNonQuery()
total += rowsAffected
Next row
End With
Private Function BuildSql(ByVal dr As DataRow) As String
Dim sqQry As New StringBuilder
sqQry.AppendLine("SELECT CityCode,CarNum,RegNum,Event,EngSerialNum)")
sqQry.AppendLine("FROM [MyDB].[dbo].[Events]")
If dr.Item("EngSerialNo") Is DBNull.Value Then
sqQry.AppendLine("WHERE (CityCode=#City AND CarNum=#CarNo AND RegNum=#RegNo AND Event=#Event AND EngSerialNum IS NULL)") 'this looks for a Null in EngSerialNo
Else
sqQry.AppendLine("WHERE (CityCode=#City AND CarNum=#CarNo AND RegNum=#RegNo AND Event=#Event AND EngSerialNum=#EngSerialNo)") 'this looks for a value in EngSerialNo
End If
Return sqQry.ToString
End Function
In SQL you can't compare null values, i.e. EngSerialNum = null always evaluates to false, even if the value in the field is null.
Either you can create the query dynamically so that you use is null to match the null values, or you can use an expression like this:
((EngSerialNum is null and #EngSerialNo is null) or EngSerialNum = #EngSerialNo)
I get the Conversion from type 'DBNull' to type 'Integer' is not valid." error on the line "Dim avgObject As string = Cstr(avgCom.ExecuteScalar())
The command works when the where module_ID='" & moduleSelect & "' statement is removed and I do not know how to fix this, can anyone help?
Dim moduleSelect As String = moduleRadio.SelectedValue
Using connection As New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True")
Using avgCom As New SqlCommand("SELECT AVG(exam) FROM completed_module where module_ID='" & moduleSelect & "' ", _
connection)
connection.Open()
Dim avgObject As Integer = CInt(avgCom.ExecuteScalar())
Dim averageVar As String
averageVar = avgObject.ToString
avgLabel.Text = averageVar
End Using
I believe you are looking for something like this, first checking if it is dbnull:
Dim moduleSelect As String = moduleRadio.SelectedValue
Using connection As New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True")
Using avgCom As New SqlCommand("SELECT AVG(exam) FROM completed_module where module_ID='" & moduleSelect & "' ", _
connection)
connection.Open()
Dim result = avgCom.ExecuteScalar()
If IsDBNull(result) then return
Dim avgObject As Integer = CInt(result)
Dim averageVar As String
averageVar = avgObject.ToString
avgLabel.Text = averageVar
End Using
DBNull means that the record in the database does not contain a value for the column. So basically you are trying to convert "nothing" into a number.
What do you want your program to do? Skip the row? Use a default value instead?
If the command really "works" if you remove a statement from the command, I suggest you simply remove it.
Use Convert.ToString instead. Directcast as string does not work for Null/Nothing
UPDATE
Problem happens whenever you do not receive any results.
I tested, so CStr to Convert.ToString works for DBNUll, but CInt and Convert.ToIntXX still throws an eception.
You can use
Dim scalarResult = avgCom.ExecuteScalar()
If Convert.IsDBNull(scalarResult) then
avgObject = 0
Else
avgObject = Convert.toInt32(scalarResult)
End If
Error :Conversion from type 'DBNull' to type 'Integer' is not valid.
This error Occurs because your query return a NULL value.. you can manage the NULL value by using the Below code..
Try like below it will help you...
connection.Open()
Dim result As String = avgCom.ExecuteScalar().ToString()
Dim avgObject As Integer = If(result = "", 0, CInt(result))
Probably this fails because there is a value missing. (i.e. NULL)
But it might work if you default to 0 if a row with NULL was encountered:
SELECT AVG(ISNULL(exam,0)) FROM completed_module where module_ID=
Otherwise make sure your table does not include NULL-values for that column:
UPDATE completed_module SET exam = 0 WHERE exam IS NULL
(maybe constraint it so it may not have future NULL-Values also ;))
EDIT: this assumes that you can actually have an average value for every row, even those where the column you access is NULL, in that case i would assume NULL does not add anything to your average value (which the other rows that share that ID might) so I default it to 0
I have a SELECT statement for ListView and for ListBox even for DataGrid the only problem is that I can't display a result to my TextBox I just want to use:
The MAX() Function
I want to used MAX() because it says that it will return the larges value of the selected column, since I used INCREMENT to my ID MAX() Function is my one way to do it.
I used this codes to generate the ID:
Dim p1num As Integer = 0
p1num += 1
txtPNumber.Text = p1num.ToString("D4")
I try to understand your question and I think you should used this:
Try:
Dim querystring As String = "SELECT MAX(pIDNo) FROM (Name of your Table)"
Using connection As New SqlConnection("Data Source=(local);Initial Catalog=(Name of your DB);Persist Security Info=True;User ID=(Your User);Password=(Your Pass)")
Dim command As New SqlCommand(querystring, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader
Dim value = String.Empty
While reader.Read
value = reader.GetString(0)
End While
txtPNumber.Text = Today.Year.ToString().Substring(2, 2) & Today.Month.ToString().PadLeft(2, "0") & (Integer.Parse(value.Substring(4, value.Length - 4)) + 1).ToString("D4")
End Using
Catch ex As Exception
txtPNumber.Text = Today.Year.ToString().Substring(2, 2) & Today.Month.ToString().PadLeft(2, "0") & num.ToString("D4")
End Try
Try to make a Private Sub with it and used it to the Form Load if you want to display it after the program run or on button if you want a trigger to display the ID that you want.