oracle db returns additional padding - oracle

Could you advise why on one of our database below query:
select ' ' from dual
returns 32 blank characters:
' '
This happens ONLY on one environment, all other databases returns correctly only one space. I checked nls_parameters, they are the same. Any idea what could be reason for that? Some DB parameter? Some patch was not applied on that instance?
Other example:
select "!" || "!" from dual
produces:
"!! "
so it's !! + 62 spaces

Check database parameter cursor_sharing. What is it set to? Set it to EXACT.
SQL> show parameters cursor_sharing
NAME TYPE VALUE
------------------------------------ ----------- ------------------------
cursor_sharing string EXACT
SQL>

Related

Oracle APEX number format mask without comma

I am trying to change the number eg. 1000 to 1.000, 10000 to 10.000 istead of 10,000 or 10,000.00
DO you have any idea? :)
As far as I can tell, there's (unfortunately) no declarative way to modify thousands/decimal separators. Should be somewhere in "Edit application definition - Globalization" settings, but - there's nothing like that there.
So, do it yourself, manually. Navigate to shared components - security attributes - database session tab - initialization PL/SQL code and put this into it:
begin
execute immediate q'[alter session set nls_numeric_characters = ', ']';
end;
which will set comma as decimal separator, and space as thousands (group) separator.
Example:
SQL> alter session set nls_numeric_characters = ', ';
Session altered.
SQL> select 5000 val1,
2 to_char(5000, '999G990D00') val2,
3 to_char(5000, '999G990') val3
4 from dual;
VAL1 VAL2 VAL3
---------- ----------- --------
5000 5 000,00 5 000
SQL>
You can use
SELECT TO_CHAR(your_nr_col, '999G999G999G990', 'nls_numeric_characters='',.''') AS nr_formatted
FROM t
if you're dealing with integers only ( without including any decimal separator ), put as much as 9s to exceed the number of the digits while adding Gs after each three padded digit starting from the right hand side.
If there might arise some cases in which the decimal separators are needed, then replace the second argument with '999G999G999G990D0000' to pad enough 0s after single D character directing from left to right
DemO

How to replace single quote with space in column in oracle database

I have a problem in updating a column in oracle which has a single quote.
The following example will clear the problem.
Lets Client name is Lucy'Mark
Now, I want to replace the Single quote with space
After output, it will be Lucy Mark
Now when I tried the following query it is not working as the query will be
select replace (Lucy'Mark , '''', '') from gen_clientvendor_m;
Please let me know the query.
I am using SQL developer
Use the column with client name and add space to the replace statement:
select replace (client_name , '''', ' ') from gen_clientvendor_m;
Multiple single quotes cause headache :) so - have a look at this option:
SQL> with test (name) as
2 (select q'[Lucy'Mark]' from dual)
3 select name,
4 replace(name, chr(39), ' ') result
5 from test;
NAME RESULT
--------- ---------
Lucy'Mark Lucy Mark
SQL>

what will translate function do if I want to change some chars to nothing?

I have a sql statement:
select translate('abcdefg', 'abc', '') from dual;
Why the result is nothing?
I think it should be 'defg'.
From the documentation:
You cannot use an empty string for to_string to remove all characters in from_string from the return value. Oracle Database interprets the empty string as null, and if this function has a null argument, then it returns null. To remove all characters in from_string, concatenate another character to the beginning of from_string and specify this character as the to_string. For example, TRANSLATE(expr, 'x0123456789', 'x') removes all digits from expr.
So you can do something like:
select translate('abcdefg', '#abc', '#') from dual;
TRANSLATE('ABCDEFG','#ABC','#')
-------------------------------
defg
... using any character that isn't going to be in your from_string.
select translate('abcdefg', 'abc', '') from dual;
To add to Alex's answer, you could use any character(allowed in SQL) for that matter to concatenate to remove all the characters. So, you could even use a space instead of empty string. An empty string in Oracle is considered as NULL value.
So, you could also do -
SQL> SELECT TRANSLATE('abcdefg', ' abc', ' ') FROM dual;
TRAN
----
defg
SQL>
Which is the same as -
SQL> SELECT TRANSLATE('abcdefg', chr(32)||'abc', chr(32)) FROM dual;
TRAN
----
defg
SQL>
Since the ascii value of space is 32.
It was just a demo, it is better to use any other character than space for better understanding and code readability.

Oracle - dynamic column name in select statement

Question:
Is it possible to have a column name in a select statement changed based on a value in it's result set?
For example, if a year value in a result set is less than 1950, name the column OldYear, otherwise name the column NewYear. The year value in the result set is guaranteed to be the same for all records.
I'm thinking this is impossible, but here was my failed attempt to test the idea:
select 1 as
(case
when 2 = 1 then "name1";
when 1 = 1 then "name2")
from dual;
You can't vary a column name per row of a result set. This is basic to relational databases. The names of columns are part of the table "header" and a name applies to the column under it for all rows.
Re comment: OK, maybe the OP Americus means that the result is known to be exactly one row. But regardless, SQL has no syntax to support a dynamic column alias. Column aliases must be constant in a query.
Even dynamic SQL doesn't help, because you'd have to run the query twice. Once to get the value, and a second time to re-run the query with a different column alias.
The "correct" way to do this in SQL is to have both columns, and have the column that is inappropriate be NULL, such as:
SELECT
CASE WHEN year < 1950 THEN year ELSE NULL END AS OldYear,
CASE WHEN year >= 1950 THEN year ELSE NULL END AS NewYear
FROM some_table_with_years;
There is no good reason to change the column name dynamically - it's analogous to the name of a variable in procedural code - it's just a label that you might refer to later in your code, so you don't want it to change at runtime.
I'm guessing what you're really after is a way to format the output (e.g. for printing in a report) differently depending on the data. In that case I would generate the heading text as a separate column in the query, e.g.:
SELECT 1 AS mydata
,case
when 2 = 1 then 'name1'
when 1 = 1 then 'name2'
end AS myheader
FROM dual;
Then the calling procedure would take the values returned for mydata and myheader and format them for output as required.
You will need something similar to this:
select 'select ' || CASE WHEN YEAR<1950 THEN 'OLDYEAR' ELSE 'NEWYEAR' END || ' FROM TABLE 1' from TABLE_WITH_DATA
This solution requires that you launch SQLPLUS and a .sql file from a .bat file or using some other method with the appropriate Oracle credentials. The .bat file can be kicked off manually, from a server scheduled task, Control-M job, etc...
Output is a .csv file. This also requires that you replace all commas in the output with some other character or risk column/data mismatch in the output.
The trick is that your column headers and data are selected in two different SELECT statements.
It isn't perfect, but it does work, and it's the closest to standard Oracle SQL that I've found for a dynamic column header outside of a development environment. We use this extensively to generate recurring daily/weekly/monthly reports to users without resorting to a GUI. Output is saved to a shared network drive directory/Sharepoint.
REM BEGIN runExtract1.bat file -----------------------------------------
sqlplus username/password#database #C:\DailyExtracts\Extract1.sql > C:\DailyExtracts\Extract1.log
exit
REM END runExtract1.bat file -------------------------------------------
REM BEGIN Extract1.sql file --------------------------------------------
set colsep ,
set pagesize 0
set trimspool on
set linesize 4000
column dt new_val X
select to_char(sysdate,'MON-YYYY') dt from dual;
spool c:\DailyExtracts\&X._Extract1.csv
select '&X-Project_id', 'datacolumn2-Project_Name', 'datacolumn3-Plant_id' from dual;
select
PROJ_ID
||','||
replace(PROJ_NAME,',',';')-- "Project Name"
||','||
PLANT_ID-- "Plant ID"
from PROJECTS
where ADDED_DATE >= TO_DATE('01-'||(select to_char(sysdate,'MON-YYYY') from dual));
spool off
exit
/
REM ------------------------------------------------------------------
CSV OUTPUT (opened in Excel and copy/pasted):
old 1: select '&X-Project_id' 'datacolumn2-Project_Name' 'datacolumn3-Plant_id' from dual
new 1: select 'MAR-2018-Project_id' 'datacolumn2-Project_Name' 'datacolumn3-Plant_id' from dual
MAR-2018-Project_id datacolumn2-Project_Name datacolumn3-Plant_id
31415 name1 1007
31415 name1 2032
32123 name2 3302
32123 name2 3384
32963 name3 2530
33629 name4 1161
34180 name5 1173
34180 name5 1205
...
...
etc...
135 rows selected.

Oracle: Pattern for to_char(number) to add additional ascii characters?

Using the Oracle to_char(number) function, is it possible to append ascii characters to the returned string?
Specifically, I need to add a percentage character to the returned string.
"select to_char(89.2244, '999G999G999G999G990D00') from dual" -->
returns "89.22". I need a format pattern that returns "89.22%".
I am using this through reports in Application Express, so cannot simply concatenate "%" to the query, i need to put it in the number format.
So you can't wrap the to_char with a CONCAT?
select concat(to_char(89.2244, '999G999G999G999G990D00'),'%') from dual
You can't do it right in the number format.
If you are able to change NLS_CURRENCY for you session, you can do the following:
SELECT TO_CHAR(1.2, '999G999G999G999G990D00L' /*, 'NLS_CURRENCY=%' */)
FROM dual
---
1,20%
Quick and dirty way:
select to_char(89.2244, '999G999G999G999G990D00L', 'NLS_CURRENCY=''%''') from dual;
SYS # orant11g >select to_char(89.2244, '999G999G999G999G990D00')||'%' from dual;
TO_CHAR(89.2244,'999G999
------------------------
89.22%
Just use the || bars instead of the concat function.

Resources