Single Quote in LINQ Results Causing Error - asp.net

I have the following LINQ query:
Dim find_id = From p In dbContext.Residents _
Where p.person_name = occupant _
Select p
I then pull the first returned ID like so:
Dim building_id As String = find_building_id.FirstOrDefault.id
This works fine, except with the person has a ' in their last name, like M'arta. In this case I get a NullReferenceException. Any thoughts on how I can get around this issue?
Okay, the problem appears to be that when I am capturing the name initially from a GridView it is inserting into the value a #39 instead of ' and then LINQ is keeping things correct, so I end up with a non-match since it is attempting to match:
M#38arta = M'arta

Maybe it's an Unicode issue? I once had trouble with wrong settings of the 'Unicode' attribute of scalar string properties. Maybe your SQL connection string has defined a wrong charset? And are your sure it's a single quote and no kind of accent or a special char, looking similiar but with another code?
Just my spontanious ideas at night.

Related

SQLite REAL error

I am having some trouble with SQLite. I used to save "time" as an int, but i now want it as a double, which is causing some problems. I remake my database everytime i try a new fix, but it has no effect. Whenever i try to save, it get the error "4 values for 3 columns". when i change it all back to an int, it works fine again. Also, if i just remove "time all togeater from the saving process, i get the error "2 values for 3 columns". I have no clue what is going on. Does a real take up two values or whats the deal?
Creating the table:
sql = "CREATE TABLE Speed (id INTEGER PRIMARY KEY AUTOINCREMENT, LanguageType VARCHAR(20), cardsetNumber INT, time REAL)";
command = new SQLiteCommand(sql, dbConnection);
command.ExecuteNonQuery();
Adding to the table:
public void SaveSpeed(int cardsetNumber, LanguageType lt, double time)
{
Open();
sql = "insert into Speed (cardsetNumber, LanguageType, time) values (" + cardsetNumber + ", '" + lt + "', " + time + ")";
command = new SQLiteCommand(sql, dbConnection);
command.ExecuteNonQuery();
Close();
}
According to Wikipedia, Denmark uses a comma as a decimal separator. Most probably, the default culture of your process is the Danish one that imposes exactly that decimal separator when converting decimal numbers to strings.
You are doing two things that you shouldn't be doing in your code, though in this case, changing one will fix the problem:
You convert a value to a string based on a culture that is not the invariant culture for any other purpose than displaying it to the user.
You are constructing an SQL query with custom values by concatenating the values unescaped into the query string.
The first means that code that does not expect to read locale-specific number formats will simply interpret your string differently than intended. In particular, that is true when reading the string on another machine (that has another default locale set), but in this case, it is simply because the SQL parser does never expect any locale-specific number formats (and, as the comma serves as the argument separator, the syntax would actually stop being well-defined unless the parser would add any further locale-specific amendments).
The second can cause really bad trouble, so you are best served by always avoiding it.
So, what is happening here? With that locale-specific conversion, the time number is converted to something like 1,2, which is interpreted by the SQL parser as two integer numbers (separated with a comma), not as one decimal number. Hence the error message about the argument count.
The first problem could be solved by explicitly specifying the invariant culture for string conversions when the result is targeted at programs rather than humans. Always do that when you, or someone else, intends to read the value back into a number type, for example, when storing it in a text-based format for computers such as CSV or XML.
As for the second issue, to insert any custom (literal) values into your SQL query, (especially, but not exclusively, those that are not hard-coded somewhere but received from user-input), parametrize your query string:
sql = "insert into Speed (cardsetNumber, LanguageType, time) values (#cardsetNumber, #lt, #time)";
command = new SQLiteCommand(sql, dbConnection);
command.Parameters.AddWithValue("#cardsetNumber", cardsetNumber);
command.Parameters.AddWithValue("#lt", lt);
command.Parameters.AddWithValue("#time", time);
This will automatically insert any quotation or escape marks to the literal values, and there is no risk of intentional or accidental SQL injection.

Using Date parameter in SQL query, ASP.net

I am writing a code that calls a column from a dataset using a SQL query. I use two parameters to identify which rows to select. One is the ProductSerialNumber, and the other is a datetimestamp. See my SQL query below
Select TestStation FROM tblData
WHERE ProductSerialNumber = ? AND Datetimestamp = ?
In the dataset's datatable the productserialnumber is formatted as text, and the other is formatted as a date (as you would expect).
In my vb.net code, I grab the Datetimestamp from another source (don't ask why, the only thing you need to know is that it grabs a valid datetimestamp, dimensioned as a date, that matches exactly with the tblData's entry) and I use the premade query to generate a datatable. The query is a Fill query called "TestStationLookUp"
my vb.net code looks like this
Dim dt as new dataset.tbldataDataTable
Dim dta As New DataSetTableAdapters.tbldataTableAdapter
Dim ProductSerialNumber as string = "XXXXXX"
Dim DateTimeStamp as date = SomeDateVariable
dta.TestStationLookUp(dt, ProductSerialNumber, DateTimeStamp)
It is here that the code tells me:
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
Line 7366: dataTable.Clear
Line 7367: End If
Error: Line 7368: Dim returnValue As Integer = Me.Adapter.Fill(dataTable)
Line 7369: Return returnValue
Line 7370: End Function
I cannot understand why this error arises, as everything is dimensioned the way it should be. This exact code setup works elsewhere in my code (except it doesn't use a date), but this specific piece won't work.
Also, if I go to the dataset in my solution, I can use the "preview data" on this query and type in the EXACT same parameters (the ProductSerialNumber and DateTimeStamp that match the record in the table AND what I use in my vb code) and it will give me produce the table I want.
Can anyone assist?
This error means that you are trying to access not valid unique id "ProductSerialNumber", maybe it does not exist
Failed to enable constraints. One or more rows contain values
violating non-null, unique, or foreign-key constraints.
Instead of passing the variable that comes from dataset ,pass a valid number that you are sure it exists in database

LINQ-to-SQL Query Returning No Results

I have a query using LINQ-to-SQL. It queries an underlying database table Rooms. It uses Where conditions to narrow down the results, namely:
Gender.
Current Occupancy < Max Occupancy
Available Flag is Checked
I know this should return results but it keeps returning an empty set. Any ideas? Code is below
Dim selectedHalls = (From sh In dbHalls.Rooms _
Where sh.gender = Session("gender").ToString _
Where sh.max_occupancy > sh.current_occupancy _
Where sh.is_available = 1 _
Select sh.building_name).Distinct()
UPDATE: I've verified that the issue is with the statement where sh.is_available = 1, which doesn't make sense since this is a bit field.
I think the best way to find out what the problem is to generate the SQL string and test your assumption that "it should return results" by executing it directly against the data source.
To do this:
Dim sqlQuery As String = dbHalls.GetCommand(
(From sh In dbHalls.Rooms _
Where sh.gender = Session("gender").ToString _
Where sh.max_occupancy > sh.current_occupancy _
Where sh.is_available = 1 _
Select sh.building_name).Distinct()
).CommandText
(I usually use C#, but I think that's how you declare a string in VB, right?)
Anyway, this will give you an SQL statement that will be more informative than anything we can give you without being able to look at your underlying database.
The only thing that jumps out at me as being potentially problematic is the Session("gender"). You are basically relying on your Session object to be populated, have a value for the case-sensitive string key "gender" that matches the case-sensitive string field gender in your database. This sounds like quite a few assumptions, that may or may not be tested and could be the reason for receiving empty results.
EDIT
I just saw your update. Linq-to-sql, interprets a bit field as a boolean value, not an integer value. Try changing it to just where sh.is_available
I don't see anything obviously wrong with your LINQ, so try removing the Where clauses and bringing them back one at a time. That should let you know what's causing the issue, though I agree with Andrew Vogel that the gender clause is a likely suspect.
If the query comes back empty after all the Where clauses are gone, then you'll know there's something else going on here.
Do you really record their genders as "Female" and "Male" in dbHalls.Rooms.sh?

Converting Decimal In a Label to an Integer

Currently using VS2008, VB.NET, SQL.
I have a FormView from a Data Source that is getting some fields that are stored as Decimals in the SQL Database.
I am grabbing the field from the FormView as such:
Dim AvgTicketL As Label = CType(frmMerchantProfile.FindControl("F10Label"), Label)
I need to take this value, and convert it to an Integer, then send it along to an API. I have the API Calls done, tested and working, but I'm getting an error as when it is getting this value, the API is returning "Must be an Integer" error.
What I have tried so far:
Dim AvgTicketL As Label = CType(frmMerchantProfile.FindControl("F10Label"), Label)
Dim AvgTicket1 As Integer
AvgTicket1 = Double.Parse(AvgTicket.Text)
Do something with AvgTicket1
I have also attempted to Round the Value, then convert it and call it - no luck.
Checking the value of AvgTicket1 (Writing it out to a Label or Response.Write) shows "100", where the database value was 100.00. But the API is still getting 100.00, apparently. Any other conversion method that I've attempted states errors that the Label cannot be converted to Integer.
What are some methods I can successfully convert this value to an integer from a label?
The title of your question and the text of your question point to two different things.
Assuming you want to know how to safely convert the decimal value retrieved from the database, which is presumably the value of AvgTicketL, before calling your API you would do the following:
Create a variable of datatype Integer and use System.Int32.TryParse() to safely convert the decimal to an integer. Then pass that variable. (Code coming)
Dim testInt as Integer = -1
If System.Int32.TryParse(AvgTicketL.Text, testInt) Then
' Do something with testInt - call the API using the value
Else
' code to execute if the parse fails.
' This could be whatever you need the code to do if the value of AvgTicketL.Text can't be properly parsed into an Int value.
End If
After some fooling around this is what I was able to do to get this to work...
I took some of what David had said, and then just made a simple adjustment - I don't know why I hadn't thought of it earlier!
Dim AvgTicketL As Label = CType(frmMerchantProfile.FindControl("F10Label"), Label)
Dim AvgTicketI As Integer = "-1"
I dimmed a second variable as an int, then
AvgTicketI = CInt(AvgTicketL.Text)
From there, I just called AvgTicketI as the variable to pass to the API. Worked!
Thanks, David, for the guidance!

Constructing a good search query using system.data.oracleclient

I am constructing a search function in a class to be used by several of our asp pages. The idea is simple, take a search term from the user and query the database for the item. Currently I am doing this the wrong way, which is vulnerable to SQL injection attacks (and ELMAH is in there to save the day if something goes wrong):
Public Shared Function SearchByName(ByVal searchterm As String) As DataTable
SearchByName = New DataTable
Dim con As New OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings("OracleDB").ConnectionString)
Try
con.Open()
Dim SqlStr As String = "select ID_ELEMENT, ELEMENT_NAME from table_of_elements where upper(ELEMENT_NAME) like upper('%" & searchterm & "%')"
Dim cmd As New OracleCommand(SqlStr, con)
SearchByName.Load(cmd.ExecuteReader)
Catch ex As Exception
Elmah.ErrorSignal.FromCurrentContext().Raise(ex)
End Try
con.Close()
con.Dispose()
Return SearchByName
End Function
String concatenation is BAD. Next thing you know, Bobby Tables wrecks my system.
Now, the correct way to do this is to to make a proper oracle variable, by putting :searchterm in the string and adding the following line:
cmd.Parameters.Add(New OracleParameter("SEARCHTERM", searchterm))
The problem is since I am using a like statement, I need to be able to have % on either side of the search word, and I can't seem to do that with '%:searchterm%', it just gives an error of ORA-01036: illegal variable name/number.
Can I parameterize but still have my flexible like statement be a part of it?
Instead of doing the concatenation in your VB code, do the concatenation in the SQL statement. Then what you're trying to do should work. Here's some SQL illustrating what I'm talking about:
select ID_ELEMENT, ELEMENT_NAME
from table_of_elements
where upper(ELEMENT_NAME) like ('%' || upper(:searchterm) || '%')
BTW, you might end up with more efficient queries if you switch the collation on ELEMENT_NAME to case-insensitive and then remove the calls to upper().
Since you're using oracle, another option would be to use Oracle Text to perform the search.
It can take a bit to set up properly, but if you have a large amount of text to search, or have some sort of structured data, it can offer you many more options than a simple wild-card comparison.
It also has some nice features for dealing with multiple languages, if you happen to have that problem as well.

Resources