Oracle column Datatype from metadata [duplicate] - oracle

I want to get the columns names and datatype and its datatype's length .as example
if there is a table
SQL> create table TestTable(
2 ID VARCHAR2(4) NOT NULL,
3 CODE Number(5),
4 MyDate DATE,
5 MyNumber Number(8,2))
I need something like in some_column to identify separately number(5) is for an integer and number(8,2) is for a desimal value...
I tried this
SELECT column_name, data_type, data_length FROM USER_TAB_COLUMNS WHERE table_name = 'some_table'
but this data_length gives me the length in byte so I can't figure out when there is a case like number(5) ,number(8,2)..what I need is like somthing below
TABLE_NAME COLUMN_NAME DATA_TYPE some_column
------------------------------ ------------------------------ --------------------------
TESTTABLE ID VARCHAR2 4
TESTTABLE MYNAME VARCHAR2 5
TESTTABLE MYDATE DATE -
TESTTABLE MYNUMBER NUMBER 8,2
help?

There are data_precision and data_scale columns there.
Please take a look at this example:
create table qwer(
x number,
y number(8,2),
z number(5,0),
a int,
b decimal(5,3)
);
SELECT column_name, data_type, data_precision, data_scale
FROM USER_TAB_COLUMNS
WHERE Table_name = 'QWER'
;
COLUMN_NAME DATA_TYPE DATA_PRECISION DATA_SCALE
------------- --------- -------------- ----------
B NUMBER 5 3
A NUMBER
X NUMBER
Y NUMBER 8 2
Z NUMBER 5 0
EDIT
To find primary key columns you need to join two dictionary views, please see the below example:
CREATE TABLE pk1(
id int primary key,
name varchar2(10)
);
CREATE TABLE pk2(
id int ,
pk1 number(10,0),
pk2 varchar2(5),
name varchar2(10),
constraint my_composite_pk primary key (id, pk1, pk2 )
);
SELECT c.table_name, cols.column_name, cols.position
FROM user_constraints c
JOIN USER_CONS_COLUMNS cols
USING ( CONSTRAINT_NAME )
WHERE c.table_name IN ('PK1', 'PK2' )
and c.constraint_type = 'P' /* P - means PRIMARY KEY */
ORDER BY 1,3
;
TABLE_NAME COLUMN_NAME POSITION
---------- ----------- ----------
PK1 ID 1
PK2 ID 1
PK2 PK1 2
PK2 PK2 3

If this is only for Geetting information then just Press ALT+F1 on the name of the table this will show you the names of the columns with length and data types.

Why don't you try SELECT * FROM information_schema.columns ?
It has columns "table_schema, table_name, column_name, ordinal_position, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision", etc.

Related

How to generate 18 digit code using cursor based on some conditions in Oracle

I have a table from which I want to generate 18 digit code.
Below is the 18 digit code sample which I want.
R-AP-AP01-SMT-4567
Also for generating the above sample code, here is the data and its logic:
R - Fix value
AP – (2 digit state code from STATE column)
EAST- (From ZONE_NAME column from query below
SMT – (From FORMAT_CODE column from below query)
4567 – (From Store Code column from below query)
SELECT STATE, STORE_CODE, ZONE_NAME FROM TBL_RRSOC_STORE_INFO;
AND
select FORMAT_CODE from TBL_SITE_STORE_FORMAT;
How can it be achieved?
Update
Below is the table description
Table name:- TBL_RRSOC_STORE_INFO
Name Null Type
--------------------------- -------- --------------
RRSOC_ID NOT NULL NUMBER
STORE_CODE NOT NULL NVARCHAR2(55)
STATE NVARCHAR2(55)
SLP_STATE NVARCHAR2(100)
FORMAT_GROUP NVARCHAR2(100)
Table name:- TBL_SITE_STORE_FORMAT
Name Null Type
------------ ---- -------------
ID VARCHAR2(20)
STORE_FORMAT VARCHAR2(100)
ISACTIVE VARCHAR2(3)
FORMAT_GROUP VARCHAR2(100)
FORMAT_CODE VARCHAR2(50)
The way you put it, you'd join those tables somehow (cross join is as good as any other, as you didn't explain it better) and concatenate column values.
Something like this:
SQL> with
2 tbl_rrsoc_store_info (state, store_code, zone_name) as
3 (select 'AP', 'EAST', 'SMT' from dual union all
4 select 'NY', 'WEST', 'XYZ' from dual
5 ),
6 tbl_site_store_format (format_code) as
7 (select 4567 from dual)
8 --
9 select 'R' ||'-'|| r.state ||'-'|| r.store_code ||'-'|| r.zone_name ||'-'|| s.format_code result
10 from tbl_rrsoc_store_info r cross join tbl_site_store_format s;
RESULT
--------------------
R-AP-EAST-SMT-4567
R-NY-WEST-XYZ-4567
SQL>
Function returns a value; you didn't explain how it should look like (which parameters it accepts) so I chose to pass state, presuming it is unique within the table.
Sample data:
SQL> select * From tbl_rrsoc_store_info;
ST STOR ZON
-- ---- ---
AP EAST SMT
NY WEST XYZ
SQL> select * from tbl_site_store_format;
FORMAT_CODE
-----------
4567
Function:
SQL> create or replace function f_test (par_state in varchar2)
2 return varchar2
3 is
4 retval varchar2(18);
5 begin
6 select 'R' ||'-'|| r.state ||'-'|| r.store_code ||'-'|| r.zone_name ||'-'|| s.format_code
7 into retval
8 from tbl_rrsoc_store_info r cross join tbl_site_store_format s
9 where r.state = par_state;
10
11 return retval;
12 end;
13 /
Function created.
Testing:
SQL> select r.state, f_test(r.state) result
2 from tbl_rrsoc_store_info r;
ST RESULT
-- --------------------
AP R-AP-EAST-SMT-4567
NY R-NY-WEST-XYZ-4567
SQL>

Oracle: detect a NOT INMEMORY column

I have a table that has been created with a NOT INMEMORY column:
CREATE TABLE myTable (
foo VARCHAR2(20 BYTE) NOT NULL,
bar VARCHAR2(20 BYTE) NOT NULL,
baz VARCHAR2(2000 BYTE) NOT NULL,
);
ALTER TABLE myTable INMEMORY;
ALTER TABLE myTable NO INMEMORY ("baz") ;
What I need to do is identify the NO INMEMORY column by querying the static data dictionary views, but it appears all_tables, all_tab_columns and similar don't carry this information, and I can't find mention of one in the documentation. Is there a view which does?
You can use the ALL_TABLES and V$IM_COLUMN_LEVEL views to get the information. The information was found on Oracle-Base.
SQL> select inmemory from all_tables
2* where table_name = 'MYTABLE';
INMEMORY
___________
ENABLED
SQL> SELECT table_name,
2 segment_column_id,
3 column_name,
4 inmemory_compression
5 FROM v$im_column_level
6 WHERE table_name = 'MYTABLE'
7* ORDER BY segment_column_id;
TABLE_NAME SEGMENT_COLUMN_ID COLUMN_NAME INMEMORY_COMPRESSION
_____________ ____________________ ______________ _______________________
MYTABLE 1 FOO DEFAULT
MYTABLE 2 BAR DEFAULT
MYTABLE 3 BAZ NO INMEMORY

View and Table Column Size mismatch due to UNION

I have created View using unioned CVAS:
CREATE
OR REPLACE VIEW SAMPLEVIEW AS
SELECT
PT.CREDITPARTYACCOUNT AS PT_CREDITPARTYACCOUNT,
PT.DEBITPARTYACCOUNT AS PT_DEBITPARTYACCOUNT,
...
...
FROM
accountingevent AE
LEFT OUTER JOIN paymenttransaction PT ON (
AE.PAYMENTTRANSACTIONKEY = PT.PAYMENTTRANSACTIONKEY
)
OR (
AE.PAYMENTINSTRUCTIONKEY = PT.INCOMINGINSTRUCTIONKEY
)
WHERE
...
UNION ALL
SELECT
PT.CREDITPARTYACCOUNT AS PT_CREDITPARTYACCOUNT,
PT.DEBITPARTYACCOUNT AS PT_DEBITPARTYACCOUNT,
...
...
FROM
accountingevent AE
LEFT OUTER JOIN paymenttransaction PT ON (
AE.PAYMENTTRANSACTIONKEY = PT.PAYMENTTRANSACTIONKEY
)
WHERE
...
ORDER BY 1;
Result of
DESC SAMPLEVIEW;
PT_CREDITPARTYACCOUNT VARCHAR2(1024 CHAR)
PT_DEBITPARTYACCOUNT VARCHAR2(1024 CHAR)
...
...
AND
DESC PAYMENTTRANSACTION;
CREDITPARTYACCOUNT VARCHAR2(256 CHAR)
DEBITPARTYACCOUNT VARCHAR2(256 CHAR)
...
Data Sizes I get are 4 times the size of table column sizes.
If we remove the UNION ALL and go with single CVAS than sizes becomes equal in table and view.
This view and tables are part of large scripts so something in scripts is off which is causing this behavior.
This odd behavior is only visible with char and varchar2 datatypes.
I also checked the result of the following query:
select * from NLS_DATABASE_PARAMETERS where parameter='NLS_CHARACTERSET';
NLS_CHARACTERSET AL32UTF8
Kindly guide me on what could be wrong here which is causing this behavior.
Thanks
Which version are you testing? Here's what I get on my DB (20.2):
SQL> desc tukc
Name Null? Type
----------- ----- ------------------
OBJECT_NAME VARCHAR2(128 CHAR)
OBJECT_ID NUMBER
SQL>
SQL> create or replace view tv as
2 select t.object_name
3 from tukc t join all_objects o on (t.object_id=o.object_id)
4 union all
5 select t.object_name
6 from tukc t join all_objects o on (t.object_id=o.object_id)
7 ;
View TV created.
SQL> desc tv
Name Null? Type
----------- ----- ------------------
OBJECT_NAME VARCHAR2(128 CHAR)

Copy from VARCHAR field to NUMBER field such that VARCHAR value becomes null after being copied to NUMBER field

I have two tables Table1 and Table2 both with the same columns TestResult and Testcounts. Table1 has testresult as varchar and Table2 has testresult as number.
I have a string .for eg "Oracle" as value for testresult of varchar type for Table1 which needs to be inserted to testresult of number type of Table2 as null.How can i do this? Any suggestions will be highly appreciated :)
EDIT
I have table1 with columns as TestResult varchar2(50) and Testcount number with values as "0.5","0.6","0.8","Oracle" for TestResult and 1,2,3,4 for Testcount.
Now i have another table Table2 as TestResult number and Testcount number with no values, in other words its empty.. I would like to insert all data from table1 to table2 with "Oracle" being inserted as "null"
The following will do what you've asked for:
INSERT INTO TABLE2 (TESTRESULT, TESTCOUNTS)
SELECT CASE
WHEN LENGTH(REGEXP_SUBSTR(TESTRESULT, '[0-9.]*')) = LENGTH(TESTRESULT) THEN TESTRESULT
ELSE NULL
END,
TESTCOUNTS
FROM TABLE1
SQLFiddle here
If you only have a single string value that you can't convert to a number, and you want to set that to null, you can just use a case expression to supply the null:
insert into table2 (testresult, testcounts)
select case when testresult = 'Oracle' then null else to_number(testresult) end,
testcounts
from table1;
Demo:
create table table1 (testresult varchar2(10), testcounts number);
insert into table1
select '0.5', 1 from dual
union all select '0.6', 2 from dual
union all select '0.8', 3 from dual
union all select 'Oracle', 4 from dual;
create table table2 (testresult number, testcounts number);
insert into table2 (testresult, testcounts)
select case when testresult = 'Oracle' then null else to_number(testresult) end,
testcounts
from table1;
select * from table2;
TESTRESULT TESTCOUNTS
---------- ----------
.5 1
.6 2
.8 3
4
db<>fiddle
If you are using Oracle 12c Release 2 (or above) you could also just try to convert the string to a number and use the default ... on conversion error clause to substitute null for that, or any other, non-numeric value:
insert into table2 (testresult, testcounts)
select to_number(testresult default null on conversion error), testcounts
from table1;
select * from table2;
TESTRESULT TESTCOUNTS
---------- ----------
.5 1
.6 2
.8 3
4
In earlier versions you could do the same thing with a user-defined function that wraps the real to_number() call and returns null on error. Or a regex/translate check similar to what #BobJarvis has shown.
Having multiple rows with null would make the data hard to interpret though, so hopefully you only have this one fixed value...

What is the difference between column_name and qualified_col_name?

The following query on the standard view user_tab_col:
select * from user_tab_cols;
returns on Oracle the columns column_name and qualified_col_name.
What is the difference?
qualified_col_name indicates full column path for XML tables. Basically it stores the expression for this column. For regular columns it will be equal to column_name.
If you run:
select owner, table_name, column_name, data_type, qualified_col_name
from all_tab_cols
where column_name <> qualified_col_name;
you will see returned columns from XML tables in XDB schema.
For example:
OWNER TABLE_NAME COLUMN_NAME DATA_TYPE QUALIFIED_COL_NAME
XDB XDB$SIMPLE_TYPE SYS_NC00074$ XDB$APPINFO_LIST_T "XMLDATA"."RESTRICTION"."MIN_INCLUSIVE"."ANNOTATION"."APPINFO"
Update:
For object tables qualified_col_name stores expression of type casting and accessing to attribute. For example:
create or replace type test1_obj as object(
n1 number,
n2 number,
s1 varchar2(10),
s2 varchar2(20)
)
not final;
create or replace type test2_obj under test1_obj(
d1 date,
d2 date
)
not final;
create table object_table of test1_obj;
select column_name, data_type, qualified_col_name
from user_tab_cols
where table_name = 'OBJECT_TABLE'
order by internal_column_id;
For last 2 hidden system columns reserved for instances of type test2_obj we can see:
COLUMN_NAME DATA_TYPE QUALIFIED_COL_NAME
SYS_NC00010$ DATE TREAT(SYS_NC_ROWINFO$ AS "TEST"."TEST2_OBJ")."D1"
SYS_NC00011$ DATE TREAT(SYS_NC_ROWINFO$ AS "TEST"."TEST2_OBJ")."D2"

Resources