I'm trying to execute a query in C# which sums the view count of a user. I get returned a NULL value. Using the same statement in Server Management Studio gives me the correct result.
here's my code:
public static int Count_views(string username)
{
int views = 0;
StringBuilder query = new StringBuilder();
query.Append("SELECT Sum(views) FROM videos WHERE username = #username");
using (SqlConnection con = new SqlConnection(Config.ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand(query.ToString(), con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("#username", username));
views = Convert.ToInt32(cmd.ExecuteScalar());
}
}
return views;
}
I have debugged the code and the parameters are correct. I get this error :
System.InvalidCastException: Object cannot be cast from DBNull to other types.
which means I'm getting a Null value in return.
The ConnectionString is alright. Every other function works fine except for this one. can anyone tell me what might me the issue here?
Edit:
Below are the screen shots of what I'm encountering. The first screenshot shows the value "Administrator" is being passed inside the function. the second screenshot shows this value is also in the database.
You can change the SUM query to return 0 instead of NULL:
query.Append("SELECT COALESCE(Sum(views),0) FROM videos WHERE username = #username");
You could also use the as operator to cast it to the desired nullable type:
int? views = cmd.ExecuteScalar() as int?;
Related
When I use this code below, I get a -1 returned from line
cmd.ExecuteNonQuery()
It may have something to do with InvalidCastException.
When we run this stored procedure manually in SSMS, it produces a SQL script in its output which we then copy and paste in a new window and run that to get what we want.
Any ideas of why it's not working from C#?
I knew the connection to the server is good.
using (SqlCommand cmd = new SqlCommand("dbo.sp_SSISCloneConfiguration", sqlConnection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#project", SqlDbType.VarChar).Value = projectName;
cmd.Parameters.Add("#destinationProject", SqlDbType.VarChar).Value = projectName;
cmd.ExecuteNonQuery();
}
Because ExecuteNonQuery() returns "The number of rows affected."
If you're expecting data as a result, you probably meant to use ExecuteReader() which returns "A SqlDataReader object", or perhaps ExecuteScalar() which returns "The first column of the first row in the result set, or a null reference if the result set is empty."
For example:
var result = cmd.ExecuteScalar();
Note that the type of result is object. So if "it produces a sql script in its output" then you would probably need to convert it to a string, for example:
var result = cmd.ExecuteScalar()?.ToString();
Note the ? operator being used, because ExecuteScalar() could return null.
I'm trying to return all rows of a single column in my database to populate a list. When I execute the stored procedure in SQL, it works fine, but nothing gets returned when I try to do it in C#.
public static List<string> GetRows(string filter_one, string filter_two)
{
var retrievedRows = new List<string>();
var storedProc = "dbo.MyStoredProc";
using (SqlConnection connection = new SqlConnection(MY_CONNECTION_STRING))
using (SqlCommand command = new SqlCommand(storedProc, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#FilterOne", SqlDbType.VarChar).Value = filter_one;
command.Parameters.Add("#FilterTwo", SqlDbType.VarChar).Value = filter_two;
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
retrievedRows.Add(reader.GetString(0));
}
}
}
return retrievedRows;
}
Any ideas? I get no errors in the console or when I run it on IIS Express either. When I watch retrievedRows, the size stays at 0 even though when I run the same query in SQL with the same passed parameters, it returns results for me.
EDIT: Please excuse me, my brain must be running a bit slow today. One of the parameters I was passing was pointed at the (empty) value of the wrong webcontrol. I don't know how I missed this.
There is only one issue with your posted snippet that I can see, which could pose a problem:
command.Parameters.Add("#FilterOne", SqlDbType.VarChar).Value = filter_one;
command.Parameters.Add("#FilterTwo", SqlDbType.VarChar).Value = filter_two;
In this section, you're adding two VARCHAR parameters but not specifying a length for them. Try changing your code to add a length specification:
var filterOne = new SqlParameter("FilterOne", System.Data.SqlDbType.VarChar, 50);
The constructor in use here is SqlParameter(string, SqlDbType, int):
Parameters
-
parameterName (String): The name of the parameter to map.
dbType (SqlDbType): One of the SqlDbType values.
size (Int32): The length of the parameter.
When working with VARCHAR you must specify a length or anything outside of the default length (which is 1 byte for definitions and variables, and 30 bytes for CAST and CONVERT) will be truncated:
When n isn't specified in a data definition or variable declaration statement, the default length is 1. If n isn't specified when using the CAST and CONVERT functions, the default length is 30.
I am using below SQL Server function to check is userName and password entered by user through C# windows forms are correct or not as show below too but at first I am getting error at line cmd.ExecuteScalar(); saying
{"Object reference not set to an instance of an object."}
after trying to handle that error I get the error on
return result.ToString();
How I am getting null value if the SQL Server function not returning null value it return 1 or -1 if there is no match within the database?
Even so I searched and tried to handle the null value returned from the cmd.ExecuteScalar(); as you can see my tries but none of the gose successfully
please if anyone can help me ...thanks
you probably want to do something like this :
public string userLogin()
{
string connStr = ConfigurationManager.ConnectionStrings["SRJDconnstr"].ToString();
string cmdStr = #"SELECT dbo.USER_LOGIN(#USER_NAME, #PWD)";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
conn.Open();
cmd.Parameters.AddWithValue("#USER_NAME", TB_USER_NAME.Text);
cmd.Parameters.AddWithValue("#PWD", TB_PWD.Text);
var result = cmd.ExecuteScalar();
return result.ToString();
}
}
cmd.ExecuteScalar() will return the first column of the first row in the result set.
Your SQL Server function code ends with RETURN #vResult which is the RETURN value.
Try and replace RETURN #vResult with SELECT #vResult.
I'm trying to execute a SQL command that inserts values into the table. The code is as below:
public static bool Add(string username, string friend_username, int status, string msg, string key, string reject_key)
{
using (SqlConnection con = new SqlConnection(Config.ConnectionString))
{
con.Open();
StringBuilder query = new StringBuilder();
query.Append("Insert into friends(username,friend_username,status,msg,date_added,val_key,reject_key)values");
query.Append("(#username,#friend_username,#status,#msg,#date_added,#key,#reject_key)");
using (SqlCommand cmd = new SqlCommand(query.ToString(), con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("#username", username));
cmd.Parameters.Add(new SqlParameter("#friend_username", friend_username));
cmd.Parameters.Add(new SqlParameter("#status", status));
cmd.Parameters.Add(new SqlParameter("#msg", msg));
cmd.Parameters.Add(new SqlParameter("#date_added", DateTime.Now));
cmd.Parameters.Add(new SqlParameter("#key", key));
cmd.Parameters.Add(new SqlParameter("#reject_key", reject_key));
cmd.ExecuteNonQuery();
}
}
return true;
}
The 'Add' function gets called here :
private void Process_Approve_Action(int mtype, long groupid, long content_id, string usr)
{
// approval status = 0(
int status = 0;
switch (mtype)
{
case 4: // friend invitation
string request_username = usr;
string friend_username = Page.User.Identity.Name;
//FriendsBLL.Update_Status(request_username, friend_username, 0);
//// also add invited user as their own friend
FriendsBLL.Add(friend_username, request_username, status, "", "", "");
Config.ShowMessageV2(msg, Resources.vsk.message_inbox_06, "Success!", 1); //Friend invitation accepted.
break;
}
I've tried debugging the Add function and the debugger doesn't go past 'cmd.ExecuteNonQuery();' and breaks out
What am I doing wrong here?
Add space before VALUES because you have syntax error in SQL:
query.Append("Insert into friends(username,friend_username,status,msg,date_added,val_key,reject_key) values");
The SqlParameter class has many constructors, but two constructors are well know to cause problems when the parameter value is an integer with a zero value. (And in your example the status variable has a zero value)
The first constructor takes a string and an object, the second one takes a string and an SqlDbType. This scenario leads to the following problem.
If you call the SqlParameter constructor and pass an integer with a value of zero the constructor called is the one that consider your parameter an SqlDbType of value zero. And you end up with a parameter with a NULL value.
If the column of your database doesn't accept a NULL value you have a big time scratching your head to understand why your code fails.
I have started to use always this kind of syntax when adding parameters
cmd.Parameters.Add("#status", SqlDbType.Int).Value = status;
By the way, the MSDN explain it as well
Have a look at this
SQL Insert Query Using C#
Some say you need to open the connection right before execute non query.
Also found that your cmd.Parameters.Add() function is deprecated, use cmd.Parameters.AddWithValue() instead.
Complete doco:
https://msdn.microsoft.com/en-us/library/9dd8zze1(v=vs.110).aspx
Use
cmd.Parameters.Add("#PARAMETERNAME", SqlDbType.VarChar).Value = variableName;
Another possible issue is where your connection string is placed
using(SqlConnection con = new SqlConnection("Your Connection String Here");
NOTE: if you have this kind of code you should no longer be doing the
con.Open() since you already placed it in a using() which indicates that if there's an open connection you use it, if not, open a connection.
I'm running into an issue that is mind boggling to me. I've noticed that IDataReader.Read() is acting differently depending on how the IDbCommand.CommandText is set.
In the code below - If 'AID' is set and passed to EntAgencyId(), reader.Read() returns true and the program is able to enter into the while loop. If I just set 'query' in EntAgencyId() using the same value I'm passing to the function ('455'), the program is never able to enter the while loop (the same behavior happens when passing in 'AID' from a textbox.text).
public string EntAgencyId(string AID)
{
cmd = uasConnection.CreateCommand();
//query = "select * from EnterpriseAgencyTbl where AOCId = " + AID; //<--Works
query = "select * from EnterpriseAgencyTbl where AOCId = 455"; //<--Causes issue
cmd.CommandText = query;
reader = cmd.ExecuteReader();
while (reader.Read())
{
EntAgId = reader["Id"].ToString();
AgencyName = reader["Name"].ToString();
}
reader.Close();
return AgencyName;
}
When debugging, 'query' always has the same value, so why is this making a difference with .Read().
Food for thought - .Read() returns true if there are more rows; otherwise, false. In this case I tried just reading the first single row using the Item property and GetValue(), both result in an 'Object not set to an instance of an object' error.
I've completely run out of ideas, so any help will be appreciated!
If AID may come from an untrusted source, then you should really be using parameters.
Use the following code instead:
query = "select * from EnterpriseAgencyTbl where AOCId = #AOCId";
cmd.CommandText = query;
cmd.Parameters.Add(new SqlParameter("#AOCId", SqlDbType.Int) { Value = int.Parse(AID) });
Then see if this behaves the same using static inputs, such as:
cmd.Parameters.Add(new SqlParameter("#AOCId", SqlDbType.Int) { Value = 455 });
Note: I'm making the assumption, based on 'Id' in the name, that AOCId is an int type.