IIF Statment returning false part in SSRS 2005 - reportingservices-2005

Below is the VB Expression Code for a field in my SSRS 2005 Report. This Expression Code returns only the False Part of the IIF Statement. But there is no reason why it should not return the true part as it is Referencing the correct colomn which contains data.
VB CODE
=IIF(CBOOL(Fields!OverallCPT.Value) = TRUE OR Fields!OverallCPT.Value > 0 OR Fields!OverallCPT.Value <> 0,
FORMAT((AVG(Fields!CPT_Time.Value) / 60000),"00") & ":" & FORMAT((AVG(Fields!CPT_Time.Value) mod 60000/1000),"00") ,Nothing)
Below is parts of the dataset I am using to get the data into a usable format.
SQL DATA SET CODE
Convert(Bigint,DatePart(minute,[Arrival Time]) * 60000) + Convert(Bigint,Datepart(second,[Arrival Time])*1000) AS 'CPT Time'
Why would this IIF statement return false when the Data Set returns a value for the conditions I supply in the IIF Statement.

Try changing your IIF for debugging purposes to this:
=IIF(TRUE,1,0)
If you are still getting unexpected results, I would suggest that your "true" and "false" outcomes may be in the wrong positions. (You did not specify which you intended to get back when the condition is true - the proper syntax is if condition first, then true outcome, and finally false outcome)
If not, then you have a bug in either your if condition, or in your calculations of OverallCPT. You may also want to verify that [Arrival Time] contains the value(s) you expect. Your if condition looks syntactically correct, but I can't be certain that it's what you intended it to be without more information.

Related

Oracle CASE statements

I'm trying to write a conditional statement in Oracle. There's a table for customers' accounts.
The logic is: If the Account_Close_Date contains values, it means the account has been closed by the customer, so the 'Status' should be "closed". Otherwise, the 'Status' should be "Open".
I write something like this:
select
CASE Account_Close_Date WHEN null THEN 'Open'
ELSE 'Closed' END as Status,
Account_Close_Date
from customer_account_Table
However, it doesn't work. The "Status" is all "closed", even if there is no value in "Account_Close_Date".
CASE "statements" do exist, but only in PL/SQL, not in plain SQL. What you have in your SELECT statement is an example of a CASE expression.
CASE expressions have two syntactical forms: searched and simple. You have an example of a simple CASE expression, one where the conditions are equality conditions. Problem is, in the three-valued logic of SQL, nothing is ever equal to NULL. Your condition is "if so-and-so-date equals NULL, then..." which is never TRUE.
Instead, use the searched syntax (already shown in a comment under your question):
CASE WHEN so-and-so-date IS NULL THEN ... ELSE ... END as ...
Try to use brackets:
SELECT Account_Close_Date, (CASE WHEN Account_Close_Date IS NULL THEN 'Open' ELSE 'Closed' END) as status FROM customer_account_Table;
See http://sqlfiddle.com/#!4/186d47/9

How can I use multiple iif in SSRS report?

I have an IIF expression I am trying to use ...
=iif(sum(Fields!Actual.Value) > 0,"Increased",
iif(sum(Fields!Actual.Value) < 0,"Decreased",
iif(sum(Fields!Actual.Value) = 0,"No Change","None")))
or iif(isnothing(sum(Fields!Actual.Value)),"N/ap","None")
This is throwing me an error. Is there any other workaround for this?
In cases like this it's much easier to use SWITCH. Switch uses pairs of expressions to evaluate and values to return. It's much easier to read and requires no nesting normally.
So for you example you can do something like this.
=SWITCH (
SUM(Fields!Actual.Value) > 0, "Increased",
SUM(Fields!Actual.Value) < 0, "Decreased",
SUM(Fields!Actual.Value) = 0, "No Change",
ISNOTHING(SUM(Fields!Actual.Value)) , "N/ap",
True, "None"
)
The True at the end basicaly acts like an ELSE, it captures anything that does not match previous expressions.
SWITCH stops when it finds the first match so depending on result, you may have to alter the order or each check but start with this and see where you get.

SSRS - Filtering an Integer With Both a String and a Boolean Parameter

I have a Boolean parameter called WLH where if True then it should ignore everything but if False then it should show a 0 for every craft textbox in a row that has the word "LABORER" in it. This is the expression that I am using but it doesn't seem to be doing anything. Can I get help on making it work? What am I doing wrong?
=IIF(Parameters!WLH.Value = false AND ReportItems!craft.Value LIKE "*laborer*", 0, ---main calculation for the else statement---)
Two things I see with this expression that need closer attention.
Parameters!WLH.Value = CBool("false"): The false side of the equality test needs to be converted to a boolean type with the CBool (conver to boolean) function.
ReportItems!craft.Value.IndexOf("laborer") >= 0: SSRS doesn't support LIKE in expressions but we can test for the existance of a substring in this manner. What this is doing is looking for the index (where the string "laborer" starts) in the field value and checking for a value greater than 0. This would mean that "laborer" was found while a value other than a positive integer means that the string "laborer" was not found.
I don't have SSRS installed on this machine to double check so post a comment if you still need help. Also note that IndexOf is case sensitive and that if you want to match to "Laborer" as well, you will have to do a case conversion prior to the IndexOf.
Full expression:
=IIF(Parameters!WLH.Value = CBool("false") AND ReportItems!craft.Value.IndexOf("laborer") >= 0, 0, ---main calculation for the else statement---)
EDIT: To deal with case sensitivity
Use "UCase()" to convert your field to upper case and then test only against "LABORER".
=IIF(Parameters!WLH.Value = CBool("false") AND UCase(ReportItems!craft.Value).IndexOf("LABORER") >=0, 0, ---main calculation for the else statement---)

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.

vbscript Type mismatch error when calling function

I am running into the Type Mismatch error when I attempt to call a function I created.
Example:
Function DoThis(paramA, paramB, paramC)
If paramA = "Something" Then
DoThis = DoSomething
ElseIf paramA = "This" Then
DoThis = DoSomethingDifferent
Else
DoThis = DoThisOtherThing
End If
End Function
Dim result: result = DoThis(valueA, ValueB, ValueC)
Can anyone see what my mistake could be? Other functions are working correctly. I have double checked the spelling by actually copying and pasting the function name where I call it. I have verified that the function name is not used anywhere else, i.e., as a constant or something else.
Note that when debugging this the ValType for all arguments is vbString. Also I am never able to enter the function, so it is not like I am debugging the function, enter it and then get the type mismatch.
ty.
VBScript has only one data type called a Variant. A Variant is a special kind of data type that can contain different kinds of information, depending on how it is used. Because Variant is the only data type in VBScript, it is also the data type returned by all functions in VBScript.
There are some subtypes of data that a Variant can contain (e.g. Empty, Null, string, integer, object, array etc.) You can use some conversion functions to convert data from one subtype to another, if that conversion is not implicit in VBScript. Now, pay your attention to real, factual data subtype of True and vbTrue.
The True keyword (boolean literal) has a value (inner representation) equal to -1.
On the other hand, vbTrue is one of few built-in constants and, in despite of it's name, has a subtype of Integer! It's one of so-called Tristate Constants:
Constant Value Description
vbUseDefault -2 Use default from computer's regional settings.
vbTrue -1 True
vbFalse 0 False
I hope next code could make clear all above statements:
Wscript.Echo _
vbTrue, CStr( vbTrue), VarType( vbTrue), TypeName( vbTrue) , _
vbNewLine, True, CStr( True), VarType( True), TypeName( True)
However, used with If _condition_ Then ..., there are some particularities; in brief:
The Then part of the If ... statement conditionally executes groups of statements only when a single test If condition is not False, i.e. any non-zero number esteems to be true, not only -1. Therefore you are able to use whatever variable or expression (numeric or string) you choose as long as the result is numeric...
Summarizing: If _expr_ Then ... is the same as
If CBool(_expr_) Then ...
The reason why retval is retuning mismatch error because it has a numeric value and an alpha value and wsh does not like that.
A sure way to get a type mismatch error for the published code is to define DoSomething etc. as Subs (which seems probable, given the names).
I cannot explain why this was a problem, but today I reduced the function down to a simple boolean return value and I still got the type mismatch error.
So I then created a new function with the same parameters and such. When I changed the call to the new function the error goes away.
My original function with the simple boolean return:(MISMATCH ERROR)
Function IsInstalledCheck(valueToCheck, expectedValue, checkType)
IsInstalledCheck = vbFalse
End Function
My new function with the a simple return:(Works)
Function IsItemInstalled(valueToCheck, expectedValue, checkType)
IsItemInstalled = vbFalse
End Function
EDIT
Note that I had tried this with the standard True / False values as well. The solution was to simply recreated the same function with a new name and for whatever magical reason that worked. The function signature was the same, the order of variables, variable names, the test conditions, everything in the body of the new function is the same.

Resources