How to remove leading spaces in plsql
Hi folks,
currently this below gives leading spaces after using 'RTRIM', is there any way i can improvise on this and remove those also if the value is ending with 0 i don't need the 'RTRIM' to remove that 0 since it is part of the solution
BEGIN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(0.252345, '9990.99999999999999999999'));
DBMS_OUTPUT.PUT_LINE(RTRIM(TO_CHAR(0.252345, '9990.99999999999999999999'), 0));
END;
Output
0.25234500000000000000
0.252345
PS : I used RTRIM to prefix 0 before decimal point.
You should use FM in your format to suppress leading space.
TO_CHAR(0.252345, 'FM9990D99999999999999999999')
Or better still, don't do this in SQL (or PL/SQL for that matter) at all, but handle display issues in your app or Website instead.
The decimal separator is D in the format string, not . by the way.
Related
with the help of this thread I have tweak a regex for my use.
Decimal number regular expression, where digit after decimal is optional
So far I have this /^-?[1-9]$|^,\d+$|^0,\d$|^[1-9]\d*,\d*$
It works for
-12
0
1
It does not work for
-1,
-1,1
what I want is:
-1,1
may a kind soul explain what I am missing or doing wrong with this regex pls? Thank you very much!
I am tweaking it with : https://regexr.com/6sjkh but it's been 2 hours and I still don't know what I am missing. I don't know if language is important but I am in visual basic.
The thread you are quoting in your question has already some good answers. However if you do not need to also capture + and do not care about numbers without the leading zero before the comma and no thousand separator I would recommend the following:
/^-?\d+(,\d+)?/
The ^ indicates the beginning so that no other text in front is allowed
The -? is allowing a negative sign ( you need to escape this with \ as - can be a special character
\d+ expects 1 or more digits
The last part in parentheses covers the fractional part which as a whole can occure 0 or one time due to the question mark at the end
, is the decimal separator (if you want to have dots you need to put her ., as a dot is the special character for any character and also needs to be escaped if you look for a real dot)
\d+ is again one or more digits after the comma
I hope this helps a bit. Besides this I can also recommend using an online regular expression tool like https://regex101.com/
The IBM i implementation of regex uses apostrophes (instead of e.g. slashes) to delimit a regex string, i.e.:
... where REGEXP_SUBSTR(MYFIELD,'myregex_expression')
If I try to use an apostrophe inside a [group] within the expression, it always errors - presumably thinking I am giving a closing quote. I have tried:
- escaping it: \'
- doubling it: '' (and tripling)
No joy. I cannot find anything relevant in the IBM SQL manual or by google search.
I really need this to, for instance, allow names like O'Leary.
Thanks to Wiktor Stribizew for the answer in his comment.
There are a couple of "gotchas" for anyone who might land on this question with the same problem. The first is that you have to give the (presumably Unicode) hex value rather than the EBCDIC value that you would use, e.g. in ordinary interactive SQL on the IBM i. So in this case it really is \x27 and not \x7D for an apostrophe. Presumably this is because the REGEXP_ ... functions are working through Unicode even for EBCDIC data.
The second thing is that it would seem that the hex value cannot be the last one in the set. So this works:
^[A-Z0-9_\+\x27-]+ ... etc.
But this doesn't
^[A-Z0-9_\+-\x27]+ ... etc.
I don't know how to highlight text within a code sample, so I draw your attention to the fact that the hyphen is last in the first sample and second-to-last in the second sample.
If anyone knows why it has to not be last, I'd be interested to know. [edit: see Wiktor's answer for the reason]
btw, using double quotes as the string delimiter with an apostrophe in the set didn't work in this context.
A single quote can be defined with the \x27 notation:
^[A-Z0-9_+\x27-]+
^^^^
Note that when you use a hyphen in the character class/bracket expression, when used in between some chars it forms a range between those symbols. When you used ^[A-Z0-9_\+-\x27]+ you defined a range between + and ', which is an invalid range as the + comes after ' in the Unicode table.
From within an Oracle 11g database, using SQL, I need to remove the following sequence of special characters from a string, i.e.
~!##$%^&*()_+=\{}[]:”;’<,>./?
If any of these characters exist within a string, except for these two characters, which I DO NOT want removed, i.e.: "|" and "-" then I would like them completely removed.
For example:
From: 'ABC(D E+FGH?/IJK LMN~OP' To: 'ABCD EFGHIJK LMNOP' after removal of special characters.
I have tried this small test which works for this sample, i.e:
select regexp_replace('abc+de)fg','\+|\)') from dual
but is there a better means of using my sequence of special characters above without doing this string pattern of '\+|\)' for every special character using Oracle SQL?
You can replace anything other than letters and space with empty string
[^a-zA-Z ]
here is online demo
As per below comments
I still need to keep the following two special characters within my string, i.e. "|" and "-".
Just exclude more
[^a-zA-Z|-]
Note: hyphen - should be in the starting or ending or escaped like \- because it has special meaning in the Character class to define a range.
For more info read about Character Classes or Character Sets
Consider using this regex replacement instead:
REGEXP_REPLACE('abc+de)fg', '[~!##$%^&*()_+=\\{}[\]:”;’<,>.\/?]', '')
The replacement will match any character from your list.
Here is a regex demo!
The regex to match your sequence of special characters is:
[]~!##$%^&*()_+=\{}[:”;’<,>./?]+
I feel you still missed to escape all regex-special characters.
To achieve that, go iteratively:
build a test-tring and start to build up your regex-string character by character to see if it removes what you expect to be removed.
If the latest character does not work you have to escape it.
That should do the trick.
SELECT TRANSLATE('~!##$%sdv^&*()_+=\dsv{}[]:”;’<,>dsvsdd./?', '~!##$%^&*()_+=\{}[]:”;’<,>./?',' ')
FROM dual;
result:
TRANSLATE
-------------
sdvdsvdsvsdd
SQL> select translate('abc+de#fg-hq!m', 'a+-#!', etc.) from dual;
TRANSLATE(
----------
abcdefghqm
I need to find and clean up line breaks, carriage returns, tabs and "SUB"-characters in a set of 400k+ string records, but this DB2 environment is taking a toll on me.
Thought I could do some search and replacing with the REPLACE() and CHR() functions, but it seems CHR() is not available on this system (Error: CHR in *LIBL type *N not found). Working with \t, \r, \n etc doesn't seem to be working either. The chars can be in the middle of strings or at the end of them.
DBMS = DB2
System = iSeries
Language = SQL
Encoding = Not sure, possibly EBCDIC
Any hints on what I can do with this?
I used this SQL to find x'25' and x'0D':
SELECT
<field>
, LOCATE(x'0D', <field>) AS "0D"
, LOCATE(x'25', <field>) AS "25"
, length(trim(<field>)) AS "Length"
FROM <file>
WHERE LOCATE(x'25', <field>) > 0
OR LOCATE(x'0D', <field>) > 0
And I used this SQL to replace them:
UPDATE <file>
SET <field> = REPLACE(REPLACE(<field>, x'0D', ' '), x'25', ' ')
WHERE LOCATE(x'25', <field>) > 0
OR LOCATE(x'0D', <field>) > 0
If you want to clear up specific characters like carriage return (EBCDIC x'0d') and line feed (EBCDIC x'25') you should find the translated character in EBCDIC then use the TRANSLATE() function to replace them with space.
If you just want to remove undisplayable characters then look for anything under x'40'.
Here is an sample script that replaces X'41' by X'40'. Something that was creating issues at our shop:
UPDATE [yourfile] SET [yourfield] = TRANSLATE([yourfield], X'40',
X'41') WHERE [yourfield] like '%' concat X'41' concat '%'
If you need to replace more than one character, extend the "to" and "from" hexadecimal strings to the values you need in the TRANSLATE function.
Try TRANSLATE or REPLACE.
The brute force method involves using POSITION to find the errant character, then SUBSTR before and after it. CONCAT the two substrings (less the undesirable character) to re-form the column.
The character encoding is almost certainly one of the EBCDIC character sets. Depending on how the table got loaded in the first place, the CR may be x'0d' and the LF x'15', x'25'. An easy way to find out is to get to a green screen and do a DSPPFM against the table. Press F10 then F11 to view the table is raw, hexadecimal (over/under) format.
For details on the available functions see the
DB2 for i5/OS SQL Reference.
Perhaps the TRANSLATE() function will serve your needs.
TRANSLATE( data, tochars, fromchars )
...where fromchars is the set of characters you don't want, and tochars is the corresponding characters you want them replaced with. You may have to write this out in hex format, as x'nnnnnn...' and you will need to know what character set you are working with.
Using the DSPFFD command on your table should show the CCSID of your fields.
we struggled a lot to replace the new line char and carriage return from flat file.
Finally we used below sql to sort the issue.
REPLACE(REPLACE(COLUMN_NAME, CHR(13), ''), CHR(10), '')
Try it out
CR = CHR(13)
LF = CHR(10)
I need to pad numbers with leading zeros (total 8 digits) for display. I'm using oracle.
select to_char(1011,'00000000') OPE_NO from dual;
select length(to_char(1011,'00000000')) OPE_NO from dual;
Instead of '00001011' I get ' 00001011'.
Why do I get an extra leading blank space? What is the correct number formatting string to accomplish this?
P.S. I realise I can just use trim(), but I want to understand number formatting better.
#Eddie: I already read the documentation. And yet I still don't understand how to get rid of the leading whitespace.
#David: So does that mean there's no way but to use trim()?
Use FM (Fill Mode), e.g.
select to_char(1011,'FM00000000') OPE_NO from dual;
From that same documentation mentioned by EddieAwad:
Negative return values automatically
contain a leading negative sign and
positive values automatically contain
a leading space unless the format
model contains the MI, S, or PR format
element.
EDIT: The right way is to use the FM modifier, as answered by Steve Bosman. Read the section about Format Model Modifiers for more info.