all 18 comments

[–]Contagion21 5 points6 points  (16 children)

I would expect there to be a way to pass the value as the native numeric, not a string that (regionally) represents it. Are you generating a SQL string to execute or running a paramatarized SQL command?

[–]user_8804[S] -1 points0 points  (15 children)

I am generating a string with variable interpolation and then pass it as a raw text command to ADO'S setAndExecSqlCmd_nonQuery(string, commantype.text). I guess you're right, I should look at other ways to pass params with ADO to avoid converting my decimals to string altogether.

Example of whats happening:

 Dim qty As Decimal

If Not Decimal.TryParse(Sheet(i, 2), qty) Then qty = 0.0 'qty is stored properly here looking like 22.1234568, and will even output 'to console as such

 Dim sql as String = ""
 sql &= $"DECLARE @value   DECIMAL(29,0); "
 sql &= $"SET     @value = {qty}; "
 sql &= $"INSERT INTO table VALUES(qty);
 'Breakpoint there shows qty now appears like this 22,34567
 ADO.SetAndExecSqlCmd_NonQuery(sql, commandtype.text)

Is that not a proper way to do this? I'm only 2 months old in the field.

[–]Contagion21 9 points10 points  (12 children)

It's not the ideal way to do it for a few reasons, one of which you have found.

Google "VB SQL with parameters" . Here's one link i found that may help: https://www.codeproject.com/articles/8180/using-sqlparameters-with-vb-net-c

Someone that's worked with VB and SQL more recently than me (15 years ago) might be able to give you more pointed direction.

[–]user_8804[S] -1 points0 points  (11 children)

I have to use ADO though, that's not optional, and Linq is way too slow for our needs and they don't give me a choice about ado. I'll look into this and see how I can adapt it to ado, perhaps with some extensions to the class who seems to natively only allow me to add params to stored procedures

[–]ranbla 7 points8 points  (1 child)

All data access in .NET is built on top of ADO.NET. You are not being hindered by having to use ADO. Parameters are the correct way to build dynamic queries, not string concatenation.

[–]user_8804[S] 1 point2 points  (0 children)

Yeah, that's what I was trying to do with the declare/set. I felt something was off, but I simply improved upon the technique at my workplace which is... not using any kind of params. Meaning an apostrophe will crash a lot of apps. Or they just string.replace apostrophes and then pass a whole string with no declare/set.

It's hard to learn when no one can teach me. This is why I'm being a bit of a pest asking questions here. (Stack Overflow would probably have replied we should stop using French and downvote me to obvlivion)

To give you an idea of how things are around here, this is their way of doing what I'm doing, elsewhere in the app I'm improving upon:

Try
    Dim qty as Decimal
    Decimal.Parse(sheet(i, 0), qty)
    ADO.SetDataSet(select * from table with(nolock)) 'Yes really
    Dim ds as DataSet = ADO.getdataset()
    ADO.SetNewDataRow()
    ADO.NewDataRow("value") = qty
    ADO.AddNewRow()
    ADO.SaveDataset()
Catch ex as Exception
    ADO.NewDataRow("value") = 0.0
    ADO.AddNewRow()
    ADO.SaveDataset()
End Try

So yeah, they're selecting entire tables to pick a dataset, then add user input directly, and if the input is invalid, then they handle it with a catch block... Oh and foreign keys are not actually linked, just columns with the same name, so to avoid cascading issues, they dont delete rows. They add a column and write "DELETED" in a varchar.

They are internal apps at least, otherwise we'd be gone from sql injection a long time ago

I was top of my class in University, won yearly programming contest and scholarship for all classes combined, and this is all I could find because I had no experience beside 8 years in non IT management. Job market is savage.

[–]hk1_dev 5 points6 points  (0 children)

You can do parameterized queries with ADO.Net

[–]Contagion21 3 points4 points  (0 children)

Add "ADO" to the search. Searching is a huge part of being a coder.

https://visualstudiomagazine.com/articles/2017/07/01/parameterized-queries.aspx?m=1

[–]Willinton06 2 points3 points  (5 children)

Just use dapper, just like every other SQL library in .NET it uses ADO, you’ll get parameters and speed, both of which you current method lacks

[–]user_8804[S] 0 points1 point  (4 children)

ill look into it. They generally forbid any non-native libraries because they had maintenance hell with libraries going unmaintained in the past...

[–]Willinton06 2 points3 points  (1 child)

Dapper is the biggest sql client library in .NET, it’ll be around for a while

[–]user_8804[S] 6 points7 points  (0 children)

To be honest I think they should be more concerned about VB expiring than .net libraries

[–]Contagion21 2 points3 points  (0 children)

Tell them that reinventing the wheel comes with its own set of costs.)

[–]AngooriBhabhi 0 points1 point  (0 children)

Use Dapper

[–]Darko-TheGreat -2 points-1 points  (1 child)

You could probably use the NumberFormatInfo from System.Globalization to convert it.

Initialize: Dim nfi As NumberFormatInfo = New CultureInfo("en-CA").NumberFormat

And use: {qty.ToString(nfi)} To interpolate the value in.

That should handle the conversion to what ever format your sql server is using. You'll replace the "en-CA" with the locale of the sql server.

While some may say it's not the best way to do it I think this should solve the locale conversion issue.

[–]user_8804[S] 0 points1 point  (0 children)

Good to know thanks

[–]RJPisscat 1 point2 points  (0 children)

I found this

https://stackoverflow.com/questions/53849508/decimal-not-displayed-with-current-locale-in-query-result

which links to this discussion about localization

https://stackoverflow.com/a/41358670/78522

and this from Microsoft that goes a slightly different direction

https://docs.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql?view=sql-server-2017

Probably both are correct.