Problems with saving numbers after formatting example "200,000" - sql-server

I try to save data from TextBox1.Text value to a SQL Server database in column of type Decimal(18, 0). I use VB.NET and SQL Server database.
I format the data in the textbox value to number for example "200,000".
When I try to save, I get this error
Error converting nvarchar to numeric
I can't use Val(Textbox1.text) because he take only "200" not "200000"
How can I fix this?

18 precision 0 scale is essentially a Long, so you should use Long.Parse() or Long.TryParse() to get the real numeric value in VB. This will give you more control than the antiquated Val() over things like separator characters.
Then, in the SQL part, make sure you're using a parameterized query with the appropriate type for the parameter:
Dim data As Long = Long.Parse(Textbox1.Text)
Dim sql As String = "INSERT INTO [someTable] (column) VALUES (#parameter)"
Using con As New SqlConnection("connection string here")
Using cmd As New SqlCommand(sql, con)
cmd.Parameters.Add("#parameter", SqlDbType.Decimal, 18, 0).Value = data
con.Open()
cmd.ExecuteNonQuery()
End Using

Related

How to pass a date time value to SQL without a conversion error

I'm doing a windows form using Visual Basic.NET, SQL Server 2016, Visual Studio 2017.
I have been trying to fix this problem and already tried set dateformat mdy in SQL Server Management Studio query, but the dates on the table I have are still in this format: 2022-07-17 00:00:00.000. Does this have anything to do with this error when trying to insert something while running the project?
Everyone says stuff along the line "datetime doesn't work with yy/mm/dd or dd/mm/yy, use mm/dd/yy instead". But nobody says how you actually change/fix it in the database or Visual Studio.
I never found this error while using MySQL when I was studying and doing stuff on other languages, so this datetime thing is really getting desperate. Any insight on how to actually fix this error is greatly appreciated.
Code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim someid As Integer = TextCode.Text
Dim descri As String = TextDescription.Text
Dim somedate As DateTime = DateTimePickerinsert.Text
Dim value As String = TextValue.Text
Dim stock As String = TextStock.Text
Dim warehouse As String = ComboWarehouse.Text
con.Open()
Dim command As New SqlCommand("Insert into Item values('" & someid & "','" & descri & "','" & somedate & "','" & value & "','" & stock & "','" & warehouse & "')", con)
command.ExecuteNonQuery()
con.Close()
MessageBox.Show("Inserted succesfully")
LoadDataInGrid()
End Sub
I get
System.Data.SqlClient.SqlException: 'The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.' error on the line: command.ExecuteNonQuery()
You should use proper parameterization, keeping your dates as actual DateTime values, rather than strings, likewise for numbers. Otherwise you will get SQL injection problems, this is not just a security issue but also about correctness.
The parameter values should be cast to the correct type before you send them, and the parameter objects should be declared with the correct SqlDbType and precision/length also.
You should also create and dispose your connection object, rather than keeping a global connection open, which is wasteful. Automatic connection pooling will ensure efficient usage of available connections.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim query As String = "
INSERT INTO Item (someid, descri, somedate, value, stock, warehouse)
VALUES (#id, #description, #date, #value, #stock, #warehouse)
"
Dim someid As Integer = Integer.Parse(TextCode.Text)
Dim somedate As DateTime = DateTimePickerinsert.Value
Dim value As Decimal = Decimal.Parse(TextValue.Text)
Dim stock As Integer = Integer.Parse(TextStock.Text)
Using con As new SqlConnection("YourConnectionString"),
command As New SqlCommand(query, con)
command.Parameters.Add("#id", SqlDbType.Int).Value = someid
command.Parameters.Add("#description", SqlDbType.VarChar, 100).Value = If(TextDescription.Text, DBNull.Value)
command.Parameters.Add("#date", SqlDbType.DateTime).Value = somedate
command.Parameters.Add("#value", SqlDbType.Decimal).Value = value
command.Parameters.Add("#stock", SqlDbType.Int).Value = stock
command.Parameters.Add("#warehouse", SqlDbType.VarChar, 50).Value = If(ComboWarehouse.Text, DBNull.Value)
con.Open()
command.ExecuteNonQuery()
End Using
MessageBox.Show("Inserted succesfully")
LoadDataInGrid()
End Sub
As far as viewing the results in SSMS: datetime values don't have an inherent format. SSMS will have a default way of displaying them, but you can show them any way you like by converting them using CONVERT, or in VB using ToString
You are seriously entertaining SQL Injection using that Code.
You don't directly insert data to SQL database from your Windows Controls.
Use SQL Connection Parameters to house the values.
That way, any text in the incoming data will not be evaluated as a SQL Script but a text literal.
Hackers could assign SQL Script to your TextDescription.Text
like "Exec 'Delete From XXX '"
and it will be executed.
Dim descri As String = TextDescription.Text
Use SQL Connection Parameters to house the values.
You may run into many issues while using strings as dates. If you are connecting to a stored procedure or just executing SQL via SqlClient or ODBC, one way to fix this error is to use Cast in your SQL string to convert the date string to something that the server will understand. ex:
Insert Into MyTable (MyID, MyDate) Values (#MyID, Cast(#MyDate as datetime));
or,
Insert Into MyTable (MyID, MyDate) Values (123, Cast('2022-03-14 14:12:00' as datetime));
It will be more forgiving on different formats that you might use.

Keep SQL bit as 0/1 rather than boolean in vb.net command results

I have an ASP VB.NET app that acts as a go-between for an HTML client and a SQL Server database. SQL MSE shows the result set of bit columns as 0/1 as I would anticipate, but it seems that VB.NET converts them to boolean.
Private command As New SqlCommand
Private returnDataTable As New DataTable
Private adapter As New SqlDataAdapter
command = New SqlCommand("", Me.conn) With {
.CommandText = "",
.CommandType = CommandType.StoredProcedure
}
command.Parameters.AddWithValue("", )
adapter.SelectCommand = command
adapter.Fill(returnDataTable)
In this example, returnDataTable's rows contain booleans rather than byte or int or some numeric type when I JSON serialize it. I can simply send the boolean "False"/"True" to the client but would rather send 0/1 if possible, and without having to parse through the datatable to do so.
Is there a way to change this functionality?
As I have control over the queries, I could convert the bit columns to tinyint in the query and they are handled properly.

Why does this SQL search give this incompatibility error?

I'm having this error in my project when attempting to search using SQL for a specific name. When I type the name into a textbox and search.
This is the code used:
da = New SqlDataAdapter("select * From MovTable where NameOfMov = '" & NameSearchTB.Text & "'", sqlcon)
da.Fill(MovieSearchdt)
MovTable is the SQLDataTable
NameOfMov is the column I'm searching in.
This is the error appearing after attempting to search:
System.Data.SqlClient.SqlException: 'The data types ntext and varchar are incompatible in the equal to operator.'
The message is rather obvious. It has to with the table structure. The column NameOfMov seems to be ntext (Unicode text).
The name of a movie should fit in a varchar or nvarchar column so I doubt that ntext is a good choice here.
Some strategies are described here:
SQL SERVER – Fix: Error : 402 The data types ntext and varchar are incompatible in the equal to operator
Note that text/ntext are being deprecated:
IMPORTANT! ntext, text, and image data types will be removed in a future version of SQL Server. Avoid using these data types in new development work, and plan to modify applications that currently use them. Use nvarchar(max), varchar(max), and varbinary(max) instead.
Source: ntext, text, and image (Transact-SQL)
Another point repeated endlessly: always use parameterized queries. This code is unsafe (SQL injections) and will choke on characters like the single quote. This is not the way to do it in 2020.
If you cannot fix the datatype of field in your database as suggested by Anonymous in his answer then using parameters might work.
You should always use parameters to avoid Sql injection.
Private Function GetMovieData(NameToSearch As String) As DataTable
Dim dt As New DataTable
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand("select * From MovTable where NameOfMov = #Name;", cn)
cmd.Parameters.Add("#Name", SqlDbType.NText).Value = NameToSearch
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
Usage:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt = GetMovieData(NameSearchTB.Text)
DataGridView1.DataSource = dt
End Sub
This separates the User Interface code from the Data Access code. The button knows nothing about where the data is coming from and the GetMovieDate is not concerned with how or where the data is used.

Rich text box text with formatting does not save in SQL for VB.NET

I am working on vb form project in which i have RTB (rich text box),
I just want to save formatted text save into SQL also math type character.It saves but with out formatting and miss some math character?
here is my code
Dim sname As Integer = Integer.Parse(txt1.Text)
Dim sfname As Integer = 2
Dim scnic As String = rtb.SelectedText
query &= "INSERT INTO tencmpC1 (qnumber,topic,Umcq)"
query &= "VALUES (#qnumber, #topic,#Umcq )"
Using conn As New SqlConnection(strConn)
Using comm As New SqlCommand()
With comm
.Connection = conn
.CommandType = CommandType.Text
.CommandText = query
.Parameters.AddWithValue("#qnumber", sname)
.Parameters.AddWithValue("#topic", sfname)
.Parameters.AddWithValue("#Umcq", scnic)
conn.Open()
comm.ExecuteNonQuery()
txt10.Text = "question saved "
End With
End Using
here below is the code where i formated RTB
If FontDlg.ShowDialog() <> Windows.Forms.DialogResult.Cancel Then
rtb.SelectionFont = FontDlg.Font
Image below show result while in RTB at inserting time and in sql out when out from sql with out formating?
I am using nvarchar as datatype of UMCQ table of sql.
Also math character not supported.
The issue seems to be that you are saving rtb.SelectedText to the database rather than rtb.SelectedRtf. The SelectedText is a property which only ever returns the plain text. The SelectedRtf property is the one that returns the value containing all of the rich-text formatting.

XML Created in TSQL Used as ADODB.Recordset

I am attempting to use XML that was generated from a stored procesure in our MS SQL database as a Recordset in a VS2005 Application. The issue I am having is that when reading in the xml as a string, the string result comes in as "System.Byte[]". Seeing this I changed the datatype from String to Byte() and tried to use the Byte array. The Byte array does not seem to have anything to do with the data I want to be receiving. I am wondering if there is a way to handle SQL generated XML files that I am not aware of. Here is some sample code.
This is what the result of the stored procedure looks like when in SQL SMS
With this code I get the System.byte[] as my string:
Dim ADOrs As ADODB.Recordset
Dim SQLString1 As New System.Text.StringBuilder(180)
Dim catzzz as String
SQLString1.Append("exec reports_selectReportMetaData #companyCode = '001'")
ADOrs = fnReturnRecordset(SQLString1.ToString) 'function executes the query
Do While Not ADOrs.EOF
catzzz = ADOrs("XML_F52E2B61-18A1-11d1-B105-00805F49916B").Value.ToString
Debug.WriteLine(catzzz)
Loop
This is the way I get the really odd Byte Array
Dim ADOrs As ADODB.Recordset
Dim SQLString1 As New System.Text.StringBuilder(180)
Dim catzzz As Byte()
SQLString1.Append("exec reports_selectReportMetaData #companyCode = '001'")
ADOrs = fnReturnRecordset(SQLString1.ToString)'function executes the query
Do While Not ADOrs.EOF
catzzz = ADOrs("XML_F52E2B61-18A1-11d1-B105-00805F49916B").Value
Loop
The Byte array looks like
And when converted to ASCII using
catX = System.Text.Encoding.Default.GetString(catzzz)
the first three characters (that should be <rt ) Come up as
So I think my main issue is that I am missing the proper way to bring in the XML created in SQL
Any Ideas would be appricated!
Ended up changing from a stored procedure to a function so that we would be returend a value instead of just having the command executed. This solved the System.Byte[] issue.

Resources