How to check if decimal is valid value in Teradata - teradata

How to check if the given decimal is valid. I usually do a case statement like below to check if column is invalid or NULL then set it to 0 else take it as it is:
case when decimal_column is NULL or decimal_column NOT BETWEEN -999999999999 AND 999999999999 then 0 else decimal_column end
Can anyone please let me know if the above query looks correct
Thanks

In Teradata 14.10 or greater, the TO_NUMBER() function can be used.
SELECT TO_NUMBER({decimal column})
FROM {table};
If the conversion to number failed, TO_NUMBER() returns NULL. See the SQL Functions,Operators, Expressions and Predicates manual for more details.

You can also use trycast. Something like ..:
trycast(trim(col1)) as DECIMAL (XX,Y))
From TD-Doku: TRYCAST takes a string and tries to cast it to a data type specified after the AS keyword (similar to CAST). If the conversion fails, TRYCAST returns a NULL instead of failing.

Related

Displaying the same value in SQL case statement

This might be a simple question but I am unable to find a solution for this, I have a SQL case statement of some form, for example:
CASE
WHEN table_1.col_1 IS NULL THEN 'NULL'
ELSE table_1.col_1
END as 'col_1'
col_1 is of TEXT data type. What I am trying to achieve is that I want NULL to be written wherever the value is NULL and then I want the original value to be displayed if it is not NULL.
I checked the rest of the query it is fine. Making the ELSE statement to 'table_1.col_1' results in all the NOT NULL values as 'table_1.col_1'.
Making the ELSE statement to 'table_1.col_1' results in all the NOT
NULL values as 'table_1.col_1'
Don't use single quotes because you get a string literal 'table_1.col_1' and not the value of the column table_1.col_1.
In the CASE expression that you posted though there are not single quotes around table_1.col_1 so it should work fine, but this logic can be expressed with COALESCE() like this:
COALESCE(table_1.col_1, 'NULL') AS col_1
Also don't use single quotes for aliases. If needed use backticks or square brackets.

ReportBuilder embedded FormatDateTime errors in switch comparator

I have a datetime field that may be blank. when it is not blank I want to show only the date portion. I used:
=FormatDateTime(Fields!myDate.Value, DateFormat.ShortDate)
This works except for blank entries which are replaced by "1/1/0001".
I used a switch statement but it returns an error when the condition is met. The switch statement is:
=switch(Fields!myDate.Value<>"", FormatDateTime(Fields!myDate.Value, DateFormat.ShortDate))
This works for the blanks but yields an error for datetime entries.
The workaround is to change the stored procedure to return only the date for the datetime field. I would prefer to have the time value in case it is needed in the future.
Please let me know what I'm doing wrong or if there is a report builder solution that works.
=IIF(Fields!myDate.Value Is Nothing, "", Format(Fields!myDate.Value,
"dd/MM/yyyy"))
Please mark as duplicate. This is a duplicate answer of my similar question (with Answer by Jeffrey Van Laethem) "SSRS expression fails for IIF date with #error"

VB Single line with null values

I have the following code that I don't believe is functioning properly and I cannot figure out why.
dim total as decimal? = If(first Is Nothing OrElse second Is Nothing, _
Nothing, _
Math.Abs(If(first, 0D)) - Math.Abs(If(second, 0D)))
If either first or second are nothing, then nothing needs to be placed in the total. However, if they both have values, they both need to be changed to positive values and first - second needs to be calculated. First and second are both nullable decimals (decimal?).
Expected results:
first = nothing
second = nothing
total = nothing
Actual results:
first = nothing
second = nothing
total = 0D
I cannot understand why the if statement is not jumping to the true segment and putting Nothing into the variable total
The If() operator is strongly-typed, but the compiler has to infer the type of the result based on the inputs.
In this case, it can't infer the type from the first option (Nothing), because Nothing by itself has no type, and unlike C#'s null, Nothing can reduce to a value type (this will be important in a moment). Therefore the compiler has to look at the second option: Math.Abs(If(first, 0D)) - Math.Abs(If(second, 0D)). The type of this expression evaluates out to a Decimal... not a Decimal?. Therefore, the resulting type of your entire If() expression is a Decimal, and not a Decimal?. That you assign the result to a Decimal? doesn't matter.
I cannot understand why the if statement is not jumping to the true segment and putting Nothing into the variable total
That is exactly what it's doing. However, as mentioned earlier, Nothing in VB.Net can be assigned to value types. Before the assignment can occur, Nothing is converted to a Decimal, because this is the result type of that If() expression. In case of a Decimal, assigning the value of Nothing results in the default Decimal value of 0D... hence your results.
I haven't tested this, but I think you could fix this to get your desired results by explicitly casting the False expression in your If() operator as a Decimal?/Nullable(Of Decimal). This will tell the compiler to infer Decimal? instead of Decimal for the type of the If() expression, and therefore returning Nothing from that expression will have desired output.
I have reverted to make a compiler extension that allows the absolute value function to be performed on a nullable decimal, returning the value if it is Nothing or non-negative, otherwise multiply by -1 and return. That way if it returns nothing the computation result is as expected.
dim total as decimal? = first.ToAbsoluteValue() - second.ToAbsoluteValue()
<System.Runtime.CompilerServices.Extension()>
Friend Function ToAbsoluteValue(value As Decimal?) As Decimal?
If value Is Nothing OrElse value >= 0 Then Return value
Return Math.Abs(If(value, 0D))
End Function
If anyone knows how to add this to the Math.Abs() overloads that would be a much cleaner option.

Using UTCTime with SQLite in Yesod

While using a UTCTime field in my model in Yesod, I get the following error:
PersistMarshalError "field timestamp: Expected UTCTime, received PersistText \"09:18:07\""
I am using SQLite to store my database. My model looks as follows:
Myobject
timestamp UTCTime default=CURRENT_TIME
otherfield Text
Note that this error occurs both with and without the default value.
I am selecting the list of Myobject-entities as follows:
myobjects <- selectList [] [Desc MyobjectTimestamp]
Using MyobjectOtherfield instead of MyobjectTimestamp does not help either, which makes sense since all data is fetched and therefore marshaled anyway.
A similar question has been asked here, but the answer did not help me.
How can I use UTCTime in Yesod while using SQLite?
Edit:
The PersistText \"09:18:07\" that is mentioned in the error is the value the field defaulted to.
You stored a Text value "09:18:07", while it expected a UTCTime value. Did you insert values by hand?
getCurrentTime from Data.Time returns a value of type IO UTCTime, so you can either use putStr getCurrentTime in GHCI to get a valid representation, or use now <- liftIO getCurrentTime in your function.
EDIT:
Because getCurrentTime returns a timestamp like: 2013-10-25 10:16:32.1627238 UTC, inserting a value like that in your database should resolve the error.

TALES expression to compare numeric input in Plone?

TALES expression is new to me. Can I get some good reference for the same? Actually I wish to define a content rule for numeric input field using ploneformgen. Something like:
python: request.form.get('amt', False) <= 5000
then apply the rule.
Here 'amt' is a numeric/whole number field on the input form.
For reference, you should look at the official TALES specification, or refer to the TALES section of the Zope Page Templates reference.
In this case, you are using a plain python expression, and thus the normal rules of python code apply.
The expression request.form.get('amt', False) would return the request parameter 'amt' from the request, and if that's missing, return the boolean False, which you then compare to an integer value.
There are 2 things wrong with that expression: first of all you assume that the 'amt' parameter is an integer value. Even a PFG integer field however, is still a string in the request object. As such you'll need to convert in to an integer first before you can compare it.
Also, you fall back to a boolean, which in integer comparisons will be regarded as the equivalent of 0, better be explicit and use that instead:
python: int(request.form.get('amt', 0)) <= 5000
Note that for a PFG condition, you can also return a string error message instead of boolean True:
python: int(request.form.get('amt', 0)) <= 5000 or 'Amount must be not be greater than 5000'
Usually form parameters are passed in as strings if they are not defined on the application level otherwise e.g.
Zope will under the hood use the fieldname amt:int in order to convert the value to an integer.
So you may want to try to put an int(....) around the first expression.

Resources