SqlDataReader Convert Int to Int? - c#

I need to return a NULL or Blank value for Apvl_Lvl_Id if the SQL result returns NULL as the integration this passes the Apvl_Lvl_Id value to can't handle a value if it doesn't match an existing value for that instance.
I can't figure out what I'm missing, hoping someone can offer some pointers. Hope the below code is enough for an example.
while (dr.Read())
{
if(dr.IsDBNull(Apvl_Lvl_Id))
{
int? Apvl_Lvl_IdNULL;
Apvl_Lvl_Id = Apvl_Lvl_IdNULL;
}
else
{
Apvl_Lvl_Id = dr.GetInt32(0);
}
}

Sorry, but that code makes little sense. Apparently, Apvl_Lvl_Id is supposed to be the column ordinal - effectively the zero-based count of the column in a row - that you check for being DBNull. Then you are trying to assign the actual column's value to that ordinal? Apart from that, there is just no way you can assign null to an int. Introduce a separate variable, say, Apvl_Lvl_Value, make it an Nullable<int> (or int?) and assign the the column's value as required (actual value or null).
In "short", the code should more like this:
while (dr.Read())
{
int? Apvl_Lvl_Value;
// Check if the value of the column with the ordinal Apvl_Lvl_Id is DBNull
if(dr.IsDBNull(Apvl_Lvl_Id))
{
// If so, use .NET "null" for the rest of the logic.
Apvl_Lvl_Value = null;
}
else
{
// Use the actual columns (non-NULL) value.
Apvl_Lvl_Value = dr.GetInt32(Apvl_Lvl_Id);
}
// Do something with the column's value, stored in Apvl_Lvl_Value
}
Now, some things here are guesswork which are not really clear otherwise from your question, but generally, the above is a "pattern" by which one would use IsDBNull() and
a Get*() method together.

And why don't you just set
Apvl_lvl_Id = null;

Related

How do I get a C# transform in SSIS to allow me to output a null

I am reading some text from an input file, splitting it into relevant columns, and then trying to convert those columns to the right data type. For Column 2/price adjustment, it is important that when the output of a column is null, this is what is output. The target column can legitimately contain 0 or negative numbers, and the variation is huge, so a dummy such as -1 or even 999999 is no good here.
One of the columns contains either a valid decimal, such as 125.123, the text N.A, or an empty string. I am using Regexp to take care of the text values - or at least they come through as the initialised value as well as the empty strings when testing with a non-null output, so that's fine.
However when I want the output to be null, I always get the error.
Any ideas? I can find all sorts of things showing how to convert it to a default value if it's null, and I can initialise the variable with -100 to achieve that as a default too, but I want the actual output for that column to be null, not any replacement.
I tried GenOutputBuffer.priceadj_IsNull = true but that did not help and might have been a red herring here, as the error is the value is null, not that the output field cannot contain nullable values I guess. I cannot take .Value off or it underlines red. I could try to check if it has a value using .HasValue but then how do I say, if it doesn't have a value, please still put a null in the output?
Relevant sections of the code:
string col2str, col3str;
decimal? col2decN, col3decN;
col2decN = null; //DOES NOT WORK WHEN THIS IS NULL
col3decN = -100; //DOES WORK BUT DO NOT WANT A DUMMY FOR COLUMN 2
. . .
col2str = Regex.Replace(SplitData[2], "[^0-9.]","");
try
{
col2decN = System.Convert.ToDecimal(col2str);
}
catch
{
//NOTHING
}
GenOutputBuffer.AddRow();
GenOutputBuffer.prodid = SplitData[0];
GenOutputBuffer.priceadj = col2decN.Value;
Just set the _IsNull of that column to true if the parsing of a string to decimal fails
decimal dOut;
if (decimal.TryParse(SplitData[1],out dOut))
{
Output0Buffer.C2 = dOut;
}else
{
Output0Buffer.C2_IsNull = true;
}

String.IsNullOrEmpty check with Data Table cell

If I have a Data Table and I want to see if the value contained within a specific cell is empty I would use this.
foreach(DataRow row in DataTable.Rows)
{
bool isEmpty = String.IsNullOrEmpty(row["MyColumn"].ToString());
}
but what happens if the value in row["MyColumn"] is null. Wouldn't the .ToString() throw an exception? Yet when I try the following ..
bool isEmpty = String.IsNullOrEmpty(row["MyColumn"]);
I get an invalid argument exception because the IsNullOrEmpty() method is looking for a string object.
So what is the proper way to check if a specific cell in a Data Table is empty or null?
Change your statement to this,
bool isEmpty = String.IsNullOrEmpty(row["MyColumn"]?.ToString());
?. means run the process .ToString() only if row["MyColumn"] is not null.
Basically just adding this for the sake of completeness... but if for some reason you aren't using C# 6 or above, you can always do it the "old fashioned way":
bool isEmpty = row["MyColumn"] == null || string.IsNullOrEmpty(row["MyColumn"].ToString());
You could instead use the Field<T>() method of the DataRow:
bool isEmpty = String.IsNullOrEmpty(row.Field<string>("MyColumn"));
This provides strongly typed access to the row values.
You can use it with other types too, so no need to parse int or DataTime, for example.
var myDate = row.Field<DateTime>("MyDate"); // DateTime
var myInt = row.Field<int>("MyInt"); // int
It also works with nullable types:
var myDate = row.Field<DateTime?>("MyDate"); // DateTime? (Nullable)
if (myDate.HasValue)
{
...
}

OracleDataReader - Handling a NULL field value when setting up a default dropdown SelectedValue

I've got the following code:
// Here is where we will read in all our values and populate the form with them
lblBenCatX.Text = Convert.ToString(reader["Category"]);
lblBenProvX.Text = Convert.ToString(reader["Provision"]);
txtCommentBox.Text = Convert.ToString(reader["Feedback"]);
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
ddlIssue1.SelectedValue = Convert.ToString(reader["Issue_ID"]);
ddlResolution1.SelectedValue = Convert.ToString(reader["Resolution_ID"]);
ddlDefect2.SelectedValue = Convert.ToString(reader["Network2"]);
ddlIssue2.SelectedValue = Convert.ToString(reader["Issue_ID2"]);
ddlResolution2.SelectedValue = Convert.ToString(reader["Resolution_ID2"]);
The first 3 rows of code; no problem. However, if I have a record with a NULL value, the dropdowns break the code. So, I'm thinking I need to check the field first to make sure it's not NULL. Something like:
if (!Convert.ToString(reader["Network"]) = NULL)
{
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
}
However, that's giving me an error:
The left-hand side of an assignment must be a variable, property or
indexer
Any ideas? This is C# in VS2015 with an Oracle back end, if any of that matters.
In C#, you need to use two equal signs in a row == for equality comparison, not one. One equal sign = is an assignment operator.
if (first == second) { ... }
In your case, though, you would want to use the "not equals" != operator:
if (Convert.ToString(reader["Network"]) != null)
Which is cleaner and slightly more-efficent than this:
if (!(Convert.ToString(reader["Network"]) == null))
Note that I've wrapped the whole inner comparison in parens so the whole statement is being negated; otherwise, it will think you're trying to say !Convert.ToString(reader["Network"]), and, as you pointed out in the comments here, you can't use ! with a string.
That being said, if you're converting to string, then it's better to use string.IsNullOrEmpty() for checking:
if (!string.IsNullOrEmpty(reader["Network"].ToString())))
But the best is probably to just check if the column value is null, rather than converting it to string:
if (!reader.IsDBNull(["Network"]))
= is an assignment operator, used when setting values.
== is an equality operator, which determines whether something is equal to something else.
!= is also an equality operator, opposite to the one above. So, when something is not equal to something else.
So actually, you should be using != in this scenario:
if (Convert.ToString(reader["Network"]) != null)
{
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
}
You have a couple of choices. The first is to check if the value is DBNull which is different than an empty string/null value.
if (!reader.IsDBNull([ordinalPositionOfNetworkInSelectStatement]))
ddlDefect1.SelectedValue = Convert.ToString(reader["Network"]);
See IDataReader.IsDBNull. The only thing is that you need to know the ordinal position of the column you are checking.
The alternative is to check for dbnull in your sql select statement and use a function to return an empty string if it is. The positive side of this approach is you do not have to worry about checking for null in your c# code but I am not sure if it has any negative consequences in your oracle query or view. You can do this with COALESCE.
SELECT Category, Provision, Feedback, COALESCE(Network, '') AS Network /*other columns*/
FROM ... -- rest of the query
disclaimer - my oracle syntax is lacking but COALESCE does exist as a function

Handling Null values in GetSQLDateTime and GetSQLMoney

AS part of an import I'm writing I'm using parameterised values, however the database i'm exporting to cannot handle NULL values, so I need to find a way to handle NULL values.
The closest I've gotten is:
if (tenantexportReader.GetSqlMoney(8).ToDecimal().Equals(null))
{
tenantimportCommand.Parameters["PRICEFINAL"].Value = "0.00";
}
else
{
tenantimportCommand.Parameters["PRICEFINAL"].Value = tenantexportReader.GetSqlMoney(8).ToDecimal();
}
and A similar thing with SQLDateTime
if (tenantexportReader.GetDateTime(9).ToShortDateString().Equals(null))
{
tenantimportCommand.Parameters["TENSDATE"].Value = "0.00";
}
else
{
tenantimportCommand.Parameters["TENSDATE"].Value = tenantexportReader.GetDateTime(9).ToShortDateString();
}
However this does not appear to work, instead I receive the following:
Message=Data is Null. This method or property cannot be called on Null values.
Instead of
if (tenantexportReader.GetSqlMoney(8).ToDecimal().Equals(null))
you should probably use
if (tenantexportReader.IsDbNull(8))
Since the value in the database is NULL (which is DbNull.Value in c#), I assume that GetSqlMoney and GetSqlDateTime throw the exception you received. DbNull.Value cannot be converted to SqlMoney or DateTime.
Check if the value is null via IsDbNull before calling GetSqlMoney or GetSqlDateTime.
So your final if statements should look something like this:
if (tenantexportReader.IsDbNull(8))
{
tenantimportCommand.Parameters["PRICEASK"].Value = "0.00";
}
else
{
tenantimportCommand.Parameters["PRICEFINAL"].Value = tenantexportReader.GetSqlMoney(8).ToDecimal();
}
Why would you assign a string to a monetary value???
Probably what you would want to do is like this:
var priceFinal = tenantexportReader.GetSqlMoney(8);
tenantimportCommand.Parameters["PRICEFINAL"].Value = (decimal)(priceFinal.IsNull ? 0 : priceFinal);
I really don't understand why you set it to "0.00" (string) when it is null and to a decimal value when it is not null.
And also for date/datetime values, again, why do you ever use string conversions and invite errors? Simply pass a date as a datetime.

Check if decimal value is null

I would like to check if the decimal number is NULL or it has some value, since the value is assigned from database in class object:
public decimal myDecimal{ get; set; }
and then I have
myDecimal = Convert.ToDecimal(rdrSelect[23].ToString());
I am trying:
if (rdrSelect[23] != DBNull.Value)
{
myDecimal = Convert.ToDecimal(rdrSelect[23].ToString());
}
But I am getting this:
the result of the expression is always 'true' since a value of type
'decimal' is never equal to null
How can I check if that decimal number has some value?
A decimal will always have some default value. If you need to have a nullable type decimal, you can use decimal?. Then you can do myDecimal.HasValue
you can use this code
if (DecimalVariable.Equals(null))
{
//something statements
}
decimal is a value type in .NET. And value types can't be null. But if you use nullable type for your decimal, then you can check your decimal is null or not. Like myDecimal?
Nullable types are instances of the System.Nullable struct. A nullable
type can represent the normal range of values for its underlying value
type, plus an additional null value.
if (myDecimal.HasValue)
But I think in your database, if this column contains nullable values, then it shouldn't be type of decimal.
I've ran across this problem recently while trying to retrieve a null decimal from a DataTable object from db and I haven't seen this answer here. I find this easier and shorter:
var value = rdrSelect.Field<decimal?>("ColumnName") ?? 0;
This was useful in my case since i didn't have a nullable decimal in the model, but needed a quick check against one. If the db value happens to be null, it'll just assign the default value.
Assuming you are reading from a data row, what you want is:
if ( !rdrSelect.IsNull(23) )
{
//handle parsing
}
Decimal is a value type, so if you wish to check whether it has a value other than the value it was initialised with (zero) you can use the condition myDecimal != default(decimal).
Otherwise you should possibly consider the use of a nullable (decimal?) type and the use a condition such as myNullableDecimal.HasValue
If you're pulling this value directly from a SQL Database and the value is null in there, it will actually be the DBNull object rather than null. Either place a check prior to your conversion & use a default value in the event of DBNull, or replace your null check afterwards with a check on rdrSelect[23] for DBNull.
You can also create a handy utility functions to handle values from DB in cases like these.
Ex. Below is the function which gives you Nullable Decimal from object type.
public static decimal? ToNullableDecimal(object val)
{
if (val is DBNull ||
val == null)
{
return null;
}
if (val is string &&
((string)val).Length == 0)
{
return null;
}
return Convert.ToDecimal(val);
}

Categories

Resources