I hope there is no post limit since I have posted more than once today. :-P
Now I have a table in OracleSQL. I noticed there are some useless signs and want to delete them. The way I do it is to replace all of them. Below is my table and my query.
Here is my query:
SELECT
CASE WHEN WORD IN ('!', '"', '#','""') Then ''
ELSE WORD END
FROM TERM_FREQUENCY;
It is not giving me an error, but these special characters are not going away either... Any thoughts?
A little typo of yours: you use - instead of _
SELECT
CASE WHEN WORD IN ('!', '"', '#','""') Then ''
ELSE WORD END
-- FROM TERM-FREQUENCY; --This is where the problem is.
FROM TERM_FREQUENCY; -- Because your table is named TERM _ FREQUENCY
You originally tagged your question with 'replace' but then didn't use that function in your code. You're comparing each whole word to those fixed strings, not seeing if it contains any of them.
You can either use nested replace calls to remove one character at a time:
select replace(replace(word, '!', null), '"', null) from ...
... which would be tedious and rely on you identifying every character you didn't want; or you could use a regular expression only keep alphabetic characters, which I suspect is what you're really after:
select regexp_replace(word, '[^[:alpha:]]', null) from ...
Quick demo.
You might also want to use lower or upper to get everything into the same case, as you probably don't really want to count different capitalisation differently either.
Related
Let's say you have a table called Employee and one of the employee names begins or includes the [$] or [#] sign within the String, like Hel$lo or like #heLLo. How can you call the value?
Is it possible to select and trim the value in a single command?
Kind regards
If you want to select the names, but with special characters $ and # removed, you can use the TRANSLATE function. Add more characters to the list if you need to.
select translate(name, 'A$#', 'A') from employee;
The function will "translate" the character 'A' to itself, '$' and '#' to nothing (simply removing them from the string), and it will leave all other characters - other than A, $ and # - unchanged. It may seem odd that you need the 'A' in this whole business; and you really don't need 'A' specifically, but you do need some character that you want to keep. The reason for that is Oracle's idiotic handling of null; don't worry about the reason, just remember the technique.
You may need to remove characters but you don't know in advance what they will be. That can be done too, but you need to be careful not to remove legitimate characters, like the dot (A. C. Green), dash (John Connor-Smith), apostrophe (Betty O'Rourke) etc. You can then do it either with regular expressions (easy to write, but not the most efficient) or with TRANSLATE as above (it looks uglier, but it will run faster). Something like this:
select regexp_replace(name, [^[:alpha:].'-]) from employee
This will replace any character that is not "alpha" (letters) or one of the characters specifically enumerated (dot, apostrophe, dash) with nothing, effectively removing them. Note that dash has a special meaning in character classes, so it must be the last one in the enumeration.
If you need to make the changes in the table itself, you can use an update statement, using TRANSLATE or REGEXP_REPLACE as shown above.
Unable to trim the non breakable space in the middle of a filed in oracle
'766195491 572'
Tried the below method it works only when non breakable space is present on the sides.
select length(trim(replace('766195491 572',chr(49824),''))) from dual;
it works only when non breakable space is present on the sides
That’s what the trim() function is supposed to do:
TRIM enables you to trim leading or trailing characters (or both) from a character string
“leading or trailing” means “at the sides”. It is not supposed to have any effect on appearances of the characters anywhere else in the source string.
You need to use the replace() or translate() functions instead; or for more complicated scenarios, regular expression functions.
If the input value is in a column named input_str, then:
translate(input_str, chr(49824), chr(32))
will replace every non-breakable space in the input string with a regular (breakable) space.
If you simply want to remove all non-breakable spaces and don't want to replace them with anything, then
replace(input_str, chr(49824))
(if you omit the third argument, the result is simply removing all occurrences of the second argument).
Perhaps the requirement is more complicated though; find all occurrences of one or more consecutive non-breaking spaces and replace each such occurrence with exactly one standard space. That is more easily achieved with a regular expression function:
regexp_replace(input_str, chr(49824) || '+', chr(32))
Try CHR(32) instead of CHR(49824)
select length(replace('766195491 572',chr(32),'')) from dual;
If it does not work, use something like this.
select length(regexp_replace('766195491 572','[^-a-zA-Z0-9]','') ) from dual;
DEMO
I'm trying to censor letters in a word with word.gsub(/[^#{guesses}]/i, '-'), where word and guesses are strings.
When guesses is "", I get this error RegexpError: empty char-class: /[^]/i. I could sort such cases with an if/else statement, but can I add something to the regex to make it work in one line?
Since you are only matching (or not matching) letters, you can add a non-letter character to your regex, e.g. # or %:
word.gsub(/[^%#{guesses}]/i, '-')
See IDEONE demo
If #{guesses} is empty, the regex will still be valid, and since % does not appear in a word, there is no risk of censuring some guessed percentage sign.
You have two options. One is to avoid testing if your matches are empty, that is:
unless (guesses.empty?)
word.gsub(/^#{Regex.escape(guesses)}/i, '-')
end
Although that's not your intention, it's really the safest plan here and is the most clear in terms of code.
Or you could use the tr function instead, though only for non-empty strings, so this could be substituted inside the unless block:
word.tr('^' + guesses.downcase + guesses.upcase, '-')
Generally tr performs better than gsub if used frequently. It also doesn't require any special escaping.
Edit: Added a note about tr not working on empty strings.
Since tr treats ^ as a special case on empty strings, you can use an embedded ternary, but that ends up confusing what's going on considerably:
word.tr(guesses.empty? ? '' : ('^' + guesses.downcase + guesses.upcase), '-')
This may look somewhat similar to tadman's answer.
Probably you should keep the string that represents what you want to hide, instead of what you want to show. Let's say this is remains. Then, it would be easy as:
word.tr(remains.upcase + remains.downcase, "-")
When I am trying to execute INSERT statement in oracle, I got SQL Error: ORA-00917: missing comma error because there is a value as Alex's Tea Factory in my INSERT statement.
How could I escape ' ?
To escape it, double the quotes:
INSERT INTO TABLE_A VALUES ( 'Alex''s Tea Factory' );
In SQL, you escape a quote by another quote:
SELECT 'Alex''s Tea Factory' FROM DUAL
Instead of worrying about every single apostrophe in your statement.
You can easily use the q' Notation.
Example
SELECT q'(Alex's Tea Factory)' FROM DUAL;
Key Components in this notation are
q' which denotes the starting of the notation
( an optional symbol denoting the starting of the statement to be fully escaped.
Alex's Tea Factory (Which is the statement itself)
)' A closing parenthesis with a apostrophe denoting the end of the notation.
And such that, you can stuff how many apostrophes in the notation without worrying about each single one of them, they're all going to be handled safely.
IMPORTANT NOTE
Since you used ( you must close it with )', and remember it's optional to use any other symbol, for instance, the following code will run exactly as the previous one
SELECT q'[Alex's Tea Factory]' FROM DUAL;
you can use ESCAPE like given example below
The '_' wild card character is used to match exactly one character, while '%' is used to match zero or more occurrences of any characters. These characters can be escaped in SQL.
SELECT name FROM emp WHERE id LIKE '%/_%' ESCAPE '/';
The same works inside PL/SQL:
if( id like '%/_%' ESCAPE '/' )
This applies only to like patterns, for example in an insert there is no need to escape _ or %, they are used as plain characters anyhow. In arbitrary strings only ' needs to be escaped by ''.
SELECT q'[Alex's Tea Factory]' FROM DUAL
Your question implies that you're building the INSERT statement up by concatenating strings together. I suggest that this is a poor choice as it leaves you open to SQL injection attacks if the strings are derived from user input. A better choice is to use parameter markers and to bind the values to the markers. If you search for Oracle parameter markers you'll probably find some information for your specific implementation technology (e.g. C# and ADO, Java and JDBC, Ruby and RubyDBI, etc).
Share and enjoy.
Here is a way to easily escape & char in oracle DB
set escape '\\'
and within query write like
'ERRORS &\\\ PERFORMANCE';
How would I go about counting the characters after a certain character. I'm new to Oracle, and I've learned quite a bit however I'm stumped at this point. I found a couple functions that will get you a substring and I found a function that will give you the length of a string. I am examining an email address, myemail#thedomain.com. I want to check the length after the '.' in the email.
SELECT email
FROM user_table
WHERE length(substr(email, /*what values*/, /*to put here*/))
I don't know if it's actually possible to find the location of the final '.' in the email string?
I'm not sure I would use substr. You can try something like this :
select length('abcd#efgh.123.4567') - instr('abcd#efgh.123.4567', '.', -1) from dual
Using instr(..,..,-1) searches backwards from the last character to find the position.
Since you're doing checks, I suggest you validate the format with regular expressions using REGEXP_INSTR. For instance, an email validation I found on this site is REGEXP_INSTR(email, '\w+#\w+(\.\w+)+') > 0
I didn't check it myself, but it looks quite ok.
Cheers.