Assign null value to a decimal field in SQL - sql

I want to assign null value in a field in SQL 2014 which has a data type, decimal. I tried to use theses codes but I didn't get the way I wanted (providing that other fieldnames and values are present.)
query = "INSERT INTO DBNAME.TLTRPRGP(DECIMALVAL) VALUES(#DECIMALVAL)"
params = New String() {"BLGSCD"}
values = New String() {Nothing}
SaveUpdateDelete(query, params, values)
query = "INSERT INTO DBNAME.TLTRPRGP(DECIMALVAL) VALUES(#DECIMALVAL)"
params = New String() {"BLGSCD"}
values = New String() {DbNull.Value}
SaveUpdateDelete(query, params, values)
query = "INSERT INTO DBNAME.TLTRPRGP(DECIMALVAL) VALUES(#DECIMALVAL)"
params = New String() {"BLGSCD"}
values = New String() {VbNull}
SaveUpdateDelete(query, params, values)
Private Sub SaveUpdateDelete(ByVal sql As String, ByVal parameters() As String, ByVal Values() As String)
If con.State = ConnectionState.Open Then
con.Close()
End If
con.Open()
Dim command As New SqlCommand
command = New SqlCommand(sql, con)
For i = 0 To parameters.Count - 1
command.Parameters.AddWithValue("#" & parameters(i).ToString, Values(i))
Next
command.CommandText = sql
command.ExecuteNonQuery()
con.Close()
End Sub
The first code returns 0. The second returns syntax error saying "Value System.DbNull.Value cannot be converted to String". The third code returns 1. All these codes failed to return the right value which is suppose to be NULL or EMPTY. What else is there to try?

the issue is with the datatype of the values: you constrain it to be a string but there are values that cannot be converted to strings (eg: DBNull.Value).
the solution is to use the generic object as the datatype for the parameters passed to the function SaveUpdateDelete.

Related

Is there a way to run a for loop query based on datagridview selected values in vb.net?

Unable to get the excepted result due to the following error
Conversion from string " to type 'integer' is not valid'
I have been able to load values from the products table, add selected ones to Selected Products and then search all the selected products against the Customers table to find out how many customers ordered these products.
Try
Dim ListOfDiag As StringBuilder = New StringBuilder()
For Each row As DataGridViewRow In SelectedDiagDGV.Rows
ListOfDiag.Append(row.Cells(0).Value.ToString & "", "" & Environment.NewLine)
Next
Dim query As String = String.Empty
Dim SegmentConnectionString As String = "Data Source=Test-PC;Initial Catalog=TestDB;Integrated Security=True"
query = "SELECT Customers, ProductName from Customers WHERE ProductName in (" & ListOfDiag.ToString & ")"
Dim dTable As DataTable = New DataTable()
Dim dAdapter As SqlDataAdapter
dAdapter = New SqlDataAdapter(query, SegmentConnectionString)
dAdapter.Fill(dTable)
DataGridView1.DataSource = dTable
'Next
Catch ex As System. Exception
MsgBox(ex.Message.ToString)
End Try
Unable to perform a for loop search. Some of the values contain special characters example: Soft ’Drink’; Computer (Desk).
Error: Conversion from string " to type 'Integer' is not valid.
ListOfDiag.Append(row.Cells(0).Value.ToString & "", "" & Environment.NewLine)
There is no overload of StringBuilder.Append that takes (String, String) as arguments. the first string is row.Cells(0).Value.ToString & "" and then there is a comma between parameters and the second string is "" & Environment.NewLine Remember that "" is an empty string, not escape characters. Not sure what your intention was but this will not work.
You had the right approach; to build a string for the In clause. I used a List(Of String) to get the data from the rows then after the loop I used a .Join with a comma separator to get the value for the In clause.
I passed the connection string directly to the constructor of the Connection and passed the Select statement and the connection to the constructor of the Command. For the Select statement I used and Interpolated String (the string preceded by the $) You could also use String.Format in older version of Visual Studio.
The Using...End Using blocks ensure that your database objects are closed and disposed even if there is an error.
I think the only special character that could mess things up would be the presence of a comma in a Product Name.
Private Sub OPCode()
Dim dTable As New DataTable
Dim ListOfDiag As New List(Of String)
For Each row As DataGridViewRow In SelectedDiagDGV.Rows
ListOfDiag.Add(row.Cells(0).Value.ToString)
Next
Dim InData = String.Join(",", ListOfDiag)
Using cn As New SqlConnection("Data Source=Test-PC;Initial Catalog=TestDB;Integrated Security=True")
Using cmd As New SqlCommand($"SELECT Customers, ProductName from Customers WHERE ProductName in ({InData})", cn)
cn.Open()
dTable.Load(cmd.ExecuteReader)
End Using
End Using
DataGridView1.DataSource = dTable
End Sub

Select max value in MS Access database

I need to select the max value in my row column. When I hit line
(FindCurrentTimeCard = Val(myreader("Row"))
I get an error:
System.IndexOutOfRangeException
Code:
Public Function FindCurrentTimeCard() As Integer
Dim myconnection As OleDbConnection = New OleDbConnection
Dim query As String = "Select MAX(Row) from Table2"
Dim dbsource As String =("Provider=Microsoft.ACE.OLEDB.12.0;DataSource=S:\Docs\PRODUCTION\Shop Manager\Shop_Manager\Shop_Manager\Database2.accdb;")
Dim conn = New OleDbConnection(dbsource)
Dim cmd As New OleDbCommand(query, conn)
Try
conn.Open()
Dim myreader As OleDbDataReader = cmd.ExecuteReader()
myreader.Read()
FindCurrentTimeCard = Val(myreader("Row"))
conn.Close()
Catch ex As OleDbException
MessageBox.Show("Error Pull Data from Table2")
FindCurrentTimeCard = 1
End Try
End Function
Table2
The issue is that when you evaluate an aggregate function (or indeed, any expression performing some operation on a field or fields), the result of such evaluation will be assigned an alias (such as Expr1000) unless an alias is otherwise stated.
Hence, when you evaluate the SQL statement:
select max(table2.row) from table2
MS Access will return the result assigned to an alias such as Expr1000:
Hence, the SQL statement does not output a column named Row, causing your code to fail when attempting to retrieve the value of such column:
FindCurrentTimeCard = Val(myreader("Row"))
Instead, you should specify an alias to which you may refer in your code, e.g.:
select max(table2.row) as maxofrow from table2
With your function then returning the value associated with such column:
FindCurrentTimeCard = Val(myreader("maxofrow"))
Comments and explanations in-line
Public Function FindCurrentTimeCard() As Integer
Dim CurrentTimeCard As Integer
'The Using block ensures that your database objects are closed and disposed
'even it there is an error
'Pass the connection string directly to the connection constructor
Using myconnection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;DataSource=S:\Docs\PRODUCTION\Shop Manager\Shop_Manager\Shop_Manager\Database2.accdb;")
Dim query As String = "Select MAX(Row) from Table2"
Using cmd As New OleDbCommand(query, myconnection)
Try
myconnection.Open()
'since you are only retrieving a single value
'you can used .ExecuteScalar which gets the value
'in the first row, first column
CurrentTimeCard = CInt(cmd.ExecuteScalar)
Catch ex As OleDbException
MessageBox.Show("Error Pull Data from Table2")
End Try
End Using
End Using
'vb.net uses the Return statement to return the value of the function
Return CurrentTimeCard
End Function

SQL injection method for select statement

I want to get same values form my database therefore I'm using this query:
SELECT NormalComputers
FROM usb_compliance
WHERE ATC = 'CMB'
ORDER BY date DESC
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY
Using this I want to get so many values so I plan to use SQL injection method please help me how to create this
If I can use injection method I can use function it should be like this
Private Function query(ByVal values As String, ByVal atc As String, ByVal no As Integer)
Dim connetionString As String
Dim connection As SqlConnection
Dim command As SqlCommand
Dim sql As String
connetionString = "Server=CTV-WEBDEVEXG;Database=usb;Trusted_Connection=True;"
sql = "SELECT #values FROM usb_compliance WHERE ATC=#atc ORDER BY date DESC OFFSET #no ROWS FETCH NEXT 1 ROWS ONLY"
connection = New SqlConnection(connetionString)
Try
command = New SqlCommand(sql, connection)
With command
.Connection.Open()
MsgBox("done !!!")
.CommandType = CommandType.Text
.Parameters.Add("#values", SqlDbType.DateTime).Value = values
.Parameters.Add("#atc", SqlDbType.NVarChar).Value = atc
.Parameters.Add("#NormalComputers", SqlDbType.Int).Value = no
End With
command.ExecuteNonQuery()
command.Dispose()
connection.Close()
Catch ex As Exception
End Try
Return sql
End Function
I have tried this way but its not working so please help me on this
parameter #values refers to the name of the field you want to retrieve. So it owes to be a string not a DateTime (despite the fact that this filed datatype might be DateTime).
...
.Parameters.Add("#values", SqlDbType.NVarChar).Value = values
...
to get rows affected:
Dim numRows as Integer
...
..
numRows=command.ExecuteNonQuery()

Value of type 'Integer' cannot be converted to 'System.Data.OleDb.OleDbDataReader'. vb.net

i'm trying to read the last invoice number and display it in a textbox.....
Assume that, Table name is "MyTable" , Column name is "InvoiceNumber" and it is AutoNumber, So it is Integers!
Here's my code:
Dim query As String = "SELECT MAX(InvoiceNumber) FROM MyTable"
Dim cmd As New OleDb.OleDbCommand
Dim reading As OleDb.OleDbDataReader
cmd.CommandText = query
cmd.Connection = conn
reading = Convert.ToInt32(cmd.ExecuteScalar())
If reading.Read Then
TextBox1.Text = reading.Item("InvoiceNumber").ToString
End If
Erorr is on "reading = Convert.ToInt32(cmd.ExecuteScalar())" because my Value is of type 'Integer' cannot be converted to 'System.Data.OleDb.OleDbDataReader'.
Any help ... ?
The variable reading is a OleDbDataReader which can't be used to assign an integer, that's the reason for the error. But you don't need a DataReader anyway if you use ExecuteScalar:
Dim maxNumber As Int32 = Convert.ToInt32(cmd.ExecuteScalar())
TextBox1.Text = maxNumber.ToString

A simple VB.net SQL data query that is not returning any records

I am trying to debug my code, which involves a simple webservice that passes parameters to a data class, which calls a stored proc, and returns one row of record. I am not getting any error messages, but I am not getting any records back either.
My webservice code is:
<WebMethod()> _
Public Function GetDataValues(ByVal AutoVIN As String, ByVal OrderID As String, ByVal StatusCode As String, ByVal DivisionID As String) As String
Dim oGetHeaderValue As New clsGetHeaderValue
Dim GetHeaderValues As String = ""
Dim strAutoVIN = Trim(AutoVIN)
Dim strOrderID = Trim(OrderID)
Dim strStatusCode = Trim(StatusCode)
Dim strDivisionID = Trim(DivisionID)
Try
'Validate user entries if they are the correct length;
If Not IsNumeric(strAutoVIN) Or Len(Trim(strAutoVIN)) <> 3 Then
Throw New SoapException("Invalid Auto VI Number", SoapException.ClientFaultCode)
End If
'OrderID could be 12 digits in length
If Not IsNumeric(strOrderID) Then
Throw New SoapException("Invalid Order ID", SoapException.ClientFaultCode)
End If
'************************Verify if the order exists "Order Number not in requested status" in table Auto.orderHeader
'************************Validate entries against db table;
'Call Stored Proc and pass parameters;
Dim retDataSet As Data.DataSet
retDataSet = oGetHeaderValue.GetHeaderValue(strAutoVIN, strOrderID, strStatusCode, strDivisionID)
GetHeaderValues = retDataSet.ToString()
Return GetHeaderValues
Catch ex As Exception
Return "<ERR>" & ex.Message.ToString & "</ERR>"
End Try
End Function
My database class code is:
Public Function GetGetHeaderValue(ByVal sAutoVIN As String, ByVal sOrderID As String, ByVal sStatusCode As String, ByVal sDivisionID As String) As DataSet
Dim sqlDA As New SqlDataAdapter
Dim ds As New DataSet
Dim sqlcmd As New SqlCommand
Dim conn As New SqlConnection(strCN_Auto)
sqlDA = New SqlDataAdapter("uspExportOrders", conn)
sqlDA.SelectCommand.CommandType = CommandType.StoredProcedure
sqlDA.SelectCommand.Parameters.Add(New SqlParameter("#AutoVIN", SqlDbType.VarChar, 3))
sqlDA.SelectCommand.Parameters("#AutoVIN").Value = sAutoVIN
sqlDA.SelectCommand.Parameters.Add(New SqlParameter("#OrderID", SqlDbType.VarChar, 12))
sqlDA.SelectCommand.Parameters("#OrderID").Value = sOrderID
sqlDA.SelectCommand.Parameters.Add(New SqlParameter("#StatusCode", SqlDbType.VarChar, 10))
sqlDA.SelectCommand.Parameters("#StatusCode").Value = sStatusCode
sqlDA.SelectCommand.Parameters.Add(New SqlParameter("#DivisionID", SqlDbType.VarChar, 3))
sqlDA.SelectCommand.Parameters("#DivisionID").Value = sDivisionID
sqlDA.Fill(ds) 'Fill the DataSet with the rows returned.
Return ds
sqlDA.Dispose()
conn.Close()
End Function
I'm basing this on the assumption that your stored procedure only returns a single string value. I don't think your problem is in your procedure not returning any data.
Change the following:
GetHeaderValues = retDataSet.ToString()
to
Dim dr As DataRow
dr = retDataSet.Tables(0).Rows(0)
GetHeaderValues = dr(0).ToString()
Here's why. If all you want out of this procedure in your database is a single string, you don't have to return and entire dataset, but that's OK. The dataset is a little more complicated than just getting the string value out of it. It can contain many tables (which is why it is normally used) and could allow you to change the data (which you are not doing). You may want to research using the command's .ExecuteScalar. I've assumed yours has only one, so you can refer to it as .Table(0) or you could replace the zero with the name of the table (Which you don't have.). In each table, there are rows and columns. Again only one row and one column so we can reference them as row(0) and column(0).