Informatica Expression Transformation IIF to DECODE function - expression

I have following table where in I need to check 6 combinations for the 4 columns and return the unique code assigned to it. Attached is the image and below is the full text.
UNIQUE_CODE, TYPE, FLAG, VALUES, RETURN VALUE
40031, F ,P, ANY ,44570
40031, V ,P, Z ,44572
40031, V ,P, EXCEPT Z ,44574
10110, F ,R, ANY ,44571
10110, V ,R, Z ,44573
10110, V ,R, EXCEPT Z, 44575
I have achieved this using nested IIF within expression transformation's variable port as per following logic :
IIF ( UNIQUE_NUMBER = 40031 AND FLAG ='P' ,
IIF( TYPE ='F' ,44070,
IIF (TYPE = 'V' ,
DECODE (TRUE,IN (VALUES ,'Z'),44072,44074))),
IIF ( UNIQUE_NUMBER = 10110 AND FLAG ='R' ,
IIF( TYPE ='F' ,44071,
IIF (TYPE = 'V' ,
DECODE (TRUE,IN (VALUES,'Z'), 44073,44075)))))
However now want to achieve the same through DECODE , as I am told that nested IIF expression might effect the performance.
However I am afraid that DECODE might exit as soon as it finds first condition to be true.
Any suggestions ? I think the same can be achieved using nested DECODE however it will be too complex.

DECODE is easier to read then nested IIF. It may or may not be faster, that depends. Anyway you can build it using the following pattern:
DECODE (True,
condition, value,
default)
Which in your case should go like this (please double-check):
DECODE(True,
UNIQUE_NUMBER = 40031 AND FLAG ='P' AND TYPE ='F', 44070,
UNIQUE_NUMBER = 40031 AND FLAG ='P' AND TYPE ='V' AND IN(VALUES ,'Z'),44072,
UNIQUE_NUMBER = 40031 AND FLAG ='P' AND TYPE ='V' AND NOT IN(VALUES ,'Z'),44074,
UNIQUE_NUMBER = 10110 AND FLAG ='R' AND TYPE ='F', 44071,
UNIQUE_NUMBER = 10110 AND FLAG ='R' AND TYPE ='V', 44071 AND IN(VALUES,'Z'), 44073,
UNIQUE_NUMBER = 10110 AND FLAG ='R' AND TYPE ='V', 44071 AND NOT IN(VALUES,'Z'), 44075
)

Related

Case within a Select returning "missing expression ORA-00905"

this is my first post here, I'd like to ask for help on a theoretically simple query.
The current query I'm creating is to try and generate a random number, which will be identified as even or odd. Depending on that value, it should print either "M" as even, or "W" as odd. Though when I try using a case inside the select, I'm getting the "missing keyword" error. This is my following code:
select
case
when mod(round(dbms_random.value(1,100)),2) = 0 then dbms_output.put_line('M');
when mod(round(dbms_random.value(1,100)),2) = 1 then dbms_output.put_line('W');
end
from dual
I've tried checking the website for similar problems, and while I've found similar problems and people getting the solution correctly, I don't quite know what I'm missing here. When I run the select alone, I get the even or odd number I want to get, but not when I try to print out a result.
SELECT statement cannot PRINT, it can only RETURN something.
You may use query like
select
v,
case when mod(v, 2) = 0 then 'M' else 'W' end l
from
(select round(dbms_random.value(1, 100)) v from dual)
and process it's result as you wish (print, for example).
Why are you trying to embed dbms_output in a query? Just write:
select
case
when mod(round(dbms_random.value(1,100)),2) = 0 then 'M'
when mod(round(dbms_random.value(1,100)),2) = 1 then 'W'
end
from dual
Also you know, since you are calling dbms_random two different times, you get two different values in the same query. If you want one value to be compared, then use a WITH clause
with rand_value as
( select round(dbms_random.value(1,100)) val from dual
)
select
case
when mod(val,2) = 0 then 'M'
when mod(val,2) = 1 then 'W'
end
from rand_value
You get the error because of the semicolons.
Also you are calling the random function twice and thus get two different random values. I would use IF-THEN-ELSE instead of a SELECT statement, since the latter one cannot print.
IF mod(round(dbms_random.value(1,100)),2) = 0 THEN
dbms_output.put_line('M');
ELSE
dbms_output.put_line('W');
END IF;

How to use CASE statement and a parameter in the WHERE clause?

I have an SSRS report where there is a parameter that asks the user to include records where revenue is greater than zero, or records with revenue values that are just zero.
Since the query is not a stored procedure and it is not an option to put it into a procedure, I need to use some case logic for the embedded query. I need to do this in the where clause in the end.
I am trying to do something like this:
SELECT * FROM TABLE
WHERE MY_DATE BETWEEN D_START AND D_END
AND
CASE
WHEN :REVENUE = 1 THEN REV != 0
WHEN :REVENUE = 2 THEN REV = 0
END
However, when I run this query I get the following error:
ORA-00905: missing keyword
Is what I am doing not possible? Or is there an error that someone can see and help me with?
Please help. Thanks!
UPDATE: Just to clarify, the user is passing a value of 1 or 2. And the query should filter the data according to what value is passed to it. If 1 is passed in the parameter, then filter out all revenue not equal to zero. Else if two is passed, then filter so that only records where revenue is zero is returned.
You can write it better with a bit of boolean logic:
SELECT * FROM TABLE
WHERE MY_DATE BETWEEN D_START AND D_END
AND (
(:REVENUE = 1 AND REV != 0)
OR
(:REVENUE = 2 AND REV = 0 )
)
CASE is meant to extract different values based on conditions, so you can use it to check conditions, but you need to use it as a value to check against a condition
It's not necessary to use a CASE expression to get this particular result.
But it is possible to make use of one.
The problem in the original query is that Oracle is more strict than other databases (like MySQL) in that Oracle doesn't implicitly convert a boolean expression to a value, or convert a value into boolean.
I suspect that Oracle is choking in a couple of places. The error message is only showing us one of those.
The CASE expression returns a value, and Oracle is balking that he won't evaluate the value as a boolean.
To get that value evaluated as a boolean, we could do a comparison of the value to some other value.
If we fix that, I think Oracle is still going to choke on the expression following THEN. Oracle is expecting to return a value, and it's finding a comparison, which evaluates to a boolean.
Okay, so we know the CASE expression needs to return a value, and we need to use that in a boolean expression. If we move that conditional test into the WHEN part, and specify a value to be returned in the THEN, we can compare the return from the CASE expression to another value.
(As an aside... I strongly recommend that you qualify the column references in the SQL statement. That makes the intent more clear. Looking at the statement, it looks like MY_DATE, D_START and D_END are all column references. That's perfectly valid, it just seems a bit odd to me.)
As an example, we could do something like this with the CASE expression:
SELECT t.*
FROM TABLE t
WHERE t.MY_DATE BETWEEN t.D_START AND t.D_END
AND CASE
WHEN ( :REVENUE = 1 AND t.REV != 0 ) THEN 1
WHEN ( :REVENUE = 2 AND t.REV = 0 ) THEN 1
ELSE NULL
END = 1
The parens inside the CASE aren't necessary; I just included them to highlight the part that Oracle is evaluating in a boolean context.
So, does that work? If the value passed in for :REVENUE is 2, the condition in the first WHEN won't evaluate to TRUE (the result of first comparison is guaranteed to be FALSE). The condition in the second WHEN may evaluate to TRUE (first comparison will yield TRUE, the result from second comparison will depend on the value in the REV column.)
That CASE expression is either going to return a value of 1 or NULL. (We could just as easily use a 0 or a -1, or 999 in place of NULL if we wanted.)
Once the CASE expression is evaluated, the value returned will be compared to a literal value, as if we wrote e.g. val = 1. That comparison is evaluated as boolean. If it evaluates to TRUE, the row will be returned...
To get Oracle to behave similarly to other databases (like MySQL), we would need to make the conversion from boolean to value and value to boolean explicit. We would still need the return from the CASE compared to 1, like we did above. In place of REV != 0 we could use another CASE expression. I'm not recommending this, just shown here for illustration, converting a boolean to a value.
WHERE CASE
WHEN ( :REVENUE = 1 )
THEN CASE WHEN ( t.REV != 0 ) THEN 1 ELSE NULL END
WHEN ( :REVENUE = 2 )
THEN CASE WHEN ( t.REV = 0 ) THEN 1 ELSE NULL END
ELSE
NULL
END = 1
Note that the return from the outermost CASE expression is being compared to a value, so we get a boolean (where Oracle expects a boolean.)
All of the ELSE NULL in the statements above can be omitted for an equivalent result, since that's the default when ELSE is omitted.)
Again, it's not necessary to use a CASE expression. You can get equivalent results without it. For example:
SELECT t.*
FROM TABLE t
WHERE t.MY_DATE BETWEEN t.D_START AND t.D_END
AND ( ( :REVENUE = 1 AND t.REV != 0 )
OR ( :REVENUE = 2 AND t.REV = 0 )
)
In these queries that all return an equivalent result, the CASE expression doesn't buy us anything. But in some circumstances, it can have some advantages over a regular OR, because the CASE expression stops evaluation when a condition in a WHEN clause evaluates to TRUE.
The problem is that Oracle SQL does not have the boolean data type, so you cannot have columns of type boolean, pass boolean parameters to a query, have boolean expressions etc. So they have the somewhat unnatural concept of "condition" which is something that goes into logical conditions (like in the WHERE clause). Unfortunately, when they introduced the case EXPRESSION, which can be used wherever any other expression can be used (but this excludes boolean), they DID NOT introduce a "case CONDITION" - which could be used where other conditions can be used. This omission is odd, since the code for a case condition would probably use 95% of the code for the case expression. All the more weird since PL/SQL does have the boolean type, and the case expression there works seamlessly for Booleans.

Comparing values of type Text with values of type True/False

I have a data column of strings containing a lead status. I only want to count if the lead is qualified or nurture. I have this expression:
Is Qualified = If('Lead'[Status] = OR("Qualified", "Nurture"),1,0)
But I am getting this error:
DAX comparison operations do not support comparing values of type Text
with values of type True/False. Consider using the VALUE or FORMAT
function to convert one of the values.
I'm new with DAX and haven't been able to fix this one. Any help would be great, thanks.
OR() returns a boolean value. I assume 'Lead'[Status] is a text field, in which we will find some strings with the values "Qualified" or "Nurture". If this is the case you want to do the following:
IsQualified =
IF(
'Lead'[Status] = "Qualified"
|| 'Lead'[Status] = "Nurture"
,1
0
)
This is performing two tests, and combining them with a logical or ( || - the double pipe is DAX's or operator ).

Decode getting ORA-00938 error

My current SQL is as below:
CASE
WHEN PARENT.ASLNO IS NULL THEN SUBCATEGORIES.SUBCATEGORY_LIST
-- #5098
ELSE DECODE(ASL.CATEGORY_NAME, null,
NVL(SUBCATEGORIES.SUBCATEGORY_LIST,
SUBCATEGORIES_PARENT.SUBCATEGORY_LIST),
decode(SUBCATEGORIES.SUBCATEGORY_LIST,null,null,'N/A'))
-- End #5098
END AS SUPSPD_SUBCATEGORY_LIST
I am trying to change the following sql
DECODE(ASL.CATEGORY_NAME, null,
NVL(SUBCATEGORIES.SUBCATEGORY_LIST,
SUBCATEGORIES_PARENT.SUBCATEGORY_LIST),
decode(SUBCATEGORIES.SUBCATEGORY_LIST,null,null,'N/A'))
to
DECODE(ASL.CATEGORY_NAME, null,
DECODE(SUBCATEGORIES.SUBCATEGORY_LIST,
SUBCATEGORIES_PARENT.SUBCATEGORY_LIST),
decode(SUBCATEGORIES.SUBCATEGORY_LIST,null,null,'N/A'))
but I am getting ORA-00938 not enough arguments for function?
This:
NVL(SUBCATEGORIES.SUBCATEGORY_LIST,
SUBCATEGORIES_PARENT.SUBCATEGORY_LIST)
returns the parent subcategory list if the child's is null.
Decode needs at least three argumentsm but you're only supplied two; you have the first search value but no result, and no default either, which means you don't always get a value back.
The equivalent for your NVL would be:
DECODE(SUBCATEGORIES.SUBCATEGORY_LIST, NULL,
SUBCATEGORIES_PARENT.SUBCATEGORY_LIST, SUBCATEGORIES.SUBCATEGORY_LIS),
I'm not really sure why you'd want to make the statement longer and a bit harder to understand... for some consistency I might even be tempted to change
decode(SUBCATEGORIES.SUBCATEGORY_LIST,null,null,'N/A')
to
NVL2(SUBCATEGORIES.SUBCATEGORY_LIST, 'N/A', null)
You have changed:
NVL(SUBCATEGORIES.SUBCATEGORY_LIST, SUBCATEGORIES_PARENT.SUBCATEGORY_LIST)
to:
DECODE(SUBCATEGORIES.SUBCATEGORY_LIST, SUBCATEGORIES_PARENT.SUBCATEGORY_LIST)
DECODE needs at least 3 arguments.
Aside
I find it much easier to debug complex expressions like this by laying them out nicely just like any other code:
DECODE( ASL.CATEGORY_NAME
, null
, DECODE ( SUBCATEGORIES.SUBCATEGORY_LIST
, SUBCATEGORIES_PARENT.SUBCATEGORY_LIST
)
, decode ( SUBCATEGORIES.SUBCATEGORY_LIST
, null
, null
, 'N/A'
)
)

VBscript select case for combobox

He there, I'm new to VB script and I am trying to make a select case to change an emailadress to a combobox choice. I know i'm thinking to easy but i need help with the direction. the combobox works but i cannot get the value chosen in the combobox to trigger the select case.
Sub Item_Open()
Set FormPage = Item.GetInspector.ModifiedFormPages("Message")
Set Control = FormPage.Controls("Subject")
Control.PossibleValues = "SPOED;STATUS;MANCO;KLACHT;TRANSPORT;TRACKING;INKOMEND;REPARATIE;RETOUREN;LADEN;MILKRUN"
Set MyPage = Item.GetInspector.ModifiedFormPages("Message")
Set Mail = MyPage.Item("Subject").Value
Select Case Mail
Case SPOED
Item.To = "hihi#blabla.com"
Case STATUS
Item.To = "haha#blabla.com"
Case else
Item.To = ""
End Select
End Sub
Assuming MyPage.Item("Subject").Value returns a string value like "STATUS". Then you must pick it up in a string variable:
strMail = MyPage.Item("Subject").Value ' look ma, no Set!
The Select Case X statement evaluates the X expression and compares it to the values Y, ... in the Case Y parts and executes the first block for which (the values of) X and Y are equal. To apply this to strMail containing strings like "SPOED", the Case Y expressions should be string literals:
Select Case strMail
Case "SPOED"
...
Case "STATUS"
...
If you would have used Option Explicit, VBScript would have told, that SPOED (etc) is (understood as) an unitialized variable that can't be equal to a (decent) strMail.

Resources