Updating Strings with CHRTRAN Visual FoxPro function - visual-foxpro

I have some basic record keeping software; we are trying to capture email addresses, supporting software cannot capture an '#' sign.
Trying to use Visual FoxPro command CHRTRAN to search the field 'UdidText' for a comma ',' and replace it with an '#' sign.
The current code snippet reads:
update [udids] set udidtext = CHRTRAN (udidtext, '%,%', '#') where udidno = '78' and udidtext != ''
As a brief note; the percent sign is my preferred wildcard.
Edit: When checking the code in my application, the function produces an error "Operator/operand type mismatch".

CHRTRAN() doesn't need or want the wildcards. The second parameter is the character or characters to replace. So try:
CHRTRAN(uiditext, ',', '#')
Tamar

As per the chrtran() part, it would simply be:
chrtran(uidtext, ',', '#')
Your code is likely giving you error because udidno is not character? Probably you need:
.. udidno = 78 ...
there.
However your code wouldn't do any replacement at all, unless ANSI is ON. You have this:
... and udidtext != ''
If ANSI is NOT ON then that part would resolve to FALSE and no update would occur. To correct it you need, either SET ANSI ON or better use == which is ANSI free:
update [udids] set udidtext = CHRTRAN(udidtext, ',', '#') where udidno = '78' and !(udidtext == '')
In the same manner = '78' would mean any records where udidno Starts With '78'. If you need an exact match there, then that would become:
update [udids] set udidtext = CHRTRAN(udidtext, ',', '#') where udidno == '78' and !(udidtext == '')
Last part is actually unnecessary, so it becomes:
update [udids] set udidtext = CHRTRAN(udidtext, ',', '#') where udidno == '78'
And finally, your udidno might be a numeric:
update [udids] set udidtext = CHRTRAN(udidtext, ',', '#') where udidno = 78

Related

trailing and leading blank issue in string

I am working on a project where I need to check if the employee enter *done* in a text field, though employee enters '* done *' or '*done *' or '* done*' in similar fashion. As you see they are putting trailing and leading blank or both at a time.I have to check the column for all three/four possible entry in like statement, I tried trim,rtrim nothing seems like working.
case when
col like ('*done*')
or col like ('* done*')
or col like ('*done *')
or col like ('* done *')
end as work_status
doesn't seems a smart way to do it. What is the best way to to check this. Any help will be appreciated. Thank you.
Remove spaces:
case when replace(col, ' ') = '*done*' then 'done'
else 'not'
end as work_status
You can look for the done substring with anything preceding and following using the LIKE operator and % wildcards:
CASE WHEN col LIKE '%done%' THEN 'done' END AS work_status
Or you can trim the leading and trailing space characters:
CASE WHEN TRIM(col) = 'done' THEN 'done' END AS work_status
Or you can replace all the leading/trailing white spaces (in case the users have entered new lines, tabs, etc. rather than space characters) using a regular expression:
CASE
WHEN REGEXP_REPLACE(col, '^[[:space:]]+|[[:space:]]+$') = 'done'
THEN 'done'
END AS work_status
fiddle

Oracle LTRIM triming too many charecters

I am trying to use LRTIM to obtain part of a string.
This is the code that I am using.
SELECT
C.MANUFACTURER,
C.MODEL_GROUP,
LTRIM(C.VARIANT, C.MANUFACTURER || ' ' || C.MODEL_GROUP), "VAR DESC"
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C
This is what I have field wise
VARIANT
AUDI A3 DIESEL SPORTBACK 2.0 TDI SE Technik 5dr Manual 150
MANUFACTURER
AUDI
MODEL_GROUP
A3
This is the result that I am getting
MANUFACTURER MODEL_GROUP VAR DESC
AUDI A3 ESEL SPORTBACK 2.0 TDI SE Technik 5dr Manual 150
It is cutting off the first 2 characters of DIESEL, the problem is that this is not happening in all cases. Sometimes it is cutting off 1 character and sometimes none!
I have considered other methods of achieving this, i.e. looking for the spaces, but have other manufacturers and model groups that have multiple spaces so was trying to subtract the MANUFACTURER and MODEL_ROUP from the VARIANT field (string)
Any ideas as to why this might be happening or other suggestions for achieving this would be greatly appreciated.
Many thanks in advance,
Keith
Apologies seems like the editor is reformating the results that I am getting
Oracle query result
You can use REGEXP_REPLACE with '^' - Indicating start of string.
SELECT
C.MANUFACTURER,
C.MODEL_GROUP,
REGEXP_REPLACE(C.VARIANT, '^'||C.MANUFACTURER || ' +' || C.MODEL_GROUP) "VAR DESC",
C.VARIANT
FROM STD_BI.RL2_CONTRACTS_VW C
The second parameter to LTRIM is a set of single characters, not a sequence of characters. In your example the database removes characters from the left until it encounters the first character not in ('A','U','D','I','A','3'), which is the E of DIESEL.
In order to remove a prefix p from a string s use something like
case when SUBSTR(s,1,LENGTH(p))=p then SUBSTR(s,LENGTH(p)+1) else s end
which in your case expands to
case when SUBSTR(C.VARIANT, 1, LENGTH(C.MANUFACTURER || ' ' || C.MODEL_GROUP))
= C.MANUFACTURER || ' ' || C.MODEL_GROUP
then SUBSTR(C.VARIANT, 1+ LENGTH(C.MANUFACTURER || ' ' || C.MODEL_GROUP))
else s
end

Ruby Regexp match matching repetitive values

I'm facing some issues with Ruby Regexp match.
I have the following query and I'd like to scan my parameters:
EXEC sp_executesql N'exec dbo.MyProcedure #UserID=#p0,#Products=#p1,#CountryCodes=#p2'
, N'#p0 int,#p1 nvarchar(max) ,#p2 nvarchar(max)'
, #p0 = 123569
, #p1 = N'1633,1634'
, #p2 = N'39A,CS,DE,ES,FR,GB,IT,NL,AB,BS,BU,CR,ET,FI,HU,LA,LT,MD,ME,MV,PL,RO,RS,SK,SV,GR,PT,TR,AT,CH,LI,GG,KS,UK,GI,MN,RR,CY,MT,BL,RU,DK,NO,SE,BE,IC,IE,LX'
I've just formatted query to look neat and readable. In my source there are fewer tabs and whitespaces.
Ideally, I'd like to get three matches:
#p0 = 123569
#p1 = N'1633,1634'
#p2 = N'39A,CS,DE,ES,FR,GB,IT,NL,AB,BS,BU,CR,ET,FI,HU,LA,LT,MD,ME,MV,PL,RO,RS,SK,SV,GR,PT,TR,AT,CH,LI,GG,KS,UK,GI,MN,RR,CY,MT,BL,RU,DK,NO,SE,BE,IC,IE,LX'
However, my Regexp pattern merges #p1 and #p2 and this is what I get:
#p0 = 123569
#p1 = N'1633,1634',#p2 = N'39A,CS,DE,ES,FR,GB,IT,NL,AB,BS,BU,CR,ET,FI,HU,LA,LT,MD,ME,MV,PL,RO,RS,SK,SV,GR,PT,TR,AT,CH,LI,GG,KS,UK,GI,MN,RR,CY,MT,BL,RU,DK,NO,SE,BE,IC,IE,LX'
I can see where's the issue, however I'm quite new to Regexp and I cannot figure out how to write it properly. This is my expression:
(\#p[0-9]+)+\=(\N\'.*\'|[0-9]+|NULL)
I'm testing my Regex expression here: http://rubular.com/r/OF5EVD5Nau
You main problem is the .* part in the second alternation, by default regex are greedy and match as much as possible.
You can turn it into lazy or ungreedy by adding a ? after the repetition operator.
So with little change this would do:
(#p[0-9]+)\s+=\s+(\d+|N'.+?'$|NULL)
Rubular example
There's some unknown from you description on the spaces, I used + as repetition operator assuming there will be at least 1 present around the = sign, as in the single quotes, I assume they are never empty. Replace by * if they are optionnal.

Case Statement using || (OR)

The following code I am trying to use to assign an email alias via an api to our ticketing system.
#email.cc_list = case #site_id
when /site1/ || /site2/; "smail-alias-1"
when /site3/ || /site4/ || /site5/ || /site6/; "email-alias-2"
when /site7/ || /site8/; "email-alias-3"
when /site9/; "email-alias-4"
when /site10/; "email-alias-5"
end
the problem is that only site 1, 3, 7, 9, and 10 are actually being assigned properly. anything after the || isn't working.
I would rather avoid 10 when statements for 5 alias's. Is there a way that I can make this case statement work with a hash in order to get the system to determine when it matches the specified site_id? or another way to make the or functions work?
You could write :
#email.cc_list = case #site_id
when /site(1|2)/ then "smail-alias-1"
when /site(3|4|5|6)/ then "email-alias-2"
when /site(7|8)/ then "email-alias-3"
when /site9/ then "email-alias-4"
when /site10/ then "email-alias-5"
end
Not to give you the correct ways since others have done that, but will be good for your knowledge why your original code fails.
case #site_id
when /site1/ || /site2/ ...
does not translate to:
if #site_id =~ /site1/ || #site_id =~ /site2/ ...
but to:
if #site_id =~ /site1/ || /site2/ ...
which is parsed as:
if ((#site_id =~ /site1/) || /site2/) ...
so, when the first match fails, it returns nil. nil ||-ed with a regex object has the value of regex object itself. A regex object in condition has boolean value of... you guess: false
you will even get a:
warning: regex literal in condition
if you do it directly in an if statement.
You might prefer to write:
#email.cc_list = case #site_id[/\d+/].to_i
when 1,2 then "smail-alias-1"
when 3..6 then "email-alias-2"
when 7,8 then "email-alias-3"
when 9 then "email-alias-4"
when 10 then "email-alias-5"
end
You could join your regexes w/ Regexp.union:
#email.cc_list = case #site_id
when Regexp.union(/site1/, /site2/); "smail-alias-1"
when Regexp.union(/site3/, /site4/, /site5/, /site6/); "email-alias-2"
when Regexp.union(/site7/, /site8/); "email-alias-3"
when /site9/; "email-alias-4"
when /site10/; "email-alias-5"
end
Or make the regex like /site1|site2/ yourself which is what union would basically do for you here.

Oracle Pattern matching

In Oracle I want to check whether the string has "=' sign at the end. could you please let me know how to check it. If it has '=' sign at the end of string, I need to trailing that '=' sign.
for eg,
varStr VARCHAR2(20);
varStr = 'abcdef='; --needs to trailing '=' sign
I don't think you need "pattern matching" here. Just check if the last character is the =
where substr(varstr, -1, 1) = '='
substr when called with a negative position will work from the end of the string, so substr(varstr,-1,1) extracts the last character of the given string.
Use the REGEX_EXP function. I'm putting a sql command since you didn't specify on your question.:
select *
from someTable
where regexp_like( someField, '=$' );
The pattern $ means that the precedent character should be at the end of the string.
see it here on sql fiddle: http://sqlfiddle.com/#!4/d8afd/3
It seems that substr is the way to go, at lease with my sample data of about 400K address lines this returns 1043 entries that end in 'r' in an average of 0.2 seconds.
select count(*) from addrline where substr(text, -1, 1) = 'r';
On the other hand, the following returns the same results but takes 1.1 seconds.
select count(*) from addrline where regexp_like(text, 'r$' );

Resources