I've googled all I know how to Google. I need some new eyes to look at this.
I am trying to center the RESULTS of a query. Here is what I have so far ...
set lines 2000 pages 2000
COLUMN total HEADING "Total" FORMAT A20 JUSTIFY CENTER
COLUMN sending_fi HEADING "Sending M" FORMAT A20 JUSTIFY CENTER
COLUMN receiving_fi HEADING "Receiving M" FORMAT A20 JUSTIFY CENTER
COLUMN status HEADING "Payment Status" FORMAT A20 JUSTIFY CENTER
SET UNDERLINE =
select
count(*) as "Total",
p.sending_fi,
p.receiving_fi,
p.status
from
my_schema.my_table p
where
p.match_date
between
to_date
(
'2017/10/26:00:00:00',
'yyyy/mm/dd:hh24:mi:ss'
)
and
to_date
(
'2017/10/28:23:59:59',
'yyyy/mm/dd:hh24:mi:ss'
)
and
p.expedited='1'
and
p.status='DELIVERED'
group by
p.sending_fi,
p.receiving_fi,
p.status
order by
1
DESC
;
Which produces this output ...
Total Sending M Receiving M Payment Status
==================== ==================== ==================== =================
266759 BAC BAC DELIVERED
49954 JPM BAC DELIVERED
45194 BAC JPM DELIVERED
25990 WFC BAC DELIVERED
25676 JPM WFC DELIVERED
24120 WFC JPM DELIVERED
23565 BAC WFC DELIVERED
The COLUMN HEADERS (names) are centered, but for the life of me, I can't figure out how to center the results.
I'm a non-privileged user (all i ever really do are select update and insert), with very limited SQL skills. Please be gentle in your suggestions.
Originally I wrote this as a Comment. Then I thought of closing the question as a duplicate; but the only duplicate I found has no answers: just a Comment saying the same thing. (I should know, it was my Comment then, too!)
Column Formatting JUSTIFY not working
ANSWER:
It looks like you want an answer in SQL*Plus. There is no answer. Strings and dates are always aligned to the left side of the column, and numbers to the right. Period. You can't change that (other than by adding to the strings themselves, in the query - by padding with spaces; a complete waste of time!) If you need to generate "good looking" reports, and what is available in SQL*Plus is not good enough, you must use a reporting tool; can't be done in SQL*Plus.
There seems to be some confusion about the SQL command COLUMN ... FORMAT ... JUSTIFY. Here is what the manual says:
JUS[TIFY] {L[EFT] | C[ENTER] | R[IGHT]}
Aligns the heading. If you do not use a JUSTIFY clause, headings for NUMBER columns default to RIGHT and headings for other column types default to LEFT.
https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12013.htm#BACHCABF
You might be able to use LPAD.
Here is a quick example:
COLUMN blks HEADING "Num Blocks" FORMAT A10 JUSTIFY CENTER
select
lpad(to_char(blocks),(10-length(to_char(blocks)))/2+length(to_char(blocks)),' ') blks
from user_segments
where rownum < 11;
The idea is to pad the column on the left with half of the difference between the format size and the size of the column value in spaces.
Output:
Num Blocks
----------
16
16
16
16
16
16
16
16
16
16
10 rows selected.
Bobby
Bobby's answer will work for text output. You can also make use of the HTML markup feature of sqlplus and produce formatted html output. An example which extends https://docs.oracle.com/database/121/SQPUG/ch_seven.htm#SQPUG531 would be
create table t1 (
id number
, dt date
, vc varchar2(20)
, constraint pk_t1 primary key (id) );
begin
for i in 1..10 loop
insert into t1 values (i,sysdate + i , 'Row '||i);
end loop;
commit;
end;
/
SET MARKUP HTML ON PREFORMAT OFF ENTMAP ON -
HEAD "<TITLE>Department Report</TITLE> -
<STYLE type='text/css'> -
<!-- BODY {background: #FFFFC6} --> -
<!-- TD { text-align: center} --> -
</STYLE>" -
BODY "TEXT='#FF00Ff'" -
TABLE "WIDTH='90%' BORDER='5'"
Then run
spool t.html
followed by your query and then
host firefox t.html
Related
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
Question: For every part description that begins with the letter βbβ, list the part description, and then pad each part description with a β+βon the left side so that all these part descriptions are 15 characters in length.
And I wrote like
SELECT
LENGTH(PART_PART_DESCRIPTION), LPAD(PART_PART_DESCRIPTION,15,'+'),
PART_PART_DESCRIPTION, CONCAT('+', PART_PART_DESCRIPTION) FROM PART
WHERE SUBSTR(PART_PART_DESCRIPTION,1,1)='B'
but the output doesn't show 15 of '+' on left side.
Here is the output table
Your column PART_PART_DESCRIPTION is of CHAR data type with 285 data length. so BLENDER in your column has a total 285 (7 + 278 trailing spaces) length. that is why you are facing the problem.
See this:
SQL> select LPAD(CAST('BLENDER' AS CHAR(285)),15,'+') FROM DUAL;
LPAD(CAST('BLENDER'ASCHAR(285)),15,'+')
------------------------------------------------------------
BLENDER
SQL> select LPAD('BLENDER',15,'+') FROM DUAL;
LPAD('BLENDER',
---------------
++++++++BLENDER
SQL>
You need to use TRIM to properly use the LPAD on CHAR datatype column Something like the following:
LPAD(trim(PART_PART_DESCRIPTION),15,'+')
Most probably your data is padded with spaces. Try this
SELECT
LENGTH(PART_PART_DESCRIPTION), LPAD(TRIM(PART_PART_DESCRIPTION),15,'+'),
PART_PART_DESCRIPTION, CONCAT('+', PART_PART_DESCRIPTION) FROM PART
WHERE SUBSTR(PART_PART_DESCRIPTION,1,1)='B'
In the below code, I am trying to get the amount in words for the value in the AMOUNT column but can't seem to get it right. Anyone with an idea? Below the CREATE VIEW statement:
SELECT GLR3 AS RECEIPT_DOC_NO,
GLANI AS ACCOUNT_NUMBER,
GLSBL AS JDE_NO,
(SELECT YAALPH FROM PRODDTA.F060116 WHERE YAAN8 = T1.GLSBL) AS STAFF_NAME,
CASE GLDGJ WHEN 0 THEN TO_DATE (TO_CHAR (1 + 1900000), 'YYYYDDD')
ELSE TO_DATE (TO_CHAR (GLDGJ + 1900000), 'YYYYDDD') END AS GL_DATE,
GLEXA AS NARRATIVE,
GLLT AS LEDGER_TYPE,
GLSBLT AS SUBLEDGER_TYPE,
GLCRCD AS CURRENCY_CODE,
CASE GLAA WHEN 100 THEN ROUND (GLAA / 100, 2) ELSE ROUND (GLAA / 100, 2)
END AS AMOUNT,
(SELECT TO_CHAR(TO_DATE(T1.GLAA,'J'),'JSP')) FROM DUAL) AS AMOUNT_INWORDS
FROM PRODDTA.F0911 T1;
My code is failing with
ORA-00923: FROM keyword not found where expected.
ORA-00923: FROM keyword not found where expected.
Indicates a syntax error. In this case you have three ( and four ):
(SELECT TO_CHAR(TO_DATE(T1.GLAA,'J'),'JSP')) FROM DUAL) AS AMOUNT_INWORDS
The compiler is not expecting the second ) after 'JSP'.
The scalar cursor is unnecessary, so the simplified and corrected version would be:
TO_CHAR(TO_DATE(T1.GLAA,'J'),'JSP') AS AMOUNT_INWORDS
ORA-01854: julian date must be between 1 and 5373484
5373484 is the Julian date for 31-DEC-9999 which is the maximum date allowed in Oracle. This poses an absolute limit on the number which we can spell using JSP mask ... in one go. However, we can use PL/SQL to break larger numbers into chunks and spell those instead. The inestimable Tom Kyte wrote such a function and published it on the AskTom site. Find it here.
I think the value i'm trying to write in words has decimal values (400.00) hence the ORA-01854 error.
The Tom Kyte I linked to does address that issue further down the page. It's this comment here.
Data retrieved in amount column is preceded by a negative symbol when it shouldn't be,
If you simply want to ignore negative values then apply the ABS() function to give you the absolute value.
I am learning how to write basic SQL*Plus Reports.
While practicing, I ran into trouble with the BREAK ON command and am unsure how to proceed.
For reference, the table being used is called "Newspaper" and it contains the name of a Feature in a newspaper, what section that feature is in, and what page that feature is on.
When running the following report, SQL*Plus returns the results as expected:
rem Newspaper Report
ttitle 'Newspaper Features by Section'
btitle 'Hot off the Presses'
column feature format a15 word_wrapped
column section format a7
column page format 99
column feature heading 'Feature'
column section heading 'Section'
column page heading 'Page'
break on section skip 1
set linesize 80
set pagesize 40
set newpage 0
set feedback off
spool test.sql
select section, feature, page from newspaper
order by section;
spool off
The output:
Section Feature Page
------- --------------- ----
A National News 1
Editorials 12
B Bridge 2
Movies 4
Modern Life 1
Television 7
C Comics 4
Weather 2
D Sports 1
E Business 1
F Obituaries 6
Classified 8
Doctor Is In 6
Births 7
In this example, SQL*Plus skips one line whenever it reaches a new feature. This is how it is expected to work.
However, when I execute the following report, my results aren't formatted the way they should be:
rem Newspaper Report
ttitle 'Newspaper Features by Page'
btitle 'Hot off the Presses'
column feature format a15 word_wrapped
column section format a7
column page format 99
column feature heading 'Feature'
column section heading 'Section'
column page heading 'Page'
break on page skip 1
set linesize 80
set pagesize 40
set newpage 0
set feedback off
spool test.sql
select page, feature, section from newspaper
order by page;
spool off
The output:
Page Feature Section
---- --------------- -------
1 Modern Life B
Sports D
National News A
Business E
2 Weather C
Bridge B
4 Movies B
Comics C
6 Doctor Is In F
Obituaries F
7 Television B
Births F
8 Classified F
12 Editorials A
No lines were skipped when the page changed. Am I doing something wrong or is the command limited in this way?
It looks to me that the problem is the column name being "Page"; since page is a BREAK ACTION. Can you try aliasing the column to something other than "page" and try that: For example:
column page_temp heading 'Page'
break on page_temp skip 1
set linesize 80
set pagesize 40
set newpage 0
set feedback off
spool test.sql
select page page_temp, feature, section from newspaper
order by page;
I have a procedure that produces a table in the spool:
create procedure.....
......
loop
...
dbms_output.put_line(p_taskno||' '||p_descrip||' '||p_hrs||' '||p_start_date);
.........
The output is correct, however not well formatted:
***************************************
ABC Company Projects:
Project: 5555
TaskNo Description Hours StartDate
_____________________________________________
11 Prototype New Screens 30 23-AUG-06
12 Convert Data Files 10.5 15-SEP-06
13 Create Test Plan 15 14-AUG-06
62 Develop Enterprise Model 280 26-OCT-06
_____________________________________________
Number of Tasks: 4
Total Project Hours: 335.5
I cannot use column description format a20 word_wrapped because the table is the result of the dbms_output.put_line. How can I format it?
You need to work out the maximum size of the column and then pad the output with spaces.
So you want taskno to align with its header, that's six characters. Because it's a numeric you'll want it to align on the right:
lpad(to_char(taskno), 6)
Whereas Description is a string, so you'll want to align it on the left
rpad(p_description, 30)
Use these functions on the elements of the header too, to get the neatest output.