Oracle 12c SQL: Missing column Headers in result - oracle

I want to understand why my columns are missing their headers.
Consider this table:
SQL> DESC customer;
Name Null? Type
------------ -------- ------------
CUST_ID NOT NULL NUMBER(5)
CUST_NAME VARCHAR2(15)
ACCOUNT_ID VARCHAR2(10)
ACCOUNT_TYPE VARCHAR2(2)
STATE VARCHAR2(2)
When I select * from the table in SQL*Plus, the result is missing the column headers.
SQL> SELECT * FROM customer;
90001 B and B A-11101 PR AK
90002 XYZ A-11102 CM NJ
90003 JJ Sons A-11103 CM NJ
90004 Exxon A-11104 PR NY
90005 ABC A-11105 CM NY
90006 Smith Co. A-11106 CM MD
90007 Brown Co. A-11107 CM MD
90008 Cooper Inc. A-11108 PR MD
8 rows selected.
But when I use SQL Developer, the column headers are displayed.
Why? And, knowing that, how do I make them display with SQL*Plus?
My goal is to display the tables with the headers. If there are other details I need to add, let me know.
Heading is set to ON.

My pagesize was set to 0. I don't know why this would cause the column headers to disappear, but it did. If someone can explain better than me, I'll gladly accept their answer in leu of mine.
I set pagesize to 14, and my column headers appeared.

SQL*Plus has changed the default behavior in ORACLE 12c.
With
SQL> set head on
you get back to the previous behavior.
With
SQL> set pagesize *n*
every n rows the header will be repeated.

Related

Remove Blank Line In Between Select Queries When Spooling to CSV File 2

I have query that is executed from SQLPLUS (11.2.0.4) and output is spooled to file. I am getting output file empty lines after each line + many empty spaces after the last column in the query. I have opened the file in notepad++ and i can see tons of empty spaces appended to the last column and ended with CRLF ( windows) , the last column is varchar 4000.
I have read tons of articles related to the same in internet but none of them help me. I have tried to set trimspool ON/OFF, trimout ON/OFF (btw - both commands are skipped ), page 0, heading off, pagesize 0, page 0, space 0, newpage nono
Example of SQL :
set termout off
set pagesize 0
set termout off
set pagesize 0
set heading off
set feedback off
set newpage none
set space 0
set linesize 8000
set longchunksize 200000
/*above was tried step by step - no help*/
spool "G:/gggg/fffff.csv"
PROMT COL1|COL2|COL3
select col1||';'||col2||';'||nvl(col3,'') abc
FROM transactions;
spool off;
output (notepad++):
COL1|COL2|COL3CRLF
col1|col2|col3 CRLF
col1|col2|col3 CRLF
col1|col2|col3 CRLF
output(linux)
COL1|COL2|COL3$
col1|col2|$
COL3 $
col1|col2|$
COL3 $
col1|col2|$
COL3 $
I have to use SQLPLUS .
it is requested to have output file without double quotes and with tilda as delimiter
e.g.
aaaa~bbbb~cccc~eeeeeeeeeeeeeeeeeeeeeeeeee
dddd~rrrr~bggggggg~rrrrrrrrrrrrrrrrrrrrrrrrrr
eeee~rrrrrrr~ttttttt~yyyyyyyyyyyyyyyyyyyyyyyyyy
Columns type :
col1 integer
col2 varchar2(4000 BYTE)
col3 varchar2(4000 BYTE)
Current output looks like
COL1NAME~COL2NAME~COL3NAME
aaaa~bbbb~cccc~eeeeeeeeeeeeeeeeeeeeeeeeee
dddd~rrrr~bggggggg~rrrrrrrrrrrrrrrrrrrrrrrrrr
eeee~rrrrrrr~ttttttt~yyyyyyyyyyyyyyyyyyyyyyyyyy
I would like to remove the empty lines without any cut of the characters in lines.
I can see in notepad++ :
COL1NAME~COL2NAME~COL3NAMECRLF
aaaa~bbbb~cccc~eeeeeeeeeeeeeeeeeeeeeeeeee..................................CRLF
dddd~rrrr~bggggggg~rrrrrrrrrrrrrrrrrrrrrrrrrr..............................CRLF
eeee~rrrrrrr~ttttttt~yyyyyyyyyyyyyyyyyyyyyyyyyy............................CRLF
I can see in linux (after less) :
COL1NAME~COL2NAME~COL3NAME$
aaaa~bbbb~cccc~eeeeeeeeeeeeeeeeeeee$
eeeeee $
$
dddd~rrrr~bggggggg~rrrrrrrrrrrrrrrr$
rrrrrrrrrr $
$
eeee~rrrrrrr~ttttttt~yyyyyyyyyyyyyy$
yyyyyyyyyyyy $
$
What's your table look like? Is COL3 defined as a CHAR or VARCHAR2? If a CHAR, that explains everything.
We need to see your data and your table, to be able to help you, otherwise you're asking us to guess.
Using the HR sample schema and the locations table, notice the varchar2's.
CREATE TABLE locations (
location_id NUMBER(4, 0),
street_address VARCHAR2(40),
postal_code VARCHAR2(12),
city VARCHAR2(30)
CONSTRAINT loc_city_nn NOT NULL ENABLE,
state_province VARCHAR2(25),
country_id CHAR(2),
CONSTRAINT loc_c_id_fk FOREIGN KEY ( country_id )
REFERENCES hr.countries ( country_id )
ENABLE
);
COUNTRY_ID is CHAR(2) - so you'll always see 2 spaces for that column, even if you only inserted '1' character.
Querying the table, with sqlformat set to CSV, I get CSV back, automatically.
SQLPlus 11.2.0.4 is approx from 2008, that's quite old.
Here's what you can do with Oracle SQLcl - smaller than SQLPlus, more powerful, and more user-friendly. Also, less code to get what you want.
SQLcl: Release 21.4 Production on Wed Feb 16 08:40:23 2022
Copyright (c) 1982, 2022, Oracle. All rights reserved.
Last Successful login time: Wed Feb 16 2022 08:40:24 -05:00
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
login.sql found in the CWD. DB access is restricted for login.sql.
Adjust the SQLPATH to include the path to enable full functionality.
SQL> set pagesize 200
SQL> cd c:\users\jdsmith\desktop
SQL> spool peeps.csv
SQL> select * from locations;
"LOCATION_ID","STREET_ADDRESS","POSTAL_CODE","CITY","STATE_PROVINCE","COUNTRY_ID"
1000,"1297 Via Cola di Rie","00989","Roma","","IT"
1100,"93091 Calle della Testa","10934","Venice","","IT"
1200,"2017 Shinjuku-ku","1689","Tokyo","Tokyo Prefecture","JP"
1300,"9450 Kamiya-cho","6823","Hiroshima","","JP"
1400,"2014 Jabberwocky Rd","26192","Southlake","Texas","US"
1500,"2011 Interiors Blvd","99236","South San Francisco","California","US"
1600,"2007 Zagora St","50090","South Brunswick","New Jersey","US"
1700,"2004 Charade Rd","98199","Seattle","Washington","US"
1800,"147 Spadina Ave","M5V 2L7","Toronto","Ontario","CA"
1900,"6092 Boxwood St","YSW 9T2","Whitehorse","Yukon","CA"
2000,"40-5-12 Laogianggen","190518","Beijing","","CN"
2100,"1298 Vileparle (E)","490231","Bombay","Maharashtra","IN"
2200,"12-98 Victoria Street","2901","Sydney","New South Wales","AU"
2300,"198 Clementi North","540198","Singapore","","SG"
2400,"8204 Arthur St","","London","","UK"
2500,"Magdalen Centre, The Oxford Science Park","OX9 9ZB","Oxford","Oxford","UK"
2600,"9702 Chester Road","09629850293","Stretford","Manchester","UK"
2700,"Schwanthalerstr. 7031","80925","Munich","Bavaria","DE"
2800,"Rua Frei Caneca 1360 ","01307-002","Sao Paulo","Sao Paulo","BR"
2900,"20 Rue des Corps-Saints","1730","Geneva","Geneve","CH"
3000,"Murtenstrasse 921","3095","Bern","BE","CH"
3100,"Pieter Breughelstraat 837","3029SK","Utrecht","Utrecht","NL"
3200,"Mariano Escobedo 9991","11932","Mexico City","Distrito Federal,","MX"
23 rows selected.
SQL> spool off
SQL>
And here's what that looks like -
If you can update your question with sample DDL and data, we can give you a better answer.
Disclaimer: I'm a product manager at Oracle for our Database tools.

Updating a view in oracle

Below, I have defined some tables, for the relevant ones I have typed in the definitions. Pretty simple, though now I'm trying to raise the salaries for those two employees in the view, and I can't complete the update having that error message you will see below. Anyone could guide me a bit, please??
Definitions for tables employees, projects and employees_projects:
create table employee
(
id number,
name varchar2(20),
mobile varchar2(10),
address varchar2(30),
salary number(6,2),
hire_date date,
department_id number
);
create table project
(
id number,
name varchar2(20),
budget number(10,2),
start_date date,
finish_date date
);
create table employee_projects
(
id number,
employee_id number,
project_id number
);
View definition is:
create view lucky_employees as
select e.name,e.salary from employees e, project p, employee_projects ep
where e.project_id=p.id and e.id=ep.employee_id and p.budget > 1000000.00 ;
SQL> select * from lucky_employees;
ID NAME SALARY
1 Maria 1365.28
2 Sonja 1365.28
Then, I try to update the view by 10%, which is something I know it's possible to do under certain conditions:
SQL>
update lucky_employees set salary = salary * 1.1;
update lucky_employees set salary = salary * 1.1
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table
How would it be to succesfully update it??
Thanks very much, sorry for the inconveniences!!
create view lucky_employees as
select e.name from employees e, project p, employee_projects ep
where e.project_id=p.id and e.id=ep.employee_id and p.budget > 1000000.00 ;
This error is occurring because each salary of your view doesnot uniquely map to a salary of your employees table.
More information from oracle docs is here.
Anoter explanation from Burleson here.

Oracle Precision

I want a number to take values between -7.2E-75 to +7.2E+75. How should I specify precision and scale for the NUMBER. (The scale range is 1 to 38 and precision is -84 to 127).
If there is any other way to accomplish this please suggest.
The numeric values you propose are well within the limits of the Oracle NUMBER datatype.
Do you need to specify a precision? Defining a column as just NUMBER is allowed:
SQL> desc t1
Name Null? Type
----------------------------------------- -------- ----------------------------
COL1 NUMBER
COL2 NUMBER
COL3 NUMBER
COL4 NUMBER
SQL> insert into t1 (col1, col2) values ( -7.2E-75, +7.2E+75);
1 row created.
SQL>
If it's the range bounds which are bothering you, you need to define a CHECK constraint to enforce the rule.
"Suppose i want COL1 to take 123456766675544.344546567676, with NUMBER as datatype its failing"
Failing? How? That value works fine for me (same table as before):
SQL> insert into t1 (col1) values ( 123456766675544.344546567676);
1 row created.
SQL>
So, please provide more details, such as the error message.
"When i fire the above query it is showing just 123456766675544,"
That sounds like a display issue. The right values are being inserted. Check this out:
SQL> set numwidth 50
SQL> select col1 from t1
/
2
COL1
--------------------------------------------------
7.20000000000000000000000000000000000000000000E+75
123456766675544.344546567676
SQL>
In this case, setting the NUMWIDTH to its maximum allowed value ( in SQL*plus) allows us to display one value but the other is still too big, and so we have to use scientific notation.

Trying to export a Oracle via PL/SQL gives a date of 0000-00-00

I have inherited an Oracle .dmp file which I'm trying to get into CSV so that I can load it into MySQL.
The general approach I'm using is described here. I'm having a problem with one row though. It contains a date of 5544-09-14 like so:
alter session set nls_date_format = 'dd-MON-yyyy';
select OID, REF, TRADING_DATE From LOAN WHERE REF = 'XXXX';
OID REF TRADING_DATE
--- -------------------- ------------
1523 XXXX 14-SEP-5544
This is garbage data from the legacy system which didn't validate the input dates. I'm wondering why my PL/SQL function to export the data chokes on this value though?
It exports that row with a TRADING_DATE value of '0000-00-00T00:00:00' and I'm not sure why?
SELECT dump(TRADING_DATE) FROM LOAN WHERE REF = 'XXXX';
DUMP(TRADING_DATE)
--------------------------------------------------------------------------------
Typ=12 Len=7: 44,156,9,14,1,1,1
and
SELECT to_char(trading_date, 'YYYYMMDDHH24MISS') FROM LOAN WHERE REF = 'XXXX';
TO_CHAR(TRADIN
--------------
00000000000000
The value stored in that column is not a valid date. The first byte of the dump should be the century, which according to Oracle support note 69028.1 is stored in 'excess-100' notation, which means it should have a value of 100 + the actual century; so 1900 would be 119, 2000 would be 120, and 5500 would be 155. So 44 would represent -5600; the date you have stored appears to actually represent 5544-09-14 BC. As Oracle only supports dates with years between -4713 and +9999, this isn't recognised.
You can recreate this fairly easily; the trickiest bit is getting the invalid date into the database in the first place:
create table t42(dt date);
Table created.
declare
d date;
begin
dbms_stats.convert_raw_value('2c9c090e010101', d);
insert into t42 (dt) values (d);
end;
/
PL/SQL procedure successfully completed.
select dump(dt), dump(dt, 1016) from t42;
DUMP(DT)
--------------------------------------------------------------------------------
DUMP(DT,1016)
--------------------------------------------------------------------------------
Typ=12 Len=7: 45,56,9,14,1,1,1
Typ=12 Len=7: 2d,38,9,e,1,1,1
So this has a single row with the same data you do. Using alter session I can see what looks like a valid date:
alter session set nls_date_format = 'DD-Mon-YYYY';
select dt from t42;
DT
-----------
14-Sep-5544
alter session set nls_date_format = 'YYYYMMDDHH24MISS';
select dt from t42;
DT
--------------
55440914000000
But if I use an explicit date mask it just gets zeros:
select to_char(dt, 'DD-Mon-YYYY'), to_char(dt, 'YYYYMMDDHH24MISS') from t42;
TO_CHAR(DT,'DD-MON-Y TO_CHAR(DT,'YY
-------------------- --------------
00-000-0000 00000000000000
And if I run your procedure:
exec dump_table_to_csv('T42');
The resultant CSV has:
"DT"
"0000-00-00T00:00:00"
I think the difference is that those that attempt to show the date are sticking with internal date data type 12, while those that show zeros are using external data type 13, as mentioned in note 69028.1.
So in short, your procedure isn't doing anything wrong, the date it's trying to export is invalid internally. Unless you know what date it was supposed to be, which seems unlikely given your starting point, I don't think there's much you can do about it other than guess or ignore it. Unless, perhaps, you know how the data was inserted and can work out how it got corrupted.
I think it's more likely to be from an OCI program than what I did here; this 'raw' trick was originally from here. You might also want to look at note 331831.1. And this previous question is somewhat related.

Are default values supported in Oracle for columns with char semantics?

I was trying to add a column to a table but got a surprising effect with the DEFAULT clause. In a table with existing rows, I added a new column like so:
alter table t add c char(1 char) default 'N' not null;
When I subsequently added a check constraint to the table, it failed:
alter table t add constraint chk check(c in ('N', 'Y'));
Which resulted in
ERROR at line 1:
ORA-02293: cannot validate (T.CHK) - check constraint violated.
Other info:
Because I'm setting the units explicitly (i.e., char(1 char) as opposed to just char(1)), I don't expect the value of nls_length_semanatics to be relevant.
After adding the column as char(1 char), the newly added "N"s are actually "N " and I'm not sure what the extra whitespace is.
Adding the column as char(1 byte) works as expected;
Adding the column without the "default 'N' not null" followed by updating all existing rows to 'N', followed by altering the column to 'not null' also works as expected.
NLS_CHARACTERSET is AL32UTF8, but I don't expect that to be relevant either.
Database is Oracle 11g; 11.2.0.1.0.
Thanks.
I believe that what you're seeing is a bug that relies on a couple different things interacting
First, the database character set has to be a variable width character set (i.e. AL32UTF8) so that a single character may require up to four bytes of storage.
Second, the column must be declared with character length semantics
Third, starting in 11.1, Oracle added an optimization so that if you add a column to the table that is declared NOT NULL and that has a DEFAULT that Oracle could do that simply by updating the data dictionary rather than actually storing the default value in every row of the table.
When both of those things are true, it appears that the value that is returned has a length of 4 and is padded with the CHR(0) character.
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL> create table foo( col1 number );
Table created.
SQL> insert into foo values( 1 );
1 row created.
SQL> commit;
Commit complete.
SQL> alter table foo add c char(1 char) default 'N' not null;
Table altered.
SQL> alter table foo add constraint chk_foo check( c in ('Y', 'N') );
alter table foo add constraint chk_foo check( c in ('Y', 'N') )
*
ERROR at line 1:
ORA-02293: cannot validate (SCOTT.CHK_FOO) - check constraint violated
SQL> select c, dump(c) from foo;
C DUMP(C)
---- ------------------------------
N Typ=1 Len=4: 78,0,0,0
If you actually force the value to be stored in the table, you'll get the expected behavior where there is no CHR(0) padding. So if I insert a new row into the table, it passes.
SQL> insert into foo(col1) values (2);
1 row created.
SQL> select c, dump(c) from foo;
C DUMP(C)
---- ------------------------------
N Typ=1 Len=4: 78,0,0,0
N Typ=1 Len=1: 78
You could also issue an UPDATE to update the rows that aren't actually storing the value in the rows of the table
SQL> update foo
2 set c = 'N'
3 where c != 'N';
1 row updated.
SQL> select c, dump(c) from foo;
C DUMP(C)
---- ------------------------------
N Typ=1 Len=1: 78
N Typ=1 Len=1: 78
You tagged oracle11g, but you didn't specify a version.
This works for me on 11.2.0.2 on Linux x86-64.
SQL*Plus: Release 11.2.0.2.0 Production on Mon Mar 26 13:13:52 2012
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management and OLAP options
SQL> create table tt(a number);
Table created.
SQL> insert into tt values (1);
1 row created.
SQL> commit;
Commit complete.
SQL> alter table tt add c char(1 char) default 'N' not null;
Table altered.
SQL> alter table tt add constraint chk check(c in('N','Y'));
Table altered.
SQL> select * from tt;
A C
---------- -
1 N
SQL> column dump(c) format a30
SQL> select c, length(c),dump(c) from tt;
C LENGTH(C) DUMP(C)
- ---------- ------------------------------
N 1 Typ=96 Len=1: 78
So....perhaps you have a bug in your version?
Hope that helps.
The reason for the ORA-02293 error, as you've already mentioned, is because it is inserting 'N ' (with a padded white space) rather than 'N'. So your constraint is violated.
The more interesting question is, why is it adding that space? Well, by definition, a CHAR is fixed width, where a VARCHAR is not. A CHAR will always pad white space to fill the entire memory space allocated for the column. Because you've chosen a width of 1 CHAR, and AL32UTF8 is a varying width character set, that would seem to conflict with the fixed width nature of CHAR. It looks like it gets padded to fill the extra byte(s) not used by the 'N'. Or, at least, I assume that is what is happening.

Resources