Error: String not recognized as a valid boolean on a varchar? - asp.net

I have a gridview with a checkbox, that when selected inserts the selected items into two databases. The error occurs at a specific insert parameter that is a data type nvarchar. I'm not sure why it's giving me a boolean error. Any help would be greatly appreciated, I can post code if needed.

Okay, so let's get started. First, this has got to change from this:
sqlds1.UpdateCommand = String.Format(
"UPDATE Fees SET Inactive = '1' WHERE Description = '{0}'",
Request("cbusno"))
to this:
sqlds1.UpdateCommand = "UPDATE Fees SET Inactive = '1' WHERE Description = #Desc"
sqlds1.UpdateCommand.Parameters.AddWithValue("#Desc", Request("cbusno"))
Next, this has got to change from this:
sqlds2.UpdateCommand = String.Format(
"UPDATE OLLicenses SET lactive = '1' WHERE cbusno = '{0}'",
Request("cbusno"))
to this:
sqlds2.UpdateCommand = "UPDATE OLLicenses SET lactive = '1' WHERE cbusno = #no")
sqlds2.UpdateCommand.Parameters.AddWithValue("#no", Request("cbusno"))
Next, you'll want to use a different API here:
Sqldatasource1.Clear()
Sqldatasource1.InsertParameters.Add("cbusno", Request("cbusno"))
Sqldatasource1.InsertParameters.Add("licsubcategory", tb5.Text)
Sqldatasource1.InsertParameters.Add("description", tb5.Text)
Sqldatasource1.InsertParameters.Add("nfee", tb2.Text)
Sqldatasource1.InsertParameters.Add("lactive", "0")
Sqldatasource1.InsertParameters.Add("tadded", DateTime.Now.ToString())
Sqldatasource1.InsertParameters.Add("cuserid", Session("Username"))
Sqldatasource1.InsertParameters.Add("myfield", Request("myfield"))
Sqldatasource1.Insert()
This allows the data source to handle the typing for you.
Same as aforementioned with this block:
SqldatasourceFee.InsertParameters.Add("myfield", Request("myfield"))
SqldatasourceFee.InsertParameters.Add("Amount", tb2.Text)
SqldatasourceFee.InsertParameters.Add("CalculatorDescription", (string)clicnotxt.Table(0)(0))
SqldatasourceFee.InsertParameters.Add("Dept", "Business Tax")
SqldatasourceFee.InsertParameters.Add("Module", "Business Tax")
SqldatasourceFee.InsertParameters.Add("Type", tb4.Text)
SqldatasourceFee.InsertParameters.Add("SubType", tb5.Text)
SqldatasourceFee.InsertParameters.Add("Inactive", "0")
SqldatasourceFee.InsertParameters.Add("UserCreated", Session("Username"))
SqldatasourceFee.InsertParameters.Add("Description", Request("cbusno"))
SqldatasourceFee.Insert()
Now, take note to a couple of things. First, notice I casted this value to a string here (string)clicnotxt.Table(0)(0). That value was suspect to me, but I don't believe it's the source of your error. I think the issue here are stuff like this:
SqldatasourceFee.InsertParameters.Add("Inactive", "0")
I'm thinking, but can't be 100% sure, that it should be:
SqldatasourceFee.InsertParameters.Add("Inactive", "False")
Finally, when you build a SqlDataSource inline like this:
Dim sqlds1 As SqlDataSource = New SqlDataSource()
you need to wrap it in a Using because it implements IDisposable:
Using sqlds1 As SqlDataSource = New SqlDataSource()
sqlds1.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("myconnectionstring").ConnectionString
sqlds1.UpdateCommand = "UPDATE Fees SET Inactive = '1' WHERE Description = #Desc"
sqlds1.UpdateCommand.Parameters.AddWithValue("#Desc", Request("cbusno"))
End Using

Related

DataRow.IsNull() does not return return correctly vb.net

UPDATE:
Just looking at the debugger and it tells me that the row is not null.
I am using DataRow.IsNull method to check if the row is null. Now if the row is null, then I am required to put in a default string, otherwise return the value in the row.
However, this does not seem to be working as expected? Am I missing something?
Problem:
It only places a default string for some rows and not others.
I am not sure if I have understood this process correctly? Can anyone point me in the right direction.
Please note, a DataSet is return from the database and I loop through this for each row.
Code:
For i As Integer = 0 To ds.Tables(0).Rows.Count - 1
Dim row = ds.Tables(0).Rows(i)
Dim obj As Foo = New Foo
With
{.FooAccNum = If(row.IsNull("accnum"), "Not Set", row.Field(Of String)("accnum")),
.FooPartsNumber = If(row.IsNull("partsnumber"), "Not Set", row.Field(Of String)("partsnumber")),
.FooGroup = If(row.IsNull("group"), "", row.Field(Of String)("group")),
.FooCustomer = If(row.IsNull("customer"), "No record exists", row.Field(Of String)
("customer"))
FooList.Add(obj )
Next
DataSet Returned:
As you can see, customer column is empty.
View:
As you can see in my grid view however, it does not set some of the row value for customer to "No record exists". Why is this?
It could be the case that these values are not null but just empty strings - then they would appear the same on the UI but fail the IsNull check. Additional value check should help you deal with them:
.FooCustomer = If(row.IsNull("customer") Or String.IsNullOrWhiteSpace(row.Field(Of String)("customer")),
"No record exists",
row.Field(Of String)("customer")

Firebird insert...returning asp.net

I'm using Firebird 2.5 and asp.net (4.5).
I'm trying to find out how to use insert ... returning, or some equivalent.
Using fbDataReader, it executes the insert OK, but I can't find anyway of accessing a returned value. Using fbDataReader.GetName(0) seems to work ok, returning the variable name in the "returning" clause. This even applies to a max() in a subselect:
..... returning (select max(userid) as newid from users)
returns the text "newid".
I can't find where, or whether, the value is available.
Using a fbDataAdaptor to fill a DataTable, the insert works OK, but data table seems empty.
Does anyone know whether this is possible, and if so, how it's done?
Thanks
EDIT
Code supplied :
strConn = ....
dbConn = New FirebirdSql.Data.FirebirdClient.FbConnection(strConn)
dbConn.Open()
MySQL = "insert into users (Firstname, Lastname) VALUES (#fname,#lname) returning userid"
FbC = New FirebirdSql.Data.FirebirdClient.FbCommand(MySQL, dbConn)
FbC.Parameters.Add("fname", FirebirdSql.Data.FirebirdClient.FbDbType.Text).Value = "Pete"
FbC.Parameters.Add("lname", FirebirdSql.Data.FirebirdClient.FbDbType.Text).Value = "Davis"
FbDataReader = FbC.ExecuteReader()
FbDataReader.Read()
TextBox1.Text = FbDataReader.GetName(0)
'TextBox1.Text = str(FbDataReader.GetInt64())
'TextBox1.Text = FbDataReader.GetString(0)
TextBox1.Text = FbDataReader.GetValue(0)
According to this thread INSERT ... RETURNING ... behaves like output parameters for the Firebird .NET provider. So you will need to add an output parameter.
So something like the code below should work:
FbParameter outParam = new FbParam("userid", FbDbType.Integer)
{
Direction = ParameterDirection.Output
};
FbC.Parameters.Add(outParam);
FbC.ExecuteNonQuery();
int? userId = outParam.Value as int?;

SqlCommand slow when executing a query with parameters

DbDataAdapter.Fill() is extremly slow when performing parameters!
I have a query with 2 parameters inside, and when I put those parameters hardcoded in the query it takes 1 second to execute (in a 470k table rows, returning only 20 rows).
I found many posts similars here and I tried all those solutions (set arithabort, option recompile, option optimize for, ...) with no luck.
I just perform a query (sql server 2008) and not a stored procedure, so the query with arithabort is like this:
string strSql = #"set ARITHABORT ON;
select TOP 20 ....
Also I tried to call set arithabort in the same transaction but performing that query first..
I don't know if I'm doing something wrong, but the sensation is the ado.net is performing a very bad execution plan in ado.net when I have defined parameters on it.
As a result of this bad choice, the execution time in SSMS is 1 second (after being cached) but in asp is like 9 seconds!
The query is something like this:
strSQL #="
select *
from Table1
where Name like #name";
And then:
DbProviderFactory factory = DbProviderFactories.GetFactory(mProvider);
DbCommand dbcmd = factory.CreateCommand();
if (CommandTimeout != null)
dbcmd.CommandTimeout = CommandTimeout.Value;
if(this.transaccion != null)
dbcmd.Transaction = this.transaccion;
dbcmd.Connection = dbc;
dbcmd.CommandText = strSQL;
if (parametros != null)
dbcmd.Parameters.AddRange(parametros);
DbDataAdapter dbda = factory.CreateDataAdapter();
dbda.SelectCommand = dbcmd;
DataTable dt = new DataTable();
dbda.Fill(dt);
return dt;
EDIT 14/01/2013 (18:44)
I'm not longer retrieve the connection from DbProviderFactory, insted I'm using directly SqlConnection and SqlCommand. I know DbCommand and DbProvider are a base clase... but I think there is something more in there.. because the performance drasticaly increase like 300%!
It's not the fill method, because I already tried in the code shown before..
Anyway, I don't know the reason why but using a SqlConnection is much faster! Any idea? Maybe isn't making that bad execution plan made before?
SqlCommand objCmd = new SqlCommand(strSQL, sqlConn);
if (CommandTimeout != null)
objCmd.CommandTimeout = CommandTimeout.Value;
if (this.transaccion != null)
objCmd.Transaction = SQLtransaccion;
if (parametros != null)
objCmd.Parameters.AddRange(parametros);
DbDataReader dbReader = objCmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dbReader);
dbReader.Close();
return dt;
Any help will be greatly appreciated,
Thanks,
I found the solution!
It was parameters!
I was using a wrong type in the the List!
Parametross.Add(bd.MakeParameter("#val", "%" + txtFind.Text + "%",
DbType.String));
DbType.String vs. DbType.AnsiString
Although both DbType.String and DbType.AnsiString deal with character data, these datatypes are processed differently, and using the wrong data type can have a negative effect on the application’s performance. DbType.String identifies the parameter as a 2-byte Unicode value and is sent to the server as such.DbType.AnsiString causes the parameter to be sent as a multibyte character string. To avoid excessive string conversions, use:
DbType.AnsiString for char or varchar columns and parameters.
DbType.String for unichar and univarchar columns and parameters.
Source:
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc20066.0115/html/adonet/adonet49.htm
In my query there is a:
....
where Table.Col1 like #val
But the column type was varchar and I should use DbType.AnsiString, instead of DbType.String
Parametross.Add(bd.MakeParameter("#val", "%" + txtFind.Text + "%",
DbType.AnsiString));
In my huge table I was making a lot of unnecesary casts and this is the reason why the performance drastically fall down!
Hope this will help someone,

Database result is passed as null unless it's read

Set rslistings = my_conn.Execute(strSQL)
Do while NOT rslistings.Eof
description = strip(rslistings("description"))
rslistings.MoveNext
loop
In strip - NULL is being passed. However, if I attach a debugger and inspect the contents of rslistings("description"), then the actual Field object is passed through
It's quite old asp code, but it works on IIS6, just not IIS7
EDIT This only happens on the "description" field with is a text type (MySQL database)
strip doesn't do a lot:
If NOT IsNull(passedinvalue) Then
// do something
Else
// do something else
If I call strip like strip(rs("description")), it is never null as the Field object is passed in. If I assign it to another value, then pass it in (like strip(mynewvar)) then the correct value is passed in.
Edit - database bits as requested below
Set my_conn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
my_conn.Open "DSN=mydb"
SQL
Set rs = my_conn.Execute("SELECT description FROM table")
the Field Collection is the default member of the Recordset object.
so is the value property for the Field object.
so the following two code statements are equivalent.
Debug.Print objRs.Fields.Item(0) ' Both statements print
Debug.Print objRs(0) ' the Value of Item(0).
it is a difference if you assign a value to a variable or use it as a parameter in a function.
#Paul: If strip doesn't check if description is NULL before working on it, you could do this --
Do while NOT rslistings.Eof
description = rslistings("description")
If NOT IsNull(description) Then
description = strip(description)
Else
description = "" ' or you could have description = " "
' if you output to screen later on
End If
rslistings.MoveNext
loop

Having problems with sqlDataReader

I am using a sqlDataReader to get data and set it to session variables. The problem is it doesn't want to work with expressions. I can reference any other column in the table, but not the expressions. The SQL does work. The code is below. Thanks in advance, Anthony
Using myConnectionCheck As New SqlConnection(myConnectionString)
Dim myCommandCheck As New SqlCommand()
myCommandCheck.Connection = myConnectionCheck
myCommandCheck.CommandText = "SELECT Projects.Pro_Ver, Projects.Pro_Name, Projects.TL_Num, Projects.LP_Num, Projects.Dev_Num, Projects.Val_Num, Projects.Completed, Flow.Initiate_Date, Flow.Requirements, Flow.Req_Date, Flow.Dev_Review, Flow.Dev_Review_Date, Flow.Interface, Flow.Interface_Date, Flow.Approval, Flow.Approval_Date, Flow.Test_Plan, Flow.Test_Plan_Date, Flow.Dev_Start, Flow.Dev_Start_Date, Flow.Val_Start, Flow.Val_Start_Date, Flow.Val_Complete, Flow.Val_Complete_Date, Flow.Stage_Production, Flow.Stage_Production_Date, Flow.MKS, Flow.MKS_Date, Flow.DIET, Flow.DIET_Date, Flow.Closed, Flow.Closed_Date, Flow.Dev_End, Flow.Dev_End_Date, Users_1.Email AS Expr1, Users_2.Email AS Expr2, Users_3.Email AS Expr3, Users_4.Email AS Expr4, Users_4.FNAME, Users_3.FNAME AS Expr5, Users_2.FNAME AS Expr6, Users_1.FNAME AS Expr7 FROM Projects INNER JOIN Users AS Users_1 ON Projects.TL_Num = Users_1.PIN INNER JOIN Users AS Users_2 ON Projects.LP_Num = Users_2.PIN INNER JOIN Users AS Users_3 ON Projects.Dev_Num = Users_3.PIN INNER JOIN Users AS Users_4 ON Projects.Val_Num = Users_4.PIN INNER JOIN Flow ON Projects.id = Flow.Flow_Pro_Num WHERE id = "
myCommandCheck.CommandText += QSid
myConnectionCheck.Open()
myCommandCheck.ExecuteNonQuery()
Dim count As Int16 = myCommandCheck.ExecuteScalar
If count = 1 Then
Dim myDataReader As SqlDataReader
myDataReader = myCommandCheck.ExecuteReader()
While myDataReader.Read()
Session("TL_email") = myDataReader("Expr1").ToString()
Session("PE_email") = myDataReader("Expr2").ToString()
Session("DEV_email") = myDataReader("Expr3").ToString()
Session("VAL_email") = myDataReader("Expr4").ToString()
Session("Project_Name") = myDataReader("Pro_Name").ToString()
End While
myDataReader.Close()
End If
End Using
This may be because column names need to be unique for the SqlDataReader to be able to index them using a string name for the column.
A couple of things:
1) You are executing the query 3 times. You can lose the ExecuteNonQuery and ExecuteScalar calls, and replace the while loop with "if myDataReader.Read() / end if" to get the data values for the first resulting record. If no records are found, no session variables are set, just as in your current code.
2) It looks more like the problem lies in your session management (ie getting values from Session) rather than your sql query, which looks OK to me.
Check:
that you have sessionState enabled in your web.config file,
that you don't reset the Session values anywhere, and
that you ask for the same Session field name when you are trying to send the email. (e.g. are you setting Session("DEV_Email") but asking for Session("DEV Email") (space instead of underscore) ?
Sorry everyone. The code works just fine. The sqlDataReader WILL accept expressions as column names.
The reason I was getting an error saying the value of the from and to parameters cannot be null. There was no data in that column for any of the records in my table.

Resources