Take a column and convert value to int - asp.net

public int AuthenticatedUserAge(String User_name)
{
string sql = "SELECT UserName,Age FROM tblDataProg WHERE (UserName ='" + User_name + "')";
ds = GetDataSet(sql);
int help = int.Parse(ds.Tables[0].Rows[0]["Age"].ToString());
return help;
}
I can't figure why this line doesn't convert the age to type int and return a value:
int help = int.Parse(ds.Tables[0].Rows[0]["Age"].ToString());

Completely offtopic to the question, but I think it's worth mentioning. Please don't create your SQL statements by concatenating strings. This creates SQL Injection attack possibility. Instead consider SqlParameter class and compose your WHERE predicates using such parameters.
Here you get nice example (look especially at convenient AddWithValue method).
Thanks!

Test your assumptions more. You are assuming GetDataSet is returning a row but it possibly isn't: -
int help = 0;
if (ds.Tables[0].Rows.Count == 0)
{
throw new ApplicationException("no rows were returned, here is an error to deal with");
}
else if (ds.Tables[0].Rows[0]["Age"] == System.DbNull.Value)
{
throw new ApplicationException("a row was found but Age is null, here is an error to deal with");
}
else
{
help = int.Parse(ds.Tables[0].Rows[0]["Age"].ToString());
}

try
int help;
int.TryParse(Convert.ToString(ds.Tables[0].Rows[0]["Age"]),out help);
and see the code in debug mode

Related

How can I perform SQL Count with ESP32 SQLite3?

I have spent ages searching for an answer to this, but i can't quite get my head around it.
Basically.I have a sqlite db on a sd card connected to a esp32. SQLite works perfectly and will return when using the standard sample code. For example:
rc = db_exec(db2, "Select * from domain_rank where domain between 'google.com' and 'google.com.z'");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
sqlite3_close(db2);
return;
}`
this looks at a "db_exec" function in the sketch then passes it to a "callback" function. Is there a way to do without this? All I want to do is count the number of records in a select statement.
Thanks
Andrew
Ok I think I may have found a solution
Putting it here just in case anyone else is interested.
String sql = "Select count(*) from surnames where name = 'MICHELLE'";
rc = sqlite3_prepare_v2(db1, sql.c_str(), 1000, &res, &tail);
if (rc != SQLITE_OK) {
String resp = "Failed to fetch data: ";
Serial.println(resp.c_str());
return;
}
while (sqlite3_step(res) == SQLITE_ROW) {
rec_count = sqlite3_column_int(res, 0);
}
Serial.println(rec_count);
can't quite get my head around what the while loop is doing counting the cells, i thought the sql count* query would just return an int value I could use directly. So I'm still a little confused.
Comments would be welcomed! If anyone has any better ideas?
Thanks
Andrew

SQLite via JDBC: SQLITE_BUSY when inserting after selecting

I'm getting the error code SQLITE_BUSY when trying to write to a table after selecting from it. The select statement and result is properly closed prior to my insert.
If I'm removing the select part the insert works fine. And this is what I'm not getting. According to the documentation SQLITE_BUSY should mean that a different process or connection (which is definetly not the case here) is blocking the database.
There's no SQLite manager running. Also jdbcConn is the only connection to the database I have. No parallel running threads aswell.
Here's my code:
try {
if(!jdbcConn.isClosed()) {
ArrayList<String> variablesToAdd = new ArrayList<String>();
String sql = "SELECT * FROM VARIABLES WHERE Name = ?";
try (PreparedStatement stmt = jdbcConn.prepareStatement(sql)) {
for(InVariable variable : this.variables.values()) {
stmt.setString(1, variable.getName());
try(ResultSet rs = stmt.executeQuery()) {
if(!rs.next()) {
variablesToAdd.add(variable.getName());
}
}
}
}
if(variablesToAdd.size() > 0) {
String sqlInsert = "INSERT INTO VARIABLES(Name, Var_Value) VALUES(?, '')";
try(PreparedStatement stmtInsert = jdbcConn.prepareStatement(sqlInsert)) {
for(String name : variablesToAdd) {
stmtInsert.setString(1, name);
int affectedRows = stmtInsert.executeUpdate();
if(affectedRows == 0) {
LogManager.getLogger().error("Error while trying to add missing database variable '" + name + "'.");
}
}
}
jdbcConn.commit();
}
}
}
catch(Exception e) {
LogManager.getLogger().error("Error creating potentially missing database variables.", e);
}
This crashes on int affectedRows = stmtInsert.executeUpdate();. Now if I remove the first block (and manually add a value to the variablesToAdd list) the value inserts fine into the database.
Am I missing something? Am I not closing the ResultSet and PreparedStatement properly? Maybe I'm blind to my mistake from looking at it for too long.
Edit: Also executing the select in a separate thread does the trick. But that can't be the solution. Am I trying to insert into the database too fast after closing previous statements?
Edit2: I came across a busy_timeout, which promised to make updates/queries wait for a specified amount of time before returning with SQLITE_BUSY. I tried setting the busy timeout like so:
if(jdbcConn.prepareStatement("PRAGMA busy_timeout = 30000").execute()) {
jdbcConn.commit();
}
The executeUpdate() function still immedeiately returns with SQLITE_BUSY.
I'm dumb.
I was so thrown off by the fact that removing the select statement worked (still not sure why that worked, probably bad timing) that I missed a different thread using the same file.
Made both threads use the same java.sql.Connection and everything works fine now.
Thank you for pushing me in the right direction #GordThompson. Wasn't aware of the jdbc:sqlite::memory: option which led to me finding the issue.

asp.net RowFilter comparing string with int

Im having an issue with this , Im new to asp.net and really dont have much understanding with their syntax, I do understand the error but have no idea how to implement a fix:
ProductTable.RowFilter = "ProductID ='" & ddlCategory.SelectedValue & "'"
The error im recieving is : cannot perform '=' operation on system.int32 and system.string data view
my productID data type is : int;
Now i dont see how im comparing a string vs int, ddlCatergory selected index would also return a value... besides the point...im completely stuck.
any help is appreciated.
Using windows 8, VS 2012 , SQL database.
ddlCategory.SelectedValue is likely to be string given the SelectedValue attribute of the drop down list is a string, you are also assigning it as a string e.g. the filter value could end up being something like "ProductID ='123'" where 123 is the SelectedValue.
Assuming that SelectedValue is never null or empty I would use something like:
ProductTable.RowFilter = string.format("ProductID = {0}", ddlCategory.SelectedValue);
If it could be empty then I would do something along these lines:
if(string.IsNullOrEmpty(ddlCategory.SelectedValue))
{
ProductTable.RowFilter ="";
}
else {
ProductTable.RowFilter = string.format("ProductID = {0}", ddlCategory.SelectedValue);
}
OR
int tempInt;
if(int.TryParse(ddlCategory.SelectedValue,out tempInt))
{
ProductTable.RowFilter = string.format("ProductID = {0}", tempInt);
}
I've written the above in C# (not syntax checked though sorry!) though it would be easy enough to convert it to VB if necessary.
You should try by removing single quotes after = sign, so it give something like this
ProductTable.RowFilter = "ProductID = " + ddlCategory.SelectedValue

SQL always returning same results

I'm trying to do a search on a table in my database where it returns the top 50 rows with a firstname like the search term being passed to the function, but its always returning the same 50 results
My sql looks like this:
Select TOP(50) *
FROM [database].[dbo].[records]
WHERE (A_1STNAME LIKE '" + #searchTerm + "%')
ORDER BY A_RECID
When I run this query in Visual Studios query window, it works as expected but when I run it through my ASP.NET application, it always returns the same 50 results, and only one of them has a first name close to the searchTerm I passed to it.
here is the page code that runs the function:
protected void Page_Load(object sender, EventArgs e)
{
_migrated_data data = new _migrated_data();
DataSet ds = data.Search(Request.QueryString.Get("query"), "A_RECID", 50);
if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
rpt_Data.DataSource = ds.Tables[0].DefaultView;
rpt_Data.DataBind();
}
}
and here is the search method of _migrated_data:
public DataSet Search(String #pSearchTerm, String #pSortBy, int #pRowCount)
{
DataSet ds = new DataSet();
OleDbConnection objOleDBConn;
OleDbDataAdapter objOleDBDa;
objOleDBConn = new OleDbConnection(ClearingHouse_OLEDDB);
objOleDBConn.Open();
string lSQL = "SELECT TOP(50) * FROM [database].[dbo].[records]";
lSQL += " WHERE (A_1STNAME LIKE #searchTerm ) ORDER BY #sortBy";
SqlCommand t = new SqlCommand(lSQL);
if (pSearchTerm != null && pSearchTerm != "")
{
t.Parameters.AddWithValue("#searchTerm", #pSearchTerm + "%");
}
if (pSortBy != null && pSortBy != "")
{
t.Parameters.AddWithValue("#sortBy", #pSortBy);
}
else
{
t.Parameters.AddWithValue("#sortBy", "A_RECID");
}
objOleDBDa = new OleDbDataAdapter(t.CommandText, objOleDBConn);
objOleDBDa.SelectCommand.CommandType = CommandType.Text;
objOleDBDa.Fill(ds);
objOleDBConn.Close();
return ds;
}
Using locals to view the final CommandText of t, I get the sql results I gave above.
Any help is greatly appriciated :)
AS Rob Rodi said, first of all, to get the results begining with a value you will need % char at the end of the therm:
Select TOP(50) *
FROM [database].[dbo].[records]
WHERE (A_1STNAME LIKE '" + #searchTerm + "%')
ORDER BY A_RECID
Second, probably your searchTerm is empty, so it's grabbing always the same results.
Debug your app and watch the variable to see if it's receiving some value.
You are having SQL injection there. Also it looks like the %-signs are missing.
The fact, that the query works in a query window and not in your app means, that the error is not in your query! Did you think about that? Probably, you should post code of your ASP.NET app.
It sounds like your parameter isn't being correctly passed to your data layer. Easiest way to find out if that's the case is to turn on Sql Profiler and check to see if it's being passed. If it is, your sql's to blame. If it's not, it's your application. You can then use the debugger on your application to work your way up the stack to see where the problem lies.

Filehelpers ExcelStorage.ExtractRecords fails when first cell is empty

When the first cell of an excel sheet to import using ExcelStorage.ExtractRecords is empty, the process fail. Ie. If the data starts at col 1, row 2, if the cell (2,1) has an empty value, the method fails.
Does anybody know how to work-around this? I've tried adding a FieldNullValue attribute to the mapping class with no luck.
Here is a sample project that show the code with problems
Hope somebody can help me or point in some direction.
Thank you!
It looks like you have stumbled upon an issue in FileHelpers.
What is happening is that the ExcelStorage.ExtractRecords method uses an empty cell check to see if it has reached the end of the sheet. This can be seen in the ExcelStorage.cs source code:
while (CellAsString(cRow, mStartColumn) != String.Empty)
{
try
{
recordNumber++;
Notify(mNotifyHandler, mProgressMode, recordNumber, -1);
colValues = RowValues(cRow, mStartColumn, RecordFieldCount);
object record = ValuesToRecord(colValues);
res.Add(record);
}
catch (Exception ex)
{
// Code removed for this example
}
}
So if the start column of any row is empty then it assumes that the file is done.
Some options to get around this:
Don't put any empty cells in the first column position.
Don't use excel as your file format -- convert to CSV first.
See if you can get a patch from the developer or patch the source yourself.
The first two are workarounds (and not really good ones). The third option might be the best but what is the end of file condition? Probably an entire row that is empty would be a good enough check (but even that might not work in all cases all of the time).
Thanks to the help of Tuzo, I could figure out a way of working this around.
I added a method to ExcelStorage class to change the while end condition. Instead of looking at the first cell for empty value, I look at all cells in the current row to be empty. If that's the case, return false to the while. This is the change to the while part of ExtractRecords:
while (!IsEof(cRow, mStartColumn, RecordFieldCount))
instead of
while (CellAsString(cRow, mStartColumn) != String.Empty)
IsEof is a method to check the whole row to be empty:
private bool IsEof(int row, int startCol, int numberOfCols)
{
bool isEmpty = true;
string cellValue = string.Empty;
for (int i = startCol; i <= numberOfCols; i++)
{
cellValue = CellAsString(row, i);
if (cellValue != string.Empty)
{
isEmpty = false;
break;
}
}
return isEmpty;
}
Of course if the user leaves an empty row between two data rows the rows after that one will not be processed, but I think is a good thing to keep working on this.
Thanks
I needed to be able to skip blank lines, so I've added the following code to the FileHelpers library. I've taken Sebastian's IsEof code and renamed the method to IsRowEmpty and changed the loop in ExtractRecords from ...
while (CellAsString(cRow, mStartColumn) != String.Empty)
to ...
while (!IsRowEmpty(cRow, mStartColumn, RecordFieldCount) || !IsRowEmpty(cRow+1, mStartColumn, RecordFieldCount))
I then changed this ...
colValues = RowValues(cRow, mStartColumn, RecordFieldCount);
object record = ValuesToRecord(colValues);
res.Add(record);
to this ...
bool addRow = true;
if (Attribute.GetCustomAttribute(RecordType, typeof(IgnoreEmptyLinesAttribute)) != null && IsRowEmpty(cRow, mStartColumn, RecordFieldCount))
{
addRow = false;
}
if (addRow)
{
colValues = RowValues(cRow, mStartColumn, RecordFieldCount);
object record = ValuesToRecord(colValues);
res.Add(record);
}
What this gives me is the ability to skip single empty rows. The file will be read until two successive empty rows are found

Resources