Storing SQL Select result into String Variable - c#

I am trying to store the result from my SQL query into a string variable. This is what I have:
string strName = dt.Rows[i][name].ToString();
string selectBrandID = "SELECT [Brand_ID] FROM [myTable] WHERE [real_name] = '" + strName + "'";
using (SqlCommand sqlCmdSelectBrandID = new SqlCommand(selectBrandID, sqlConn))
{
sqlCmdSelectBrandID .Connection.Open();
using (SqlDataReader reader = sqlCmdSelectBrandID.ExecuteReader())
{
if (reader.HasRows)
{
reader.Read();
string newBrandID = reader.GetString(reader.GetOrdinal("Brand_ID"));
}
sqlCmdSelectBrandID.Connection.Close();
}
}
This currently throws the exception Unable to cast object of type 'System.Int32' to type 'System.String'. On string newBrandID =reader.GetString(reader.GetOrdinal("Brand_ID")); line.
Any advice on how to fix this?

If your Brand_ID is stored in an integer field, then you should keep it as an integer. The GetString fails because the underlying field is not a string, you could simply use the GetInt32 (see the SqlDataReader docs)
int newBrandID = reader.GetInt32(reader.GetOrdinal("Brand_ID"));
Then, if for whatever purpose you want it as a string, it is just a matter to apply the ToString() method to your integer
string brandID = newBrandID.ToString();

Related

Can't convert DateTime to string in C#

Hi i'm trying to make a reservation page. If someone makes a reservation that date gets saved in the database and will also be showed on their page. The type of the column 'dayid' is date in postgresql. In razor pages C# i used the type DateTime for variable Dayid. I need to convert the dayid value from database to a string. But i don't know how to solve this error:
"No overload for method 'ToString' takes 1 arguments"
Here is the code
public List<ReservationModel> ShowReservation()
{
var cs = Database.Database.Connector();
List<ReservationModel> res = new List<ReservationModel>();
using var con = new NpgsqlConnection(cs);
{
string query = "Select dayid, locationid FROM reservation";
using NpgsqlCommand cmd = new NpgsqlCommand(query, con);
{
cmd.Connection = con;
con.Open();
using (NpgsqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
res.Add(new ReservationModel { Dayid = dr["dayid"].ToString("MM/dd/yyyy"), Locationid = dr["locationid"].ToString() });
}
}
con.Close();
}
}
return res;
}
The compile-time type of the NpgsqlDataReader indexer is just object, and the object.ToString() method is parameterless. You need an expression of type DateTime to call the ToString overload that you want.
You could cast to DateTime instead:
while (dr.Read())
{
res.Add(new ReservationModel
{
Dayid = ((DateTime) dr["dayid"]).ToString("MM/dd/yyyy"),
Locationid = dr["locationid"].ToString()
});
}
(Or find the column index and call dr.GetDateTime(...).)
However, I'd encourage you to change your model (ReservationModel) to keep the value as a DateTime instead of converting it to a string at this point anyway. In general, it's a good idea to keep data in its most natural data type for as much of the time as possible, only converting it to/from text at boundaries.

SQLiteException constraint failed

I have a SQLite table which I've created and it works fine when inserting data which is non-zero. However, I need to insert some zero default values and the SQLiteParameter seems to be converting the zero values to null
Can someone explain why I'm getting #xxxx3=null instead of #xxxx3=0 and also how to fix it.
This appears to happen for any numeric field (INTEGER/NUMERIC).
I've put together a simplified example that shows the problem
class Program
{
private static List<SQLiteParameter> DefaultSystemParameters()
{
List<SQLiteParameter> sp = new List<SQLiteParameter>()
{
new SQLiteParameter("#xxxx2", 60),
//new SQLiteParameter("#xxxx3", 1), // Works fine
new SQLiteParameter("#xxxx3", 0), // Throws 'System.Data.SQLite.SQLiteException' NOT NULL constraint failed: tblxxxx.xxxx3
};
return sp;
}
static void Main(string[] args)
{
//Add Nuget package - System.Data.SQLite v 1.0.99
string baseDir = AppDomain.CurrentDomain.BaseDirectory + AppDomain.CurrentDomain.RelativeSearchPath + "db\\";
string fileName = "test.db";
string sqlCreateTable = "CREATE TABLE IF NOT EXISTS tblxxxx (" +
"xxxx1 INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," +
"xxxx2 INTEGER NOT NULL," +
"xxxx3 INTEGER NOT NULL" +
")";
string sqlInsert = "INSERT INTO tblxxxx (xxxx2, xxxx3) VALUES (#xxxx2, #xxxx3)";
if (!Directory.Exists(baseDir))
Directory.CreateDirectory(baseDir);
DataTable dt = new DataTable();
string connectionString = $"Data Source={baseDir + fileName};Version=3;";
using (var connection = new SQLiteConnection(connectionString))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
//CREATE
using (SQLiteCommand command = new SQLiteCommand(sqlCreateTable, connection))
{
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
//INSERT
command.CommandText = sqlInsert;
command.Parameters.AddRange(DefaultSystemParameters().ToArray());
command.ExecuteNonQuery();
}
transaction.Commit();
}
}
}
}
From https://msdn.microsoft.com/en-us/library/0881fz2y(v=vs.110).aspx:
Use caution when you use this overload of the SqlParameter constructor
to specify integer parameter values. Because this overload takes a
value of type Object, you must convert the integral value to an Object
type when the value is zero, as the following C# example demonstrates.
Parameter = new SqlParameter("#pname", (object)0);

exception "Input string was not in a correct format"

I am trying to associate adminID(which is foriegn key) with my table Media. I retrieve the adminID, but when I convert it to int it throw exception "Input string was not in a correct format".
void Insert(string name, int size, string path)
{
SqlConnection connec = new SqlConnection(ConfigurationManager.ConnectionStrings["BloodDonorRegistrationConnectionString"].ConnectionString);
string VidInsertQuary = "insert into Media(AdminID,Date,Time,Content,FileName,FilePath,TopicTittle,TopicDescr) values (#ad,#dt,#tm,#cc,#Fname,#Fpath,#TpTittle,#TpDes)";
string AdminID = "select AdminID from Admin where Email='" + Session["UserID"]+"'";
try
{
int tempid = 0;
SqlCommand com2 = new SqlCommand(AdminID, connec);
tempid = Convert.ToInt32(com2.ToString());
SqlCommand com = new SqlCommand(VidInsertQuary, connec);
connec.Open();
com2.Parameters.AddWithValue("#ad",tempid);
com.Parameters.AddWithValue("#dt", DateTime.Now.Date);
com.Parameters.AddWithValue("#tm", DateTime.Now.TimeOfDay);
com.Parameters.AddWithValue("#cc", size);
com.Parameters.AddWithValue("#Fname", name);
com.Parameters.AddWithValue("#Fpath", path);
com.Parameters.AddWithValue("#TpTittle",TextBoxTittle.Text);
com.Parameters.AddWithValue("#TpDes",TextBoxDescription.Text);
com.ExecuteNonQuery();
Response.Redirect("AdminVideoUpload.aspx");
}
catch (Exception ex)
{
string exp = "Problem occured";
Response.Write(exp + ex.ToString());
}
finally
{
connec.Close();
}
}
com2.ToString() has nothing to do with the query result, and is not a number.
You want .ExecuteScalar(), which will execute the query and return the first cell of the result.
Here
SqlCommand com2 = new SqlCommand(AdminID, connec);
you have defined a sql command. You haven't requested it's execution.
So here you don't have any result to convert it into an int:
tempid = Convert.ToInt32(com2.ToString());
Actually, the com2.ToString() will return the string representation of the com2 object whose type is of SqlCommand.
In order you solve your problem, you could try this:
tempid = Convert.ToInt32(com2.ExecuteScalar());
or this:
tempid = (Int32)com2.ExecuteScalar();
I had done this earlier and when I try this exception arises..
"System.Data.SqlClient.SqlException (0x80131904): Must declare the
scalar variable "#ad"."
This is another problem in your code, it has nothing to do with the above.
Actually, this
com2.Parameters.AddWithValue("#ad",tempid);
should be rewritten to this:
com.Parameters.AddWithValue("#ad",tempid);
The com2 is not a parameterized sql query. Not being it doesn't mean it shouldn't be. You should declare oly paramterized queries in order you avoid the danger of sql injections.

DataReader IndexOutofRangeException was unhandled by user code

I ran into another issue again. I was trying to get data from the database using DataReader but I got the error when i was testing my code. Can anyone help me out? The error occurred at this line:
chkAssess = readAssess[columnName].ToString();
Below is the code snippet:
public string CheckAssess(string emailAddress, string columnName)
{
string chkAssess = "";
SqlDataReader readAssess;
//readAssess = new SqlDataReader();
string MgrAssessQry = "SELECT '"+columnName+"' FROM tblAllUsers";
//MgrAssessQry += " WHERE email ='" + emailAddress + "'";
SqlCommand cmdReadAssess = new SqlCommand(MgrAssessQry, cn);
cn.Open();
readAssess = cmdReadAssess.ExecuteReader();
while(readAssess.Read())
{
// Add the rows
chkAssess = readAssess[columnName].ToString();
}
return chkAssess;
}
try to use column name without ''
select something from table
instead of
select 'something' from table
for security reasons, don't create sql queries in that way (by concatenating strings) - use #parameters instead
2. close the reader at the end
Try this:
public string CheckAssess(string emailAddress, string columnName)
{
string chkAssess = "";
SqlDataReader readAssess;
//readAssess = new SqlDataReader();
string MgrAssessQry = "SELECT #Column_Name FROM tblAllUsers";
SqlCommand cmdReadAssess = new SqlCommand(MgrAssessQry, cn);
cmdReadAssess.Parameters.AddWithValue(new SqlParameter("Column_Name", columnName));
cn.Open();
readAssess = cmdReadAssess.ExecuteReader();
while(readAssess.Read())
{
// Add the rows
chkAssess = readAssess.GetString(0);
}
return chkAssess;
}
You have got several problems here.
Check whether your readAssess has rows like below.
if(readAssess.HasRows)
If it doesn't have rows then trying
chkAssess = readAssess.GetString(0);
would throw this error, as Arrays are index-based.
So your code should be like below
if(readAssess.HasRows)
{
while(readAssess.Read())
{
chkAssess = readAssess.GetString(0);
}
}
Other problem is you need to close both the reader & the connection afterwards.
readAssess.Close();
cn.Close();
Also your code is potentially vulnerable to SQL Injection.
if (reader.HasRows)
{
while (reader.Read())
{
int result = Convert.ToInt32(reader.GetString(0));
Console.WriteLine(result);
}
}
The most important thing is check the query first by executing in SQL Server and see if any result is coming or not.
Secondly based on the type of output you are receiving cast it to that particular data type (important).Mostly everyone is saving the data in varchar so.

How to make Sqlcommand accept null values

I'm trying to get data in a gridview from a database to show up in text boxes upon clicking and it works fine for the rows with no null data, although since my int columns have some null values my GetInt32 methods keep returning "Data is Null. This method or property cannot be called on Null values."
Is there a simple way to fix or work around this? Do I replace GetInt32 with another method? I'd like for the data that is null to show up blank/empty in the text boxes if possible. Here's my code if you have any suggestions, thanks.
public ArrayList GetAllPersonnel(int WorkerID) {
using (var connection = new SqlConnection(connectionString)) {
connection.Open();
String query = "Select * FROM Personnel WHERE WorkerID = " + WorkerID;
using (var command = new SqlCommand(query, connection)) {
var reader = command.ExecuteReader();
var list = new ArrayList();
while (reader.Read()) {
String firstname = reader.GetString(1);
String lastname = reader.GetString(2);
String occupation = reader.GetString(3);
String deployment = reader.GetString(4);
int disasterid = reader.GetInt32(5);
String location = reader.GetString(6);
int deployedhours = reader.GetInt32(7);
int resthours = reader.GetInt32(8);
list.Add(firstname);
list.Add(lastname);
list.Add(occupation);
list.Add(deployment);
list.Add(disasterid);
list.Add(location);
list.Add(deployedhours);
list.Add(resthours);
}
connection.Close();
reader.Close();
return list;
}
}
}
You should use IsDBNull method of the SqlDataReader
int resthours = (!reader.IsDBNull(8) ? reader.GetInt32(8) : 0);
or, more directly
list.Add((!reader.IsDBNull(8) ? reader.GetInt32(8).ToString(): string.Empty));
Said that, I have noticed that you use a string concatenation to build the sql command text to retrieve records. Please do not do that. It is very dangerous and could lead to Sql Injection
String query = "Select * FROM Personnel WHERE WorkerID = #wkID";
using (var command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("#wkID", WorkerID);
var reader = command.ExecuteReader();
....
OK, so you're effectively saying that everything you display should be a string type, which is fine, I'm just making that point because you stated you want even integers to show up as an empty string. So how about this code?
String firstname = reader.GetString(1);
String lastname = reader.GetString(2);
String occupation = reader.GetString(3);
String deployment = reader.GetString(4);
String disasterid = reader.IsDBNull(5) ? string.Empty : reader.GetString(5);
String location = reader.GetString(6);
String deployedhours = reader.IsDBNull(7) ? string.Empty : reader.GetString(7);
String resthours = reader.IsDBNull(8) ? string.Empty : reader.GetString(8);
list.Add(firstname);
list.Add(lastname);
list.Add(occupation);
list.Add(deployment);
list.Add(disasterid);
list.Add(location);
list.Add(deployedhours);
list.Add(resthours);
Now, the reason I stated that you want to leverage everything as a string is because the default value for a int is 0 and that wouldn't meet the empty text box requirement.
You have at least two ways to sort this out
Modify your sql to select either zero or whatever you think suitable in the place of null value. This will ensure that you always have an integer value in the integer column. It can be done in the following manner
select ISNULL ( ColumnName , 0 ) as ColumnName from xxx
Always fetch object from the reader and check if it is null or not. If it is null then replace it with suitable value.

Categories