How to use AND in a CASE sqlite statement for validation check? - sqlite

I'v a SQLite database and I want to generate a kind of validation check.
The main target is to compare three fields in a table. If stnd_sht has the value 'nicht gegeben' then there should be a entry either in mass_sof of in mass_6m, if not then plausibility is not given.
So far I tried the following:
SELECT
b.baum_id AS baum_id,
CASE
WHEN b.stnd_sht ='nicht gegeben' AND b.mass_sof IS NULL THEN 'fehler'
WHEN b.stnd_sht ='nicht gegeben' AND b.mass_6m IS NULL THEN 'fehler'
ELSE 'plausibel' END AS plaus
FROM baeume b;
and...
SELECT
b.baum_id AS baum_id,
CASE WHEN (b.mass_sof IS NULL OR b.mass_6m IS NULL) AND b.stnd_sht ='nicht gegeben' THEN 'fehler'
ELSE 'plausibel' END AS plaus
FROM baeume b;
Everything works fine without any AND or OR operator but as I add additional expressions the result is not correct.
Is the AND operator not supportet by the CASE statement, or am I totaly wrong and the statement needs another structure or has to be more complex?
Thanks in advance, Patrick

These expressions are syntactically correct, but do not correspond to the explanation.
Sometimes, it helps to reverse a logical condition.
According to the explanation, there is an error if stnd_sht is nicht gegeben and if both the mass_sof and mass_6m values are NULL.
This would correspond to the following expression:
SELECT baum_id,
CASE WHEN stnd_sht = 'nicht gegeben' AND
mass_sof IS NULL AND
mass_6m IS NULL
THEN 'fehler'
ELSE 'plausibel'
END AS plaus
FROM baeume;
This could be simplified a little:
SELECT baum_id,
CASE WHEN stnd_sht = 'nicht gegeben' AND
COALESCE(mass_sof, mass_6m) IS NULL
THEN 'fehler'
ELSE 'plausibel'
END AS plaus
FROM baeume;

Related

Adding more "AND" conditions to FOR LAST causing performance issue

I'm new to progress 4GL. I'm trying to find last record from a table. But its causing performance issue. I directly copied my query here so it should be syntax error. Please help me to modify the logic or give me suggestion.
Note - Syntax(USE-SYNTAX) available only for following fields but not sure adding this to for last is good idea.
pc_domain,
pc_list_classification,
pc_list,
pc_curr,
pc_prod_line,
pc_part,
pc_um,
pc_start
for last pc_mstr no-lock
where pc_domain = global_domain
and pc_list_classification = 1
and pc_curr <> ""
and pc_part = b_ps_mstr.ps_comp
and pc_um <> ""
and (pc_start <= v_end[v_i]
or pc_start = ?)
and (pc_expire >= v_end[v_i]
or pc_expire = ?)
and (pc_amt_type = "L"
or pc_amt_type = "P"):
end.
if not available pc_mstr then
do:
for last pc_mstr no-lock
where pc_domain = global_domain
and pc_list_classification = 1
and pc_curr <> ""
and pc_part = b_ps_mstr.ps_comp
and pc_um <> ""
and (pc_amt_type = "L"
or pc_amt_type = "P"):
end.
end.
What do you mean with last? Do you mean LAST as in what Progress means:
LAST Uses the criteria in the record-phrase to find the last record in the table that meets that criteria. The AVM finds the last record before sorting.
Or do you mean something else? Like the last record created? Depending on what you mean you might have to do different things.
Some pointers about performance though:
Basically where clauses using = is good, >, <, >=, <=, BEGINS etc is decent and <>, NOT is BAD.
But it also boils down to what index you can use. You need to know about the indices of the table! But regardless of indices: those <> will make you unhappy. They will cause "table scans" (the entire table will be read).
<> "" could perhaps be replaced with > "" in this case - a little less evil.
Also you need to use () in a better way with those or's. Otherwise you might not get what you want. OR will win over AND so A AND B OR C really is run as (A AND B) OR C. Maybe you really ment A AND (B OR C) - in that case you need to use those ( ) wisely.

Select any character string over an NA in an If statement in R

I am trying to create a function which will look at two vectors of character labels, and print the appropriate label based on an If statement. I am running into an issue when one of the vectors is populated by NA.
I'll truncate my function:
eventTypepriority=function(a,b) {
if(is.na(a)) {print(b)}
if(is.na(b)) {print(a)}
if(a=="BW"& b=="BW",) {print("BW")}
if(a=="?BW"& b=="BW") {print("?BW")}
...#and so on
}
Some data:
a=c("Pm", "BW", "?BW")
b=c("PmDP","?BW",NA)
c=mapply(eventTypepriority, a,b, USE.NAMES = TRUE)
The function works fine for the first two, selecting the label I've designated in my if statements. However, when it gets to the third pair I receive this error:
Error in if (a == "?BW" & b == "BW") { :
missing value where TRUE/FALSE needed
I'm guessing this is because at that place, b=NA, and this is the first if statement, outside of the 'is.na' statements, that need it to ignore missing values.
Is there a way to handle this? I'd really rather not add conditional statements for every label and NA. I've also tried:
-is.null (same error message)
-Regular Expressions:
if(a==grepl([:print:]) & b==NA) {print(a)}
In various formats, including if(a==grepl(:print:)... No avail. I receive an 'Error: unexpected '[' or whatever character R didn't like first to tell me this is wrong.
All comments and thoughts would be appreciated. ^_^
if all your if conditions are exclusives, just call return() to avoid checking other conditions when one is met:
eventTypepriority=function(a,b) {
if(is.na(a)) {print(b);return()}
if(is.na(b)) {print(a);return()}
if(a=="BW"& b=="BW",) {print("BW");return()}
if(a=="?BW"& b=="BW") {print("?BW");return()}
...#and so on
}
You need to use if .. else statements instead of simply if; otherwise, your function will evaluate the 3rd and 4th lines even when one of the values is n/a.
Given you mapply statement, I also assume you want the function to output the corresponding label, not just print it?
In that case
eventTypepriority<-function(a,b) {
if(is.na(a)) b
else if(is.na(b)) a
else if(a=="BW"& b=="BW") "BW"
else if(a=="?BW"& b=="BW") "?BW"
else "..."
}
a=c("Pm", "BW", "?BW")
b=c("PmDP","?BW",NA)
c=mapply(eventTypepriority, a,b, USE.NAMES = T)
c
returns
Pm BW ?BW
"..." "..." "?BW"
If you actually want to just print the label and have your function return something else, you should be able to figure it out from here.

Handle Null condition

I want to handle null condition in below code.
lstTest.Discount = If((Not dataSet.Tables("History") Is Nothing),
If(IsDBNull(dataSet.Tables("History").Rows(0)("DiscountsAdjustmentsAmount")),
"$0.00",
StringToCurrency(GetContractualDiscount(dataSet.Tables("History").Rows(0)
("DiscountsAdjustmentsAmount"), dataSet.Tables("History").Rows(0)
("DiscountsAdjustments"), dataSet.Tables("History").Rows(0)
("EstimatedCharges")))), "$0.00")
My code is getting break at
dataSet.Tables("History").Rows(0)("DiscountsAdjustments")
since its value is null. I want to replace null value with "0.00"
Please help how can I handle.
Thanks
Rahul,
You will likely need to rewrite this part of it. Here is your original code:
lstTest.Discount = If((Not dataSet.Tables("History") Is Nothing),
If(IsDBNull(dataSet.Tables("History").Rows(0)("DiscountsAdjustmentsAmount")),
"$0.00",
StringToCurrency(GetContractualDiscount(dataSet.Tables("History").Rows(0)
("DiscountsAdjustmentsAmount"), dataSet.Tables("History").Rows(0)
("DiscountsAdjustments"), dataSet.Tables("History").Rows(0)
("EstimatedCharges")))), "$0.00")
Instead of this big nested mess... why not do it this way. Note I dont have a VB debugger in front of me so there may be some slight format adjustments, so consider this pseudo code:
Is the dataset valid
If Not IsDBNull(dataSet.Tables("History"))
''We know that we have data in our dataset
''Do all your checks
if Not isDBNull(dataSet.Tables("History").Rows(0)("Your field"))
''Do something
Else
''Show a 0
END IF
''REPEAT THE ABOVE LINES FOR EACH FIELD
End if
You can check for null on any column first using methods on the DataRow object:
Which of IsDBNull and IsNull should be used?

Controlling Empty Arrays in Classic ASP

OK I'm a complete newbie to ASP.
I have a client with different content loading depending on what is passed in an array.
select case lcase(arURL(4))
Sometimes though, arURL(4) might be empty, in them cases I'm getting the following error:
Error running function functionName(), the error was:
Subscript out of range
Does anybody know a way to fix this?
Thanks
OK further code as requested. It is horrible code and I don't mean to cause anybody a headache, so please excuse it. Thanks again ........
function GetContent()
dim strURL, arURL, strRetval
select case lcase(request.ServerVariables("URL"))
case "/content.asp"
strURL = ""
arURL = split(request.querystring("url"), "/")
if request("page") = "" then
select case lcase(arURL(2))
case "searches"
select case lcase(arURL(1))
case "looking"
select case lcase(arURL(3))
case "ohai"
strRetval = "Lorem"
case "blahblah"
strRetval = "Lorem Ipsum"
case "edinburgh"
select case lcase(arURL(4))
case "ohai"
strRetval = "Ipsum"
case "ohno"
strRetval = "Lorem"
end select
case "bristol"
select case lcase(arURL(4))
case "some_blahblah"
strRetval = "LOREM"
case "overthere"
strRetval = "LOREM"
case "blahblah"
strRetval = "LOREM"
end select
case "cambridge"
select case lcase(arURL(4))
case "some_rubbish"
strRetval = "Lorem"
end select
case else
strRetval = " "
end select
case else
strRetval = " "
end select
case else
strRetval = " "
end select
end if
end select
strRetval = strRetval & "<style>h2{border: 0px);</style>"
GetContent = strRetval
end function
You are using value passed over the querystring and split it by "/" character - when the value does not contain "enough" slashes, you will get error and the code will crash.
For example, if the querystring parameter url will be only "/something" then even arURL(2) will fail since the array has only two items. (First one is empty string, second is "something")
To avoid all this mess, best way I can advice is writing custom function that will take array and index as its arguments and return either the item in the given index if exists otherwise empty string:
Function GetItemSafe(myArray, desiredIndex, defValue)
If (desiredIndex < LBound(myArray)) Or (desiredIndex > UBound(myArray)) Then
If IsObject(defValue) Then
Set GetItemSafe = defValue
Else
GetItemSafe = defValue
End If
Else
If IsObject(myArray(desiredIndex)) Then
Set GetItemSafe = myArray(desiredIndex)
Else
GetItemSafe = myArray(desiredIndex)
End If
End If
End Function
(ended up with more generic version, letting the calling code decide what is the default value in case index is out of array range)
Having this, change your code to use the function instead of accessing the array directly.
This line for example:
select case lcase(arURL(2))
Should become this instead:
select case lcase(GetItemSafe(arURL, 2, ""))
Change the rest of those lines accordingly and you'll no longer get errors when the given value won't be valid.
What that error is saying at the most basic level is that you're trying to get information from an array element that doesn't exist, eg arURL may have been declared for 3 elements, but accessing the 4th generates the "subscript out of range" error.
If you're keying on the last element in the array, you might look at the UBound() function, which returns the high index element in an array, eg:
select case lcase(arURL(ubound(arURL))
However, there might be something else going on in the code that would change how you determine which element should be used as the target of the "select case," hence the suggestion to post more of the code.

How can I tell if E4X expression has a match or not?

I am trying to access an XMLList item and convert it to am XML object.
I am using this expression:
masonicXML.item.(#style_number == styleNum)
For example if there is a match everything works fine but if there is not a match then I get an error when I try cast it as XML saying that it has to be well formed. So I need to make sure that the expression gets a match before I cast it as XML. I tried setting it to an XMLList variable and checking if it as a text() propertie like this:
var defaultItem:XMLList = DataModel.instance.masonicXML.item.(#style_number == styleNum);
if(defaultItem.text())
{
DataModel.instance.selectedItem = XML(defaultItem);
}
But it still give me an error if theres no match. It works fine if there is a match.
THANKS!
In my experience, the simplest way to check for results is to grab the 0th element of the list and see if it's null.
Here is your code sample with a few tweaks. Notice that I've changed the type of defaultItem from XMLList to XML, and I'm assigning it to the 0th element of the list.
var defaultItem:XML =
DataModel.instance.masonicXML.item.(#style_number == styleNum)[0];
if( defaultItem != null )
{
DataModel.instance.selectedItem = defaultItem;
}
OK I got it to work with this:
if(String(defaultItem.#style_number).length)
Matt's null check is a good solution. (Unless there is the possibility of having null items within an XMLList.. probably not, but I haven't verified this.)
You can also check for the length of the XMLList without casting it to a String:
if (defaultItem.#style_number.length() > 0)
The difference to String and Array is that with an XMLList, length() is a method instead of a property.

Resources