Checking empty and or missing field value in JSON with DataWeave - json

Hi I am transforming JSON to JSON with Dataweave in Mulesoft 3.8.4. I am working with the following lines in JSON (part of a larger file)
..
"someField": "12",
"otherField": "5441",
..
I want to format 'someField' to a zero left padded string with a total length of 4 (0012). I also want to concat that value to the otherField that also needs to be left padded but with a total length of 6.
To prevent the padding and concatenating to fail I have to check if the field is present, not empty and it has to be numeric.
I have the following code:
"My Number": someField as :number as :string {format: "0000"} ++ otherField as :number as :string {format: "0000"}
when somefield != null
and someField != ""
and someField is :number
and otherField != null
and otherField != ""
and otherField is :number
otherwise "",
But this fails because 'is :number' returns false because actually the value is a string. Checking something like 'and someField as :number is :number' also fails when the value is empty. What's the best way to check?
Thanx for helping out.
John

Okay I figured it out myself. The part that was mostly in the way was to see if the value was a number. As the node in JSON could be non existing, empty or a text it was difficult to be able to do these tests in one when-otherwise.
What was also a requirement is that there always should be a returning value. So skipping when null was not an option.
Changing the number test into a regex helped. To also make the code more readable I also added some functions that I could also re-use.
The code now looks like this:
%function repeat(char, times) (char ++ repeat(char, times - 1)) when times > 0 otherwise ""
%function pad(field, count) field as :number as :string {format: repeat('0', count)}
%function toNumber(value, count) (pad(value, count)
when value matches /^\d+$/
otherwise "")
...
"My Number" : "" when someField == null
otherwise "" when otherField == null
otherwise toNumber(someField, 4) ++
toNumber(filterUpper(otherField), 6),
...
The repeat function gives a string of n-th repeated characters. The pad function left pads my number converted to string with zero's. In this function I use the repeat function to provide the format with the variable zero's string.
The toNumber is a check that see if we only use numbers.
Hope someone else can also benefit from this.

Related

Octave: How to correctly make string as a condition?

I was trying the if test for the first time, well actually so does with function.
Here's the script:
function trial()
I = input("f INPUT > Manually input frequency value? (yes/no):");
if I = "yes";
f = input("Please input the frequency value : \n")
elseif I = "no";
f = randi([100 1000],5,5)
endif
O = 2*pi*f;
fprintf("%.2f \n",O);
plot(f,O);
xlabel("Frequency");
ylabel("Angular Frequency");
end
f INPUT > Manually input frequency value? (yes/no):"no"
Please input the frequency value :
There are 2 things that I don't understand:
Why do I have to write the condition with quotation marks? (i.e "yes" not yes or "no" not no).
Why the 'no' condition ran the input command when it should've been randi?
Can someone show me how it should be done?
I = "yes" assigns the string "yes" to the variable I. To make a comparison, use == like this: I == "yes". But this comparison will only work if the two strings are the same length, and will return an array, not a single equality value. Use strcmp to compare strings: if strcmp(I, "yes").
The input function parses what the user types, so that typing 3 will result in the number 3, not the string "3". If you add a second input argument like this: input("prompt","s") then it will not parse the input, and return a string. The user will then be able to type no. See the docs.

Return true when query gives 1

I want to save a true/false in my MySQL database. I'm saving 1/0 in an INT column to do this. When I select it, I get the 1 or 0, but I want it to return true/false to my PHP code, without having to rewrite the database.
Can I use another column type? Should I save it differently?
Update: My question is about not wanting to rewrite the returned value. I'm getting a lot of results from my database. Many of those are true/false, but some are 0s because the price is 0, so I don't want to universally rewrite all 1s and 0s. I also don't want to manually rewrite 10 columns.
To follow up my comment, here's a more detailed response which also covers the PHP side, although this probably belongs on StackOverflow.
I've always just used tinyint, although you can use bool/boolean which are synonyms for tinyint(1)
However as of MySQL 5.0.3 you can use the bit type:
As of MySQL 5.0.3, the BIT data type is used to store bit-field values. A type of BIT(M) enables storage of M-bit values. M can range from 1 to 64.
Next, assuming you have an active column, perhaps to store if a user is active, you could use PHP's automatic type conversion to handle this quite simply.
// Obviously you'd replace this with your database call
$results = [['active' => 1], ['active' => 0]];
foreach($results as $row) {
if ($row['active'] == true) {
echo "true\n";
}
else {
echo "false\n";
}
}
You don't strictly need to do anything.
PHP does not, and can not, use strongly typed variables. So, if you receive an (int) 1 from your query results, you can simply use this 1 as a boolean without rewriting or changing anything.
$intOne = (int) 1; //explicitly treat the variable as an integer
var_dump((bool) $intOne); //treat the variable as a boolean
When used in any boolean context, like if ($variable)... then any of these types will be considered to be false by PHP:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
... And, most importantly;
Every other value is considered TRUE (including any resource).
Source: PHP Manual > Booleans (english)
So while you can change the storage type of your column in mysql, this won't really change the way PHP handles the variable retrieved from your results at all.
Historically, I've always used a column of type TINYINT(1) to store boolean values in mysql, and as Tom Green points out, recent mysql versions provide a new BIT type, which might be appropriate. To the best of my knowledge, mysql does not currently have an actual boolean data type.
You could just as easily use a column of type VARCHAR(1), though, because PHP can and will use any value as a boolean, thanks to the glorious, majestic, and sometimes maddening, PHP Type Juggling.
If you're trying to use the values you're retrieving for boolean logic, just use the values you receive from mysql like booleans and it will work:
if ($valueFromResults) {
//The value was something like true
} else {
//The value was something like false
}
If you're trying to actually echo out the words "true" and "false", then you're probably best served by explicitly echoing the words out yourself, like this;
if ($valueFromResults) {
echo "true";
} else {
echo "false";
}
or, in my preferred shorthand;
echo ($valueFromResults) ? "true" : "false" ;
Update You mentioned in a comment that you want to pass the values through json_encode() and use them in javascript.
JavaScript treats any real value, like int 1, as true and any empty value, like int 0, or an empty string, as false. So if your json_encode() output gets used in actual JavaScript, the int values will still work as boolean values. So the integer values from your database should still work as they are.
Just check that your integer results are encoded as integers by PHP and not as strings - they should be encoded correctly by default - because "0" == true in javascript, but 0 == false.
For a boolean value (true/false), you should use the mySql type bit or tinyint(1).
$boolean = $mysql_data ? true : false;

Replace #Error or NAN with -(hyphen) in SSRS

When i get a value into the text box (say "NAN" or "#Err") i want to replace it with -(hyphen).
How to achieve this in SSRS reporting ?
Thanks in advance.
You'll need to write an expression to handle it. Ideally, you would have some custom code function in your report (ie. Code.SafeDivision())
=iif(Fields!denominator.Value = 0, "-", Numerator / Denominator)
To elaborate on cmotley's answer, add the following as custom code to your report (to do this go to report properties, then code and then paste this in):
Function SafeDivide(value1 As Decimal, value2 As Decimal) As Decimal
If (value1 <> 0.0 And value2 <> 0.0) Then
Return value1 / value2
Else
Return 0
End If
End Function
Then you can use this in your textboxes to divide without receiving not a number and/or error, for example, adding the following as an expression (changing textbox names as required):
=Code.SafeDivide(ReportItems!Textbox186.Value, ReportItems!Textbox184.Value)
Divides two textboxes using our function.
To show a dash you can simply change the formatting of your textbox to 'number' and tick the box indicating that you'd like to replace '0' with '-'.
Alternatively if for some reason 'NaN' is coming through explicitly from a datasource (rare but not impossible when referencing a loaded table in SharePoint) you could use the following:
Function evalutator(value as String) as String
Select Case value
Case "NaN"
Return "-"
Case "NAN"
Return "-"
End Select
Return value
End Function
What about:
=IIF(Fields!yourcolumnname.Value = 0, "-", Fields!yourcolumnname.Value*1)
Or if you wanted zero's where you get NAN/#ERROR then you could use:
=IIF(Fields!yourcolumnname.Value = 0, Fields!yourcolumnname.Value*1, Fields!yourcolumnname.Value)

How does string truthiness work in MySQL?

I wanted to look for records where a certain string field was not blank or null, so I simply wrote SELECT ... FROM myTable WHERE x, assuming that blank and null strings would evaluate to false, but that doesn't appear to be the case.
The string "02306" is true, whereas "N06097EIP" is somehow false.
What's going on?
Edit: I'm aware of the workarounds, I simply want to know how the casting works.
In these expression string are first converted to numbers. "02306" is converted to 2306 which is >0 and therefore considered true, while "N06097EIP" (starting with non-digit) is converted to 0, which is evaluated as false.
Compare results of:
select convert("N06097EIP",signed)
and
select convert("02306",signed)
In a boolean context, such as
WHERE x
the expression x will be evaluated as an integer value. Note that MySQL considers a BOOLEAN as a numeric type.
http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html
It doesn't matter what type the expression x is; it's either an INTEGER type, or it will be converted to an INTEGER type, according to the documented conversion rules.
The end result is that the expression x will be evaluated to be either NULL, integer zero, or integer non-zero.
And those correspond to the boolean "truthiness" values of NULL, FALSE and TRUE.
The reason '02306' is considered TRUE is because this string converts to integer value 2306, which is non-zero.
The reason 'N06097EIP' is considered FALSE is because this string converts to integer value 0.
To can run a simple test case to verify:
SELECT IF( 0 = 'N06097EIP', 'is zero', 'is not zero')
SELECT 0 = 'N06097EIP'
The behavior you observe is entirely expected. It's all pretty straightforward. You may have been caught unawares, because the normative pattern is for us to avoid this type of evaluation and to instead use "workarounds" (as you put it) to return a boolean.
Don't try to be too cute about this with syntactic shortcuts. If nothing else, it's always harder on the next developer who has to figure out what you were doing.
Just spell out what you want.
SELECT *
FROM myTable
WHERE x IS NOT NULL AND x <> '';
or, if you'd prefer:
SELECT *
FROM myTable
WHERE COALESCE(x, '') <> '';

Access Vba - To find null and blank values

I am trying to find the blank values and null values in a table. I am using Asc to assign the values of the table to a variable and then based on their ASCII values differentiating null and blank. But I am getting "runtime error 94: Invalid use of null" when the code tries to read the ASCII value of a null field.
When I have to deal with return values that can be either Null or zero-length string, I use a function that converts ZLS to Null:
Public Function varZLStoNull(varInput As Variant) As Variant
If Len(varInput) = 0 Then
varZLStoNull = Null
Else
varZLStoNull = varInput
End If
End Function
This takes advantage of the fact that the VBA Len() function treats a Null and a ZLS exactly the same so that you don't have to handle each case individually.
However, remember that if you use this in a WHERE clause, you'll be losing performance because it can't use the indexes. Thus, in a WHERE clause, you'd test for IS NULL or =""
SELECT MyField
FROM MyTable
WHERE MyField Is Null Or MyField = ""
That will be much more efficient. The varZLSToNull function is most useful when you're appending processed data to a field that has ZLS Allowed set to NO (as it should).
Another thing you should consider is changing your field so that it disallows ZLS, then running a query (using the WHERE clause above without the Is Null) to replace all the ZLS's with Nulls.
Of course, that assumes that your data is not distinguishing between Null and ZLS as meaning two different things (Null meaning "we haven't recorded any value here" and ZLS meaning "we have recorded an empty value here").
You can try the following user-defined function to test the table value:
Public Function text_test(str_in as Variant) As Long
' given input str_in, return -2 if input is Null,
' -1 if input is zero-length string; otherwise return 0
' use function Nz to test if input is Null and return -2,
' otherwise check non-null value with Len
' and return -1 if it is a 0-length string,
' otherwise return 0 for anything else
text_test = IIf(Nz([str_in], "null") = "null", -2, _
IIf(Len(str_in) = 0, -1, 0))
End Function
In the immediate window run a test with different inputs:
?text_test("fred");text_test("");text_test(Null);text_test(9);text_test(False)
Should return:
0 -1 -2 0 0
Note that you cannot use str_in as string in the function declaration since this will cause the same error you refer to in your question.
I think you should be using IsNull() to decide if a value is null.
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5034252.html
encapsulate your code inside a if statement and compare the string value to vbNullString like this:
If (Not (<string> = vbNullString) Then
if the string is NOT null execute your original code
if it is null add an Else block to execute what you need to do if the value is null
Yeah, it's an old thread, big deal...
This is the most concise way to test a value for Null and zero-length that I've seen:
FinalValue = IIf(Not Len(Nz(Value, "")) = 0, Value, Null)
How it might perform compared to David Fenton's excellent Function above, I do not know. I do know that the one-liner I present here and David's function do almost exactly the same thing. I suspect the one-liner might perform a bit better than a call out to a Function. On the other hand it makes use of an inclusive If, so it may in fact be slower. Who knows?
I use it in Class modules, mainly. For example, when creating a record with a DAO Recordset:
With rst
.AddNew
!JobCardID = IIf(Not m_JobCardID = 0, m_JobCardID, Null)
!ConstructionProjectID = IIf(Not m_ConstructionProjectID = 0, m_ConstructionProjectID, Null)
!MajorDisciplineID = IIf(Not m_MajorDisciplineID = 0, m_MajorDisciplineID, Null)
!ActivityDescriptorID = IIf(Not m_ActivityDescriptorID = 0, m_ActivityDescriptorID, Null)
!ActivityStatus = IIf(Not Len(Nz(m_ActivityStatus, "")) = 0, m_ActivityStatus, Null
'etc...
End With
In the above code, ActivityStatus is the relevant String.
Note: I never design a database with fields allowing zero-length strings. Repeat: NEVER.