Getting a string value that is between two characters - string

I need to get the value that is between !03 and !03.
Example:
JDC!0320151104!03OUT
I should get following string in return: 20151104
NOTE: The string isn't always 22 characters long, but I am only concerned with the value that is between !03 and !03.
This is what I have so far. I couldn't make any progress further than this:
SELECT
SUBSTRING(
RegStatsID,
CHARINDEX('!', RegStatsID) + 3,
CHARINDEX('!', REVERSE(RegStatsID))
)
From TableX

Great that you found a solution!
This might be better:
By replacing the "!03" with XML-tags you can easily pick the second "node". Your string will be transformed into <x>JDC</x><x>20151104</x><x>OUT</x>:
DECLARE #test VARCHAR(100)='JDC!0320151104!03OUT';
SELECT CAST('<x>' + REPLACE(#test,'!03','</x><x>') + '</x>' AS XML).value('/x[2]','datetime')
One advantage was to get the value between the two "!03" typed. In this case you get a "real" datetime back without any further casts. If the value there is not a datetime (or date) in all cases, you just use nvarchar(max) as type.
Another advantage was: If you - why ever - need the other values later, you just have them with .value('/x[1 or 3]'...)

I was able to get it right by doing following:
SELECT
SUBSTRING(
RegStatsID,
CHARINDEX('!', RegStatsID) + 3,
len(RegStatsID) - CHARINDEX('!', RegStatsID ) - 2 - CHARINDEX('!', Reverse(RegStatsID))
)

Related

LoadRunner Correlation 'Ord' random issue

I am able to capture the response using ord=All in web_reg_save_param.
case 1,
Input:12345
Response:["18/3/2017","20/2/2017","20/2/2016"].
case 2,
Input:98451
Response:["12/1/2017","01/1/2016"]
web_reg_save_param("date","LB=\"","RB=\"","ORD=ALL","LAST);
`
Captured Values are:
date_1:18/3/2017
date_2:,
date_3:20/2/2017
date_4:,
date_5:20/2/2016
Here is the task:
1) I need to fetch random date each time.
2) Date may vary depending upon the input(In case 1, 3 dates and case 2, 2 dates).
I have tried:
1) Correlating and using lr_paramarr_random() function- failed, it will fetch ',' at some point.
2) using for loop and if statement to find out odd/even position.
Using web_reg_save_param() function like you did will, of course, fetch a comma(',') since it is situated between two quote symbols(' " ').
You can use web_reg_save_param_regexp() function with the following regular expression:
"(\d{2}\/\d\/\d{4})"
Set the parameters: "Ordinal=All", "Group=1".
This function will extract the dates and store them into an array.
This time lr_paramarr_random() should return correct results because now your array contains nothing but dates.

how to use like and substring in where clause in sql

Hope one can help me and explain this query for me,
why the first query return result but the second does not:
EDIT:
first query:
select name from Items where name like '%abc%'
second Query:
select name from Items where name like substring('''%abc%''',1,10)
why the first return result but the second return nothing while
substring('''%abc%''',1,10)='%abc%'
If there are a logic behind that, Is there another approach to do something like the second query,
my porpuse is to transform a string like '''abc''' to 'abc' in order to use like statement,
You can concatenate strings to form your LIKE string. To trim the first 3 and last 3 characters from a string use the SUBSTRING and LEN functions. The following example assumes your match string is called #input and starts and ends with 3 quote marks that need to be removed to find a match:
select name from Items where name like '%' + SUBSTRING(#input, 3, LEN(#input) - 4) + '%'

Using REGEXP_SUBSTR to get key-value pair data

I have a column with below values,
User_Id=446^User_Input=L307-60#/25" AP^^
I am trying to get each individual value based on a specified key.
All value after User_Id= until it encounters ^
All value after User_Input= until it encounters ^
I tried for and so far I have this,
SELECT LTRIM(REGEXP_SUBSTR('User_Id=446^User_Input=L307-60#/25" AP^'
,'[0-9]+',1,1),'^') User_Id
from dual
How do I get the value for the User_Input??
P.S: User input can have anything, like ',", *,% including a ^ in the middle of the string (that is, not as a delimiter).
Any help would be greatly appreciated..
This can be easily solved using boring old INSTR to calculate the offsets of the start and end points for the KEY and VALUE strings.
The trick is to use the optional occurrence parameter to identify each the correct instance of =. Because the input can contain carets which aren't intended as delimiters we need to use a negative position to identify the last ^.
with cte as (
select kv
, instr(kv, '=', 1, 1)+1 as k_st -- first occurrence
, instr(kv, '^', 1) as k_end
, instr(kv, '=', 1, 2)+1 as v_st -- second occurrence
, instr(kv, '^', -1) as v_end -- counting from back
from t23
)
select substr(kv, k_st, k_end - k_st) as user_id
, substr(kv, v_st, v_end - v_st) as user_input
from cte
/
Here is the requisite SQL Fiddle to prove it works. I think it's much easier to understand than any regex equivalent.
If there is no particular need to use Regex, something like this returns the value.
WITH rslt AS (
SELECT 'User_Id=446^User_Input=L307-60#/25" AP^' val
FROM dual
)
SELECT LTRIM(SUBSTR(val
,INSTR(val, '=', 1, 2) + 1
,INSTR(val, '^', 1, 2) - (INSTR(val, '=', 1, 2) + 1)))
FROM rslt;
Of course, if you can't guarantee that there will not be any carets that are valid text characters, this will possibly return partial results.
Assuming that you will always have 'User_Id=' and 'User_Input=' in your string, I would use a character group approach to parsing
Use the starting anchor,^, and ending anchor, $. Look for 'User_Id=' and 'User_Input='
Associate the value you are searching for with a character group.
SCOTT#dev>
1 SELECT REGEXP_SUBSTR('User_Id=446^User_Input=L307-60#/25" AP^','^User_Id=(.*\^)User_Input=(.*\^)$',1, 1, NULL, 1) User_Id
2* FROM dual
SCOTT#dev> /
USER
====
446^
SCOTT#dev>
1 SELECT REGEXP_SUBSTR('User_Id=446^User_Input=L307-60#/25" AP^','^User_Id=(.*\^)User_Input=(.*\^)$',1, 1, NULL, 2) User_Input
2* FROM dual
SCOTT#dev> /
USER_INPUT
================
L307-60#/25" AP^
SCOTT#dev>
Got this answer from a friend of mine.. Looks simple and works great...
SELECT
regexp_replace('User_Id=446^User_Input=L307-60#/25" AP^^', '.*User_Id=([^\^]+).*', '\1') User_Id,
regexp_replace('User_Id=446^User_Input=L307-60#/25" AP^^', '.*User_Input=(.*)[\^]$', '\1') User_Input
FROM dual
Posting here just in case any of you find it interesting..

How to remove percent character from a string in Cognos?

I have a string field with mostly numeric values like 13.4, but some have 13.4%. I am trying to use the following expression to remove the % symbols and retain just the numeric values to convert the field to integer.
Here is what I have so far in the expression definition of Cognos 8 Report Studio:
IF(POSITION('%' IN [FIELD1]) = NULL) THEN
/*** this captures rows with valid data **/
([FIELD1])
ELSE
/** trying to remove the % sign from rows with data like this 13.4% **/
(SUBSTRING([FIELD1]), 1, POSITION('%' IN [FIELD1])))
Any hints/help is much appreciated.
An easy way to do this is to use the trim() function. The following will remove any trailing % characters:
TRIM(trailing '%',[FIELD1])
The approach you are using is feasable. However, the syntax you are using is not compatible with the version of the ReportStudio that I'm familiar with. Below you will find an updated expression which works for me.
IF ( POSITION( '%'; [FIELD1]) = 0) THEN
( [FIELD1] )
ELSE
( SUBSTRING( [FIELD1]; 1; POSITION( '%'; [FIELD1]) - 1 ) )
Since character positions in strings are 1-based in Cognos it's important to substract 1 from the position returned by POSITION(). Otherwise you would only cut off characters after the percent sign.
Another note: what you are doing here is data cleansing. It's usually more advantageous to push these chores down to a lower level of the data retrieval chain, e.g. the Data Warehouse or at least the Framework Manager model, so that at the reporting level you can use this field as numeric field directly.

Strange SELECT behavior

I have this strange problem. i have a table with 10 columns of type character varying.
I need to have a function that searches all records and returns the id of the record which has all strings. Lets say records:
1. a,b,c,d,e
2. a,k,l,h
3. f,t,r,e,w,q
if i call this function func(a,d) it should return 1, if i call func(e,w,q) its should return 3.
The function is
CREATE OR REPLACE FUNCTION func(ma1 character varying,ma2 character varying,ma3 character varying,ma4 character varying)
DECLARE name numeric;
BEGIN
SELECT Id INTO name from Table WHERE
ma1 IN (col1,col2,col3,col4) AND
ma2 IN (col1,col2,col3,col4) AND
ma3 IN (col1,col2,col3,col4) AND
ma4 IN (col1,col2,col3,col4);
RETURN name;
END;
It's working 90% of the time, the weird problem is that some rows are not found.
Its not uppercase or lowercase problem.
What can be wrong, its version 9.1 on 64 bit win 7. I feel its like encoding or string problem but i can't see where and what.
//Ok i found the problem, it has to do with all column, if all 24 columns are filled in then its not working ?? but why ? are there limitations becouse there are 24 columns that i must compare with//
Can someone help me plz.
thanks.
The problem is (probably) that some of your columns have nulls.
In SQL, any equality comparison with a null is always false. This extends to the list of values used with the IN (...) condition.
If any of the values in the list are null, the comparison will be false, even if the value being sought is in the list.
The work-around is to make sure no values are null. which unfortunately results in a verbose solution:
WHERE ma1 IN (COALESCE(col1, ''), COALESCE(col2, ''), ...)
I suspect Bohemian is correct that the problem is related to nulls in your IN clauses. An alternative approach is to use Postgres's array contained in operator to perform your test.
where ARRAY[ma1,ma2,ma3,ma4] <# ARRAY[col1,col2,...,colN]

Resources