I want to extract a specific part of a String, if the structure of that string is similar to a given example.
Each element works if tested solo, however if i try the WHERE clause as seen below its not working.
Is it possible that LIKE cant handle empty fields that well? Or am I missing something?
I’m using MS Access, therefore the Wildcards in LIKE are ‘?’
The Select Statement should grab a substring of the row “endpoint1”, from the given position to the next “:”
The WHERE Statement should only allow two different formats of that given substring
?_????_??
?_????_?
SQL:
SELECT
Mid(PLL.Endpoint1,7,(InStr(Mid(PLL.Endpoint1,7,10),":")-1))
FROM
[Test] AS PLL
WHERE
Mid(PLL.Endpoint1, 7, InStr(Mid(PLL.Endpoint1, 7, 10), ":") - 1) Like '?_????_??'
OR Mid(PLL.Endpoint1, 7, InStr(Mid(PLL.Endpoint1, 7, 10), ":") - 1) Like '?_????_?'
Issue is not with LIKE comparison.
If field is Null then InStr() will return Null. Mid() errors if result of InStr() is Null because its position arguments must be numeric. Could use Nz() to provide alternate value:
InStr(Mid(Nz(PLL.Endpoint1, ""), 7, 10), ":")
Now if your full expression returns Null, record will not be retrieved since comparing to Null returns Null. Null is not True therefore the record will be excluded same as False.
Related
I have a text column that has a data value (int) within it that I need to parse out. The problem is that it is not in the same character column, so a simple substring(x, 180, 5) won't work as it sometimes will return a character as well.
The data value always comes after the phrase 'value received:'.
Is it possible to parse the value out whereby SQL will take the next 3 values after this wording? Or even better, can you "catch" the value between two words? As before the value is a : and after the value there is always the word "complete".
You can use something like this:
select substring(x, charindex('value received', x) + 14, 5)
Without sample data, this might be off by a character or two.
I have a set of tablix results that im trying to filter based on OR condition but im having difficulty combining the two into one custom expression. [IsSafetyObservation] is just a boolean field and [Department] needs to be part of the multi-selected parameter values of [#Department]. Here's a screenshot of what it looks like as two separate filters but this is doing AND condition. When I tried to write custom expression I'm not using the write syntax because I get a red line when I try to reference the #Department parameter
tablix filter screenshot
custom expression attempt
You'll need to combine your expressions into one as you tried but instead of using IN, you should use InStr. InStr searches for a string inside another string and returns the position or 0 if not found.
First you would need to combine your parameters into a string using JOIN.
JOIN(Parameters!Department.Value, ",")
This will combine your parameters into a single string that you can now search for the Department field in the Department parameter.
InStr(JOIN(Parameters!Department.Value, ","), Fields!Department.Value) > 0
Also, SSRS doesn't always work well with Booleans (ugh) - so an expression of = (1 = 1) may work in some places for a Boolean result but not others so it's best to specify:
=IIF(InStr(JOIN(Parameters!Department.Value, ","), Fields!Department.Value) > 0
OR Fields!IsSafetyObservation.Value = False,
True,
False)
I have this query
SELECT text
FROM book
WHERE lyrics IS NULL
AND MOD(TO_NUMBER(SUBSTR(text,18,16)),5) = 1
sometimes the string is something like this $OK$OK$OK$OK$OK$OK$OK, sometimes something like #P,351811040302663;E,101;D,07112018134733,07012018144712;G,4908611,50930248,207,990;M,79379;S,0;IO,3,0,0
if I would like to know if it is possible to prevent ORA-01722: invalid number, because is some causes the char in that position is not a number.
I run this query inside a procedure a process all the rows in a cursor, if 1 row is not a number I can't process any row
You could use VALIDATE_CONVERSION if it's Oracle 12c Release 2 (12.2),
WITH book(text) AS
(SELECT '#P,351811040302663;E,101;D,07112018134733,07012018144712;G,4908611,50930248,207,990;M,79379;S,0;IO,3,0,0'
FROM DUAL
UNION ALL SELECT '$OK$OK$OK$OK$OK$OK$OK'
FROM DUAL
UNION ALL SELECT '12I45678912B456781234567812345671'
FROM DUAL)
SELECT *
FROM book
WHERE CASE
WHEN VALIDATE_CONVERSION(SUBSTR(text,18,16) AS NUMBER) = 1
THEN MOD(TO_NUMBER(SUBSTR(text,18,16)),5)
ELSE 0
END = 1 ;
Output
TEXT
12I45678912B456781234567812345671
Assuming the condition should be true if and only if the 16-character substring starting at position 18 is made up of 16 digits, and the number is equal to 1 modulo 5, then you could write it like this:
...
where .....
and case when translate(substr(text, 18, 16), 'z0123456789', 'z') is null
and substr(text, 33, 1) in ('1', '6')
then 1 end
= 1
This will check that the substring is made up of all-digits: the translate() function will replace every occurrence of z in the string with itself, and every occurrence of 0, 1, ..., 9 with nothing (it will simply remove them). The odd-looking z is needed due to Oracle's odd implementation of NULL and empty strings (you can use any other character instead of z, but you need some character so no argument to translate() is NULL). Then - the substring is made up of all-digits if and only if the result of this translation is null (an empty string). And you still check to see if the last character is 1 or 6.
Note that I didn't use any regular expressions; this is important if you have a large amount of data, since standard string functions like translate() are much faster than regular expression functions. Also, everything is based on character data type - no math functions like mod(). (Same as in Thorsten's answer, which was only missing the first part of what I suggested here - checking to see that the entire substring is made up of digits.)
SELECT text
FROM book
WHERE lyrics IS NULL
AND case when regexp_like(SUBSTR(text,18,16),'^[^a-zA-Z]*$') then MOD(TO_NUMBER(SUBSTR(text,18,16)),5)
else null
end = 1;
I am working with a pretty badly designed table. I have a field called optional fields which for some reason has been used as a catch-all for someone who didn't want to create the table correctly.
I need to make a query where I look at this optional_fields value and do a comparison on the fifth value of the string in optional_fields.
The value from this field is something like NN14YN...N
My query would be something like:
SELECT COMPANY_NUMBER
FROM table
WHERE fifth character of OPtional Fields = 'Y'
Looking at the supported string functions in DB2 (according to the documentation for DB2 for Linux UNIX and Windows 9.7.0) it would seem that substr could be used:
SELECT COMPANY_NUMBER
FROM table
WHERE substr(optional_Fields,5,1) = 'Y'
In addition to the great answer from #jpw, if you for some reason need to check multiple positions within the string (which I have unfortunately had to do at one time), you can use an IN, and invert the "normal" order, like so:
...
WHERE 'Y' in (
substr(t.flags_field, 123, 1)
,substr(t.flags_field, 19, 1)
,substr(t.flags_field, 128, 1)
,substr(t.flags_field, 1, 1)
)
Just thought I would share. It surprised me the first time I used it!
I have a specific column in a table, it shall contains only numbers in Nvarchar that have a length of 3. Unfortunately, some users wrote '12' but they should have written '012'. There were not enough validation at the time.
I need to fix that. Here is the logic I used :
UPDATE [Mandats_Approvisionnement].[dbo].[ARTICLE_ECOLE]
SET [UNIT_ADM] = STUFF(UNIT_ADM, 0, 0, '0')
WHERE LEN(UNIT_ADM) = 2;
The error goes like :
Cannot insert the value NULL into column 'UNIT_ADM', table
'Mandats_Approvisionnement.dbo.ARTICLE_ECOLE'; column does not allow
nulls. UPDATE fails.
I can't see where the problem is, I verified and all the records contain at least 2 characters, so the STUFF function cannot returns null as there are no NULL records in that table column [unit_adm]... How do I make it work ?
It should be stuff(UNIT_ADM,1,0,'0') as stuff returns null if the start position is 0.
Citing the documentation:
If the start position or the length is negative, or if the starting
position is larger than length of the first string, a null string is
returned. If the start position is 0, a null value is returned.
You could make this simpler by using
right('0' + UNIT_ADM, 3)
instead of stuff.