Read boolean values from DB? - c#

In C#, using SqlDataReader, is there a way to read a boolean value from the DB?
while (reader.Read())
{
destPath = reader["destination_path"].ToString();
destFile = reader["destination_file"].ToString();
createDir = reader["create_directory"].ToString();
deleteExisting = Convert.ToBoolean(reader["delete_existing"]);
skipIFolderDate = reader["skipifolderdate"].ToString();
useTempFile = reader["useTempFile"].ToString();
password = reader["password"].ToString();
}
In the code above, delete_existing is always a 1 or 0 in the DB. I read on MSDN that Convert.ToBoolean() does not accept a 1 or 0 as valid input. It only accepts true or false. Is there an alternative way to convert a DB value to a bool? Or do I need to do this outside of the SqlDataReader?
Also, I can not change the DB values, so please no answers saying, "Change the DB values from 1's and 0's to true's and false's."
Thanks!

If the type of delete_existing is a sqlserver 'bit' type, you can do :
var i = reader.GetOrdinal("delete_existing"); // Get the field position
deleteExisting = reader.GetBoolean(i);
or (but it will crash if delete_existing can be DBNull)
deleteExisting = (bool)reader["delete_existing"];
or better, this onebelow is DBNull proof and returns false if the column is DBNull
deleteExisting = reader["delete_existing"] as bool? ?? false;
Otherwise if the database type is int :
deleteExisting = (reader["delete_existing"] as int? == 1) ? true : false;
or if it is a varchar
deleteExisting = (reader["delete_existing"] as string == "1") ? true : false;

Casting works:
myVar = (bool)dataReader["myColumn"];

How about this?
deleteExisting = (reader["delete_existing"] as int?) == 1;
Boolean is probably the easist type to convert something to. Here's the 'Y', 'N' version:
deleteExisting = string.Equals(reader["delete_existing"] as string, "Y", StringComparision.OrdinalIgnoreCase);

If you are using CASE in SELECT and want to use GetBoolean then use CAST to change the column to bit before reading.
For eg:
SELECT CAST((CASE WHEN [Condition] THEN 1 ELSE 0 END) as bit) FROM Table_Name
then you can use
reader.GetBoolean(0)

deleteExisting = reader.GetBoolean(reader["delete_existing"]);

Related

Insert null value to Sql server bigInt column

A table contain bigInt column named 'Phone' I want to insert null value to this column by entity frame work. I used following codes:
objRegister.Phone = Convert.ToInt64(txtPhone.Text ??null );
But i get this message: "Input string was not in a correct format.".
I change the code as shown in below:
objRegister.Phone = txtMobile.Text != null ?Convert.ToInt64(txtMobile.Text):((long?)null) ;
I got same message : "Input string was not in a correct format."
You could try this something like this:
long phone;
objRegister.Phone = long.TryParse(txtPhone.Text, out phone)
? (long?)phone
: (long?)system.DBNullValue;
Int64 phoneNumber;
Int64.TryParse(txtPhone.Text, out phoneNumber) == true ? phoneNumber : DBNull.Value;
You can use ?: Conditional Operator with Int64.TryParse check whether text is convertible to Int64. If convertible then assign convertible value else DBNull.Value

How to retrieve data from sql database to check boxes [duplicate]

In C#, using SqlDataReader, is there a way to read a boolean value from the DB?
while (reader.Read())
{
destPath = reader["destination_path"].ToString();
destFile = reader["destination_file"].ToString();
createDir = reader["create_directory"].ToString();
deleteExisting = Convert.ToBoolean(reader["delete_existing"]);
skipIFolderDate = reader["skipifolderdate"].ToString();
useTempFile = reader["useTempFile"].ToString();
password = reader["password"].ToString();
}
In the code above, delete_existing is always a 1 or 0 in the DB. I read on MSDN that Convert.ToBoolean() does not accept a 1 or 0 as valid input. It only accepts true or false. Is there an alternative way to convert a DB value to a bool? Or do I need to do this outside of the SqlDataReader?
Also, I can not change the DB values, so please no answers saying, "Change the DB values from 1's and 0's to true's and false's."
Thanks!
If the type of delete_existing is a sqlserver 'bit' type, you can do :
var i = reader.GetOrdinal("delete_existing"); // Get the field position
deleteExisting = reader.GetBoolean(i);
or (but it will crash if delete_existing can be DBNull)
deleteExisting = (bool)reader["delete_existing"];
or better, this onebelow is DBNull proof and returns false if the column is DBNull
deleteExisting = reader["delete_existing"] as bool? ?? false;
Otherwise if the database type is int :
deleteExisting = (reader["delete_existing"] as int? == 1) ? true : false;
or if it is a varchar
deleteExisting = (reader["delete_existing"] as string == "1") ? true : false;
Casting works:
myVar = (bool)dataReader["myColumn"];
How about this?
deleteExisting = (reader["delete_existing"] as int?) == 1;
Boolean is probably the easist type to convert something to. Here's the 'Y', 'N' version:
deleteExisting = string.Equals(reader["delete_existing"] as string, "Y", StringComparision.OrdinalIgnoreCase);
If you are using CASE in SELECT and want to use GetBoolean then use CAST to change the column to bit before reading.
For eg:
SELECT CAST((CASE WHEN [Condition] THEN 1 ELSE 0 END) as bit) FROM Table_Name
then you can use
reader.GetBoolean(0)
deleteExisting = reader.GetBoolean(reader["delete_existing"]);

Specified cast is not valid in C#

I have a column which is of type bigint in the database table. I want it to retrieve and assign it to variable in C# as shown below in the example.
Example:
obj.Total1 = (Int32)reader["Slno"] != null ? (Int32)reader["Slno"] : 0;
obj.Total2 = (Int32)reader["Rlno"] != null ? (Int32)reader["Rlno"] : 0;
Note: Here Slno and Rlno are of type bigint in database table.
Error: Following is the error message.
Specified cast is not valid.
SQL's BigInt maps to a long in C#, not an int.
BigInt needs to be mapped to long which is the equivalent 64bit integer value in C#.
Also, you should alter your code to something like this:
int slnoCol = reader.GetOrdinal("Slno");
int rlnoCol = reader.GetOrdinal("Rlno");
obj.Total1 = !reader.IsDBNull(slnoCol) ? reader.GetInt64(slnoCol) : (long)0;
obj.Total2 = !reader.IsDBNull(rlnoCol) ? reader.GetInt64(rlnoCol) : (long)0;
EDIT:
After noticing your comment that Total1 and Total2 are int, you also need to change them to long
public long Total1 { get; set; }
public long Total2 { get; set; }
This is because int is a 32bit integer which cannot store the same max value as a 64bit integer which is what you are using in your table.
In my case I was getting a "specified cast is not valid", when my table was empty.
so I changed my code like so:
while (reader.Read())
max = reader.GetInt32(0);
Added a check for DBNull:
while (reader.Read())
max = reader.IsDBNull(0) ? 0 : reader.GetInt32(0);

C# DataSet: How can I know if a column is a of DateTime/Boolean type

In C#, I create some dataset or datatable from some query.
Data which comes from DateTime columns in the database are typed as System.String.
Is there a way to know programatically identify a column as containing a DateTime information ?
Sames question for boolean data which is considered as System.Int32 ?
Thank you
EDIT1 because it seems that this wasn't totally understood:
MyDataColumn.DataType is "System.String" (for DateTime) !
MyDataColumn.DataType is "System.Int32" (for Boolean) !
So I can't get the in I want from DataType, otherwise I wouldn't even have posted this.
EDIT2 And the TryParse() idea has a big problem here, it's more obvious with the Boolean/System.Int32 confusion: If I see "1" or "0" I could think that it's a Boolean while it may as well be an Int32 column. TryParse() has the same flaw.
if (myDataTable.Columns["thisColumn"].DataType == System.Type.GetType("System.DateTime"))
{
...
}
else
{
}
EDIT:
To check the containing data you may try to parse its values. so for each value in that column you do like this:
DateTime dateTime;
DateTime.TryParse("your string", out dateTime);
Create a stored proc like the follow:
Alter proc proc_GetDataTypeValueByColumnName
(
#TableName varchar(500)='tblAdminUser',
#ColumnName varchar(500)='Id'
)
as
declare #DataType varchar(500);
if exists(select 1 from sys.tables where name=#TableName)
begin
set #DataType=(SELECT t.Name 'Data type'FROM sys.columns c INNER JOIN
sys.types t ON c.system_type_id = t.system_type_id
WHERE
c.object_id = OBJECT_ID(''+#TableName+'') and c.name=#ColumnName)
-- select dbo.GetDataTypeValue(#DataType)
select #DataType
End
You need to pass the table name and the column name of which you want to get the datatype
if you want to get it in the code then you can go for the following stuff:
public String GetNumberForDataTypeofColumn(String TableName, String ColumnName)
{
SqlParameter[] param = new SqlParameter[2];
param[0] = new SqlParameter("#TableName", TableName);
param[1] = new SqlParameter("#ColumnName", ColumnName);
String result = SqlHelper.ExecuteScalar(ConfigurationManager.ConnectionStrings["cn"].ConnectionString, CommandType.StoredProcedure, "proc_GetDataTypeValueByColumnName", param).ToString();
return result;
}
And there is another way that is :: data Column has property "DataType" you can also check from that like below:
dtItems.Columns[0].DataType
Hope this will help you
You can use LINQ to see if any column of DateTime type exists in your datatable. You need to parse each column with DateTime.TryParse to see if any column gets successfully parsed like:
if (dt == null || dt.Rows.Count <= 0)
return false;
DateTime temp;
if (dt.Rows[0].ItemArray.Any(r => DateTime.TryParse(r.ToString(),
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out temp)))
{
//Column exists.
}
If you want to get the column index then you can try:
var column = dt.Rows[0].ItemArray
.Select((r, index) => new { Value = r, Index = index })
.FirstOrDefault(t => DateTime.TryParse(t.ToString(),
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out temp));
if(column != null)
Console.WriteLine(column.Index);
(Remember to include System.LINQ)

Object cannot be cast from DBNull to other types

I have an insert stored procedure like this
if exists(select EmailId from Profile_Master where EmailId=#EmailId)
set #result=-1
else
begin
set #result=0
insert into Profile_Master(FirstName,LastName,Dob,Gender,MobileNo,Country,State,EmailId,Password)
values
(#FirstName,#LastName,#Dob,#Gender,#MobileNo,#Country,#State,#EmailId,#Password)
set #id=SCOPE_IDENTITY()
return
end
pid = cmd1.Parameters.Add("#id", SqlDbType.Int);
pid.Direction = ParameterDirection.Output;
cmd1.ExecuteNonQuery();
int res = Convert.ToInt32(pid.Value);
I am catching the value of last inserted record but i am getting an error like
Object cannot be cast from DBNull to other types.How to catch the value of last inserted record?
Do a null-check before you try to convert the value.
if( pid.Value is DBNull )
{
// Do alternative route.
}
else
{
int res = Convert.ToInt32(pid.Value);
}
or:
if( ! pid.Value is DBNull )
{
int res = Convert.ToInt32(pid.Value);
}
Well, clearly we can assume that pid.Value is equal to DBNull.Value and cannot be converted to type int
You need to check what the sp does adn what it returns from the Database.

Categories