I used the following statement for a parameter.
.Parameters("#SearchValue").Value = TextBoxParentID.Text
for this query:
objSqlCommand.CommandText = "Select ID " & _
"From Parents " & _
"Where ID = #SearchValue"
ID is a SQL server numeric column but I get this error:
error converting nvarchar to numeric
Can you show me the coding needed fix this?
At this point you are trying to assign value which is of type string and the parameter is bound as string (nvarchar). You need to convert it at first.
' Let's suppose that this is a value from your textbox
Dim strNumber As String = "12"
' Prepare a placeholder to convert your string value into integer
Dim myInteger As Integer
' Try to convert
If Int32.TryParse(strNumber, myInteger) Then
'If the conversion is successful
Dim myConnection As New SqlConnection("Your ConnectionString")
Dim myCommand As New SqlCommand("INSERT INTO Foo(Bar) VALUES (#Bar", myConnection)
'Use this syntax to assign values to parameters
myCommand.Parameters.AddWithValue("Bar", myInteger)
End If
This snippet also uses AddWithValue method. I suggest you to use this approach.
Related
I want to count the number of PPM orders this month and every month, And this is my code but when I run I get an error
Incorrect syntax near '#'
I need to know generally how to select depending on date, I hate working with date, help me please. Thanks
Dim dtp0 As New DateTimePicker
Dim dtp1 = dtp0.Value
Dim count_m As Integer
Dim cmd1 As New SqlCommand("SELECT count ([id]) FROM [machines] where ppm1 = #" & dtp1.Day & "/" & dtp1.Month & "/" & dtp1.Year & " # and [takhen] is NULL and [irga] is NULL", connsql)
Dim da1 As New SqlDataAdapter(cmd1)
Dim dt1 As New DataTable
da1.Fill(dt1)
If dt1.Rows.Count > 0 Then
connsql.Open()
count_m = Convert.ToInt32(cmd1.ExecuteScalar())
connsql.Close()
Label68.Text = count_m.ToString
End If
I'll provide advice on how to properly use string concatenation to insert a date into SQL code, given that that is the specific question you're asking, but you should absolutely NOT do that. You should ALWAYS use parameters to insert ANY values into SQL code. Here is my own writeup on that.
As for this specific issue, you need to use the correct date format and there's a much easier way to do that than inserting day, month and year separately, e.g.
Dim sql = $"SELECT * FROM MyTable WHERE DateColumn = #{myDTP.Value:M/dd/yyyy}#"
That is using string interpolation, which is the most correct option in the last couple of VB versions. If you're using an older version then you can use String.Format:
Dim sql = String.Format("SELECT * FROM MyTable WHERE DateColumn = #{0:M/dd/yyyy}#", myDTP.Value)
If you wanted to do it wrong then you could use concatenation operators:
Dim sql = "SELECT * FROM MyTable WHERE DateColumn = #" & myDTP.Value.ToString("M/dd/yyyy") & "#"
Simply using parameters to pass a DateTime value will avoid problems with the date string literal and provide many other benefits too.
Code example:
Dim dtp0 As New DateTimePicker
Dim dtp1 = dtp0.Value
Dim count_m As Integer
Dim cmd1 As New SqlCommand("SELECT count ([id]) FROM [machines] where ppm1 = #ppm1 and [takhen] is NULL and [irga] is NULL;", connsql)
Dim param1 As SqlParameter = cmd1.Parameters.Add("#ppm1", SqlDbType.Date)
param1.Value = New DateTime(dtp1.Year, dtp1.Month, dtp1.Day)
Dim da1 As New SqlDataAdapter(cmd1)
Dim dt1 As New DataTable
da1.Fill(dt1)
If dt1.Rows.Count > 0 Then
connsql.Open()
count_m = Convert.ToInt32(cmd1.ExecuteScalar())
connsql.Close()
Label68.Text = count_m.ToString
End If
I am creating a simple spreadsheet which takes an array of IDs from worksheet "input", queries an Oracle database asking for only the records which match the IDs in the array and outputs the results to worksheet "output".
So far, my VBA will work if my array only contains a single ID (by specifying a single cell range), and everything completes with the desired output from the Oracle database appearing in worksheet "output". Good times.
The problem I am having now is that I want to specify a range of IDs (anything up to around 5000) in worksheet "input" to include in my array and pass that array to the Oracle database to return data for each ID it finds (I am not expecting all IDs to exist). Whenever I try this I seem to get "Error 13 Type Mismatch" errors... Bad times.
My VBA code is:
Dim OracleConnection As ADODB.Connection
Dim MosaicRecordSet As ADODB.RecordSet
Dim SQLQuery As String
Dim DBConnect As String
Dim count As String
Dim strbody As String
Dim Exclude As String
Dim i As Integer
Dim Rec As RecordSet
Dim InputIDs As Variant
Set OracleConnection = New ADODB.Connection
DBConnect = "Provider=msdaora;Data Source=MOSREP;User ID=***;Password=***;"
OracleConnection.Open DBConnect
' Clear Output Sheet Down
Sheets("Output").Select
Range("A2:F10000").Clear
' Set Input Range
Sheets("Input").Columns("A:A").NumberFormat = "0"
InputIDs = Sheets("Input").Range("A2:A10").Value
' SQL Query
SQLQuery = "select DMP.PERSON_ID, DMP.FULL_NAME, DMP.DATE_OF_BIRTH, DMA.ADDRESS, DMA.ADDRESS_TYPE, DMA.IS_DISPLAY_ADDRESS " & _
"from DM_PERSONS DMP " & _
"join DM_ADDRESSES DMA " & _
"on DMA.PERSON_ID=DMP.PERSON_ID " & _
"where DMP.PERSON_ID in (" & InputIDs & ")"
Set MosaicRecordSet = OracleConnection.Execute(SQLQuery)
Sheets("Output").Range("A2").CopyFromRecordset MosaicRecordSet
' Change DOB Format
Sheets("Output").Columns("C:C").NumberFormat = "dd/mm/yyyy"
' Set Left Alignment
Sheets("Output").Columns("A:Z").HorizontalAlignment = xlHAlignLeft
Range("A1").Select
OracleConnection.Close
Set MosaicRecordSet = Nothing
Set OracleConnection = Nothing
ActiveWorkbook.Save
Can anyone shed light on what I am missing? I have attempted to resolve the Type Mismatch issue by setting the 'numberformat' on the column in worksheet "input" to "0" but that didn't help. I also thought that I might have to have a loop to iterate through each record, but I haven't got to that stage yet because of this Type Mismatch thing...
Thank you everyone for your help in advance!
Regards
Matt
The ID's need to be comma delimited
InputIDs = getIDs( Sheets("Input").Range("A2:A10") )
Function getIDs(rng As Range)
Dim c As Range
Dim s As String
For Each c In rng
s = s & c.Value & ","
Next
getIDs = Left(s, Len(s) - 1)
End Function
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.
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 want to take the values from textboxes on a windows form and then update the values in the sql server database...I want to update only those fields for which a value has been entered by the user and leave the fields for which the textboxes are left empty by the user.....How can I generate the query dynamically for such a situation???
Edit:
I haven't yet coded for the update option...Here is my insertion code and i wanted to implement the update feature the same way just couldn't figure out how i can generate the query dynamically....It's a Booking System application
Dim str As String ' defines str as a string variable
'takes insertion query as a string in str variable
str = "Insert into Bookings Values(#cust_id, #cust_name,#contact, #game, #courtno, #poolno, #tableno, #booking_date, #booking_time, #booking_duration)"
'defines a new command which takes query string and connection string as parameters
Dim cmd As New SqlCommand(str, con)
' defines Customer ID parameter and takes its value from the form
Dim prmCustID As New SqlParameter("#cust_id", SqlDbType.Char)
prmCustID.Value = MskdTxtCustId.Text
' defines Customer Name parameter and takes its value from the form
Dim prmCustName As New SqlParameter("#cust_name", SqlDbType.Char)
prmCustName.Value = TxtCustName.Text
' defines Contact parameter and takes its value from the form
Dim prmContact As New SqlParameter("#contact", SqlDbType.VarChar)
prmContact.Value = MskdTxtCntctno.Text
' defines Game parameter and takes its value from the form
Dim prmGame As New SqlParameter("#game", SqlDbType.Char)
prmGame.Value = TxtGame.Text
' defines Court No parameter and takes its value from the form
Dim prmCrtNo As New SqlParameter("#courtno", SqlDbType.Int)
If TxtCrtNo.Text = "" Then
prmCrtNo.Value = Convert.DBNull 'If the textbox is empty then places Null in databse field
Else
prmCrtNo.Value = CType(TxtCrtNo.Text, Integer) ' converts from string to integer
End If
' defines Pool No parameter and takes its value from the form
Dim prmPoolNo As New SqlParameter("#poolno", SqlDbType.Int)
If TxtPoolNo.Text = "" Then
prmPoolNo.Value = Convert.DBNull 'If the textbox is empty then places Null in databse field
Else
prmPoolNo.Value = CType(TxtPoolNo.Text, Integer) ' converts from string to integer
End If
' defines Table No parameter and takes its value from the form
Dim prmTblNo As New SqlParameter("#tableno", SqlDbType.Int)
If TxtTblNo.Text = "" Then
prmTblNo.Value = Convert.DBNull 'If the textbox is empty then places Null in databse field
Else
prmTblNo.Value = CType(TxtTblNo.Text, Integer) ' converts from string to integer
End If
' defines Booking Date parameter and takes its value from the form
Dim prmBookDate As New SqlParameter("#booking_date", SqlDbType.DateTime)
prmBookDate.Value = TxtBookDate.Text
' defines Booking Time parameter and takes its value from the form
Dim prmBookTime As New SqlParameter("#booking_time", SqlDbType.DateTime)
prmBookTime.Value = TxtBookTime.Text
' defines Booking Duration parameter and takes its value from the form
Dim prmBookDur As New SqlParameter("#booking_duration", SqlDbType.Int)
prmBookDur.Value = CType(TxtBookDur.Text, Integer)
'Command cmd takes all the parameters
cmd.Parameters.Add(prmCustID)
cmd.Parameters.Add(prmCustName)
cmd.Parameters.Add(prmContact)
cmd.Parameters.Add(prmGame)
cmd.Parameters.Add(prmCrtNo)
cmd.Parameters.Add(prmBookDate)
cmd.Parameters.Add(prmBookTime)
cmd.Parameters.Add(prmBookDur)
cmd.Parameters.Add(prmPoolNo)
cmd.Parameters.Add(prmTblNo)
Dim str1 As String ' defines string variable for taking select query
str1 = "select bookingID from Bookings" 'takes select query in string variable for retrieving booking ID from the databse
Dim cmd1 As New SqlCommand(str1, con) 'defines a new command which takes query string and connection string as parameters
Dim x As Integer ' defines an integer for storing booking ID
con.Open() 'sets the connection state to open
Using (con) 'specifies the connection which is to be used by the SQLcommands
cmd.ExecuteNonQuery() 'Executes the insertion query
Dim id As SqlDataReader = cmd1.ExecuteReader() 'Defines and initiates the datareader to read data from database using cmd1 command
While id.Read() 'Iterates the reader to read booking id
x = id("bookingID") 'stores the booking Id in variable x
End While
id.Close()
End Using
con.Close() 'sets the connection state to close
' shows message box with successful booking message
MessageBox.Show("New booking saved successfully" & vbCrLf & "Your Booking ID is " & x, "Saved Successfully", MessageBoxButtons.OKCancel, MessageBoxIcon.Information)
this is a very broad question and highly dependend on what type of data-access framework your are going to use.
You could go low-level and use SqlCommand (if you use MsSql) or OdbcCommand to wrap up all with a SQL Update statement, with setters only for the fields you changed.
You could do dataset/datatable/dataadapter, load the row change only the fields you changed and update the table again.
You could do the same with LingToSql or EF.
If you want details please tell us what you tried and what you want to use.