qu = 'SELECT DS.TABLESPACE_NAME AS SCHEMA_NAME,
SEGMENT_NAME AS TABLE_NAME,
ROUND(SUM(DS.BYTES) / (1024 * 1024)) AS MB
FROM DBA_SEGMENTS DS
WHERE SEGMENT_NAME IN (SELECT TABLE_NAME
FROM DBA_TABLES)
GROUP BY DS.TABLESPACE_NAME, SEGMENT_NAME;'
When I'm executing this query in the synapse notebook, it says "missing right parenthesis".
Can anyone help pls?
Seems to be OK, unless you need to remove the terminating semi-colon:
... GROUP BY DS.TABLESPACE_NAME, SEGMENT_NAME;'
^
|
here
Query itself runs OK:
SQL> SELECT ds.tablespace_name AS schema_name,
2 segment_name AS table_name,
3 round(SUM(ds.bytes)/(1024 * 1024)) AS mb
4 FROM dba_segments ds
5 WHERE segment_name IN (SELECT table_name
6 FROM dba_tables
7 )
8 GROUP BY ds.tablespace_name,
9 segment_name;
SCHEMA_NAME TABLE_NAME MB
------------------------------ ---------- ----------
SYSTEM OBJ$ 2
SYSTEM UNDO$ 0
SYSTEM FILE$ 0
<snip>
Related
I want to get schema name, table name and a boolean column for primary keys (if primary key exists in the table).
I used this query to do the task:
select DISTINCT row_number() over(order by q.Schema, q.TableName, q.constraint_type) as Id
,q.Schema
,q.TableName
,q.constraint_type
from (
select at.owner as Schema
, at.table_name as TableName
,ac.constraint_type
from ALL_TABLES at
left join ALL_CONSTRAINTS ac
on ac.owner = at.owner and ac.table_name = at.table_name
where at.temporary = 'N'
and at.owner in ( 'Source_schema' )
and at.owner not in ( 'CTXSYS', 'MDSYS', 'SYSTEM', 'XDB','SYS' )
and ac.constraint_type in ('P','R','C') or ac.constraint_type != null
group by at.owner, at.table_name,ac.constraint_type ) q
order by q.TableName asc
I want to get all the table names and in the third column I want to know if that table contains a primary key.
With this query, I am getting duplicate table names because it can contain more than one keys. But I only want to have a flag which tells if there is a primary key in that table.
Here is the output of the above query which has duplicate table names:
Isn't that what you asked for? This condition:
and ac.constraint_type in ('P','R','C')
will return 3 constraint types, while you need only primary keys. Therefore, remove R and C.
Alternatively, if you modify query a little bit so that constraint_type contains all types and add another column (a flag, which shows whether that table contains a primary key or not), you'd get this (I commented filter at line #16):
SQL> SELECT ROW_NUMBER () OVER (ORDER BY q.schema, q.tablename) AS id,
2 q.schema,
3 q.tablename,
4 LISTAGG (q.constraint_type, ', ')
5 WITHIN GROUP (ORDER BY q.constraint_type) constraint_type,
6 MAX (CASE WHEN q.constraint_type = 'P' THEN '*' ELSE NULL END) contains_pk
7 FROM (SELECT DISTINCT
8 at.owner AS schema,
9 at.table_name AS tablename,
10 ac.constraint_type
11 FROM all_tables at
12 LEFT JOIN all_constraints ac
13 ON ac.owner = at.owner
14 AND ac.table_name = at.table_name
15 WHERE at.temporary = 'N'
16 --AND at.owner IN ('Source_schema') --> commented
17 AND at.owner NOT IN ('CTXSYS',
18 'MDSYS',
19 'SYSTEM',
20 'XDB',
21 'SYS')
22 AND ac.constraint_type IN ('P', 'R', 'C')
23 OR ac.constraint_type IS NOT NULL) q
24 GROUP BY q.schema, q.tablename
25 ORDER BY q.tablename ASC;
Result:
ID SCHEMA TABLENAME CONSTRAINT C
---------- -------------------- ------------------------------ ---------- -
1 SCOTT ADVISER P, R *
2 SCOTT BOOK_NAMES C, P *
3 SCOTT CARTE P, R *
4 SCOTT COMPTE P *
5 SCOTT DEPARTMENT P *
6 SCOTT DOCUMENT_TO_DROP P *
7 SCOTT EMP C
8 SCOTT EMPLEADO1 C
9 SCOTT EMPLEADO2 C
10 SCOTT EMPLOYEES C
11 SCOTT FILIALI_CHIUSE C
12 SCOTT NEW_DEPT P *
13 SCOTT NOVCET P *
14 SCOTT ORDERS P *
15 SCOTT PERSONAL_INFO C
16 SCOTT RECORDING C, P, R *
17 SCOTT TEACHER P *
18 SCOTT VIEWS P *
18 rows selected.
SQL>
[EDIT] According to comments you posted, you'd want to see tables that don't have any constraints. Currently, you can't because of conditions you put into the query - you explicitly specified that constraint type can't be NULL (note that such a condition isn't != null but is not null). Therefore, remove it. For example:
SQL> WITH
2 data
3 AS
4 (SELECT DISTINCT at.owner, at.table_name, ac.constraint_type
5 FROM all_tables at
6 LEFT JOIN all_constraints ac
7 ON ac.owner = at.owner
8 AND ac.table_name = at.table_name
9 WHERE at.temporary = 'N'
10 AND at.owner NOT IN ('CTXSYS',
11 'MDSYS',
12 'SYSTEM',
13 'XDB',
14 'SYS'))
15 SELECT ROW_NUMBER () OVER (ORDER BY owner, table_name) rn,
16 owner,
17 table_name,
18 LISTAGG (constraint_type, ', ')
19 WITHIN GROUP (ORDER BY constraint_Type) constraint_type,
20 MAX (CASE WHEN constraint_type = 'P' THEN '*' ELSE NULL END) contains_pk
21 FROM data
22 GROUP BY owner, table_name
23 ORDER BY owner, table_name;
Result:
RN OWNER TABLE_NAME CONSTRAINT_TYPE CONTAINS_PK
---------- --------------- ------------------------------ --------------- -----------
1 ISPO TOAD_PLAN_TABLE
2 SCOTT ACCNT_PROFILE_SPCL
3 SCOTT ADVISER P, R *
4 SCOTT AUSRÜSTUNG
5 SCOTT AUTH_USER_REGISTRATION
6 SCOTT BF_USER
7 SCOTT BONUS
8 SCOTT BOOK_NAMES C, P *
9 SCOTT CARTE P, R *
10 SCOTT CATALOG
<snip>
71 SCOTT TUSER
72 SCOTT VIEWS P *
73 SCOTT WAFFEN
73 rows selected.
SQL>
I am reviewing code written by a previous colleague. It uses a "natural join", which I am unfamiliar with and never used.
I would like to change this into JOIN inner, outer, left….. whatever the correct equivalent is, which shows what is actually being joined.
Below is my test case. Any help would be greatly appreciated.
create table holidays(
holiday_date DATE not null,
holiday_name VARCHAR2(20),
constraint holidays_pk primary key (holiday_date),
constraint is_midnight check ( holiday_date = trunc ( holiday_date ) )
);
INSERT into holidays (HOLIDAY_DATE,HOLIDAY_NAME)
WITH dts as (
select to_date('25-NOV-2021 00:00:00','DD-MON-YYYY HH24:MI:SS'), 'Thanksgiving 2021' from dual union all
select to_date('29-NOV-2021 00:00:00','DD-MON-YYYY HH24:MI:SS'), 'Hanukkah 2021' from dual
)
SELECT * from dts;
SELECT constraint_name, constraint_type, column_name
from user_constraints natural join user_cons_columns
where table_name = 'HOLIDAYS';
CONSTRAINT_NAME CONSTRAINT_TYPE COLUMN_NAME
SYS_C0075523509 C HOLIDAY_DATE
IS_MIDNIGHT C HOLIDAY_DATE
HOLIDAYS_PK P HOLIDAY_DATE
In a natural join, Oracle creates an "implicit" join clause based on common column names. If you want to switch to inner join, you'll have to do it yourself.
Natural:
SQL> SELECT constraint_name, constraint_type, column_name
2 from user_constraints natural join user_cons_columns
3 where table_name = 'EMP';
CONSTRAINT_NAME C COLUMN_NAME
------------------------------ - --------------------
SYS_C00105284 C EMPNO
PK_EMP P EMPNO
Which columns are common? Let's see:
SQL> select column_name from all_tab_columns where table_name = 'USER_CONSTRAINTS'
2 intersect
3 select column_name from all_tab_columns where table_name = 'USER_CONS_COLUMNS';
COLUMN_NAME
--------------------
CONSTRAINT_NAME
OWNER
TABLE_NAME
SQL>
Inner:
SQL> SELECT a.constraint_name, a.constraint_type, b.column_name
2 from user_constraints a join user_cons_columns b
3 on a.constraint_name = b.constraint_name
4 and a.owner = b.owner
5 and a.table_name = b.table_name
6 where a.table_name = 'EMP';
CONSTRAINT_NAME C COLUMN_NAME
------------------------------ - --------------------
SYS_C00105284 C EMPNO
PK_EMP P EMPNO
SQL>
OK, but - we know better. As we're querying user_cons... views, they contain data we own so we don't really need an owner. Moreover, constraint names are unique within a single schema, so we don't need table_name either. Therefore, this would do:
SQL> SELECT a.constraint_name, a.constraint_type, b.column_name
2 from user_constraints a join user_cons_columns b on a.constraint_name = b.constraint_name
3 where a.table_name = 'EMP';
CONSTRAINT_NAME C COLUMN_NAME
------------------------------ - --------------------
SYS_C00105284 C EMPNO
PK_EMP P EMPNO
SQL>
What should I add in this given query to get the schema name of the tables?
SELECT DS.TABLESPACE_NAME AS schema_name,
SEGMENT_NAME AS table_name,
a.num_rows AS row_count,
ROUND(SUM(DS.BYTES) * 8 * 1024) AS total_space_bytes,
ROUND(SUM(DS.BYTES) * 8) AS total_space_kilobytes,
ROUND(SUM(DS.BYTES) / (1024/1000)) AS total_space_megabytes,
CASE WHEN a.partitioned='NO' THEN 0 WHEN a.partitioned='YES'THEN 1 ELSE
0 END AS is_table_partitioned
FROM DBA_SEGMENTS
DS JOIN (SELECT table_name,tablespace_name,owner,num_rows,partitioned
FROM all_tables)a ON a.table_name=DS.SEGMENT_NAME AND
DS.TABLESPACE_NAME = a.tablespace_name
WHERE
segment_type='TABLE' AND SEGMENT_NAME IN (SELECT TABLE_NAME FROM
DBA_TABLES)
GROUP BY DS.TABLESPACE_NAME,
SEGMENT_NAME,a.num_rows,a.partitioned ORDER BY SEGMENT_NAME
Add dba_segments.owner column to it (don't forget to include it into the group by clause as well):
SELECT ds.tablespace_name AS schema_name,
ds.owner, --> this
segment_name AS table_name,
a.num_rows AS row_count,
ROUND (SUM (ds.bytes) * 8 * 1024) AS total_space_bytes,
ROUND (SUM (ds.bytes) * 8) AS total_space_kilobytes,
ROUND (SUM (ds.bytes) / (1024 / 1000)) AS total_space_megabytes,
CASE
WHEN a.partitioned = 'NO' THEN 0
WHEN a.partitioned = 'YES' THEN 1
ELSE 0
END AS is_table_partitioned
FROM dba_segments ds
JOIN
(SELECT table_name,
tablespace_name,
owner,
num_rows,
partitioned
FROM all_tables) a
ON a.table_name = ds.segment_name
AND ds.tablespace_name = a.tablespace_name
WHERE segment_type = 'TABLE'
AND segment_name IN (SELECT table_name FROM dba_tables)
GROUP BY ds.owner,
ds.tablespace_name,
segment_name,
a.num_rows,
a.partitioned
ORDER BY segment_name
I have a requirement to come up with a break down of the below
overall DWH SIZE
used space
free space
break down of space per schema (example STAGE,EDW/CORE,MART....) (point 1,2,3 must be covered)
4.1 - I am interested to see specifically all the schemas break down by total table size vs used size
(tables), i have tried the below queries (1 to 5)
upon checking various posts it's bit confusing
some suggests checking the following tables
DATA_SIZE (to check the data files)
TEMP_SIZE (to check the temporaryfiles)
SYS.V_$LOG (to check the redo log files)
V$CONTROLFILE (to check the redo log files) DBA_SEGMENTS
i have tested the below queries
Query 1 - actual size of the database
SELECT SUM (bytes) / 1024 / 1024 / 1024 AS GB FROM dba_data_files;
RESULT - GB
GB
900 - only example
Query 2 - Gives the size occupied by data in this database or Database usage details
SELECT SUM (bytes)/1024/1024/1024 AS GB FROM dba_segments;
RESULT- GB
GB
900 - only example
Query 3 - overall database size in TB
SELECT
( SELECT SUM(BYTES)/1024/1024/1024/1024 DATA_SIZE FROM DBA_DATA_FILES ) +
( SELECT NVL(SUM(BYTES),0)/1024/1024/1024/1024 TEMP_SIZE FROM DBA_TEMP_FILES ) +
( SELECT SUM(BYTES)/1024/1024/1024/1024 REDO_SIZE FROM SYS.V_$LOG ) +
( SELECT SUM(BLOCK_SIZE*FILE_SIZE_BLKS)/1024/1024/1024/1024 CONTROLFILE_SIZE FROM V$CONTROLFILE) "SIZE IN TB"
FROM
DUAL
RESULT- TB
SIZE IN TB
100 - only example
Query 4 - Database Size in TB with use space and free space Oracle DB
select round(sum(used.bytes) / 1024 / 1024 / 1024/1024 ) || 'TB' "Database Size"
, round(sum(used.bytes) / 1024 / 1024 / 1024/1024 ) -
round(free.p / 1024 / 1024 / 1024/1024) || 'TB' "Used space"
, round(free.p / 1024 / 1024 / 1024/1024) || 'TB' "Free space"
from (select bytes
from v$datafile
union all
select bytes
from v$tempfile
union all
select bytes
from v$log) used
, (select sum(bytes) as p
from dba_free_space) free
group by free.p
/
RESULT- TB
Database Size Used space Free space
100 90 10
Query 5 - QUERY TO GET SIZE OF ALL TABLES IN AN ORACLE DATABASE SCHEMA
SELECT * FROM
(
SELECT
OWNER,
OBJECT_NAME,
OBJECT_TYPE,
TABLE_NAME,
--ROUND(BYTES)/1024/1024 AS MB,
ROUND(BYTES) / 1024 / 1024 / 1024 AS GB,
--ROUND(100*RATIO_TO_REPORT(ROUND(BYTES) / 1024 / 1024 / 1024) OVER(),2) AS GB_PERCENT,
ROUND(100*RATIO_TO_REPORT(BYTES) OVER (), 2) PERCENTAGE,
TABLESPACE_NAME,
EXTENTS,
INITIAL_EXTENT,
ROUND(SUM(BYTES/1024/1024/1024) OVER (PARTITION BY TABLE_NAME)) AS TOTAL_TABLE_GB
--ROUND(SUM(BYTES)/1024/1024/1024) OVER (PARTITION BY TABLE_NAME)) AS TOTAL_TABLE_GB
FROM
(
--TABLES
SELECT OWNER, SEGMENT_NAME AS OBJECT_NAME, 'TABLE' AS OBJECT_TYPE,
SEGMENT_NAME AS TABLE_NAME, BYTES,
TABLESPACE_NAME, EXTENTS, INITIAL_EXTENT
FROM DBA_SEGMENTS /*DBA_SEGMENTS*/
WHERE SEGMENT_TYPE IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
UNION ALL
--INDEXES
SELECT I.OWNER, I.INDEX_NAME AS OBJECT_NAME, 'INDEX' AS OBJECT_TYPE,
I.TABLE_NAME, S.BYTES,
S.TABLESPACE_NAME, S.EXTENTS, S.INITIAL_EXTENT
FROM DBA_INDEXES I /*DBA_INDEXES*/
, DBA_SEGMENTS S /*DBA_SEGMENTS*/
WHERE S.SEGMENT_NAME = I.INDEX_NAME
AND S.OWNER = I.OWNER
AND S.SEGMENT_TYPE IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
--LOB SEGMENTS
UNION ALL
SELECT L.OWNER, L.COLUMN_NAME AS OBJECT_NAME, 'LOB_COLUMN' AS OBJECT_TYPE,
L.TABLE_NAME, S.BYTES,
S.TABLESPACE_NAME, S.EXTENTS, S.INITIAL_EXTENT
FROM DBA_LOBS L, /*DBA_LOBS*/
DBA_SEGMENTS S /*DBA_SEGMENTS*/
WHERE S.SEGMENT_NAME = L.SEGMENT_NAME
AND S.OWNER = L.OWNER
AND S.SEGMENT_TYPE = 'LOBSEGMENT'
--LOB INDEXES
UNION ALL
SELECT L.OWNER, L.COLUMN_NAME AS OBJECT_NAME, 'LOB_INDEX' AS OBJECT_TYPE,
L.TABLE_NAME, S.BYTES,
S.TABLESPACE_NAME, S.EXTENTS, S.INITIAL_EXTENT
FROM DBA_LOBS L, /*DBA_LOBS*/
DBA_SEGMENTS S /*DBA_SEGMENTS*/
WHERE S.SEGMENT_NAME = L.INDEX_NAME
AND S.OWNER = L.OWNER
AND S.SEGMENT_TYPE = 'LOBINDEX'
)
WHERE OWNER IN UPPER('&SCHEMA_NAME')
)
--WHERE TOTAL_TABLE_MB > 10
ORDER BY TOTAL_TABLE_GB DESC, GB DESC
/
EXPECTED_RESULTS
OWNER OBJECT_TYPE TOTAL_SPACE_GB TOTAL_SPACE_USED_GB PERCENTAGE_GB
DWH_STAGE TABLE 400 200 50
DWH_EDW TABLE 800 400 50
DWH_MART TABLE 1600 800 50
could you please suggest how to achieve this ?
This shows space within table segments if that is what you want but I think you probably want free space by tablespace instead.
select t.owner,'TABLE' OBJECT_TYPE ,t.TOTAL_SPACE_GB, u.TOTAL_SPACE_USED_GB,(u.TOTAL_SPACE_USED_GB/t.TOTAL_SPACE_GB)*100 PERCENTAGE_USED
from
(select owner,sum(bytes)/(1024*1024*1024) TOTAL_SPACE_GB
from dba_segments
where segment_type like 'TABLE%'
group by owner) t,
(select owner, sum(NUM_ROWS*AVG_ROW_LEN)/(1024*1024*1024) TOTAL_SPACE_USED_GB
from dba_tables
group by owner) u
where
t.owner=u.owner
order by owner;
Bobby
How can i get the information about all tables space in my database in below format.
TABLESPACE_NAME | FILE_NAME | ALLOCATED_MB | FREE_MB | CAPACITY |
Is there way to store daily size of all table-space in another table automatically ?. Actually i need to prepare checklist regarding table space on daily basis. So I wan't to create front end which email me the table space size details automatically on the basis of that table which store the information about table space size on daily basis..
Try the below query to get all tablespace details in oracle. Assuming that you have the necessary privileges to access dba tables.
SELECT a.file_name,
substr(A.tablespace_name,1,14) tablespace_name,
trunc(decode(A.autoextensible,'YES',A.MAXSIZE-A.bytes+b.free,'NO',b.free)/1024/1024) free_mb,
trunc(a.bytes/1024/1024) allocated_mb,
trunc(A.MAXSIZE/1024/1024) capacity,
a.autoextensible ae
FROM (
SELECT file_id, file_name,
tablespace_name,
autoextensible,
bytes,
decode(autoextensible,'YES',maxbytes,bytes) maxsize
FROM dba_data_files
GROUP BY file_id, file_name,
tablespace_name,
autoextensible,
bytes,
decode(autoextensible,'YES',maxbytes,bytes)
) a,
(SELECT file_id,
tablespace_name,
sum(bytes) free
FROM dba_free_space
GROUP BY file_id,
tablespace_name
) b
WHERE a.file_id=b.file_id(+)
AND A.tablespace_name=b.tablespace_name(+)
ORDER BY A.tablespace_name ASC;
Select a.tablespace_name,a.file_name,a.bytes/1024/1024 TABLESPACE_SIZE_MB,
Sum(b.bytes)/1024/1024 FREE_IN_MB from dba_free_space b,dba_data_files a
Where a.tablespace_name = b.tablespace_name
AND a.file_id = b.file_id
GROUP by a.tablespace_name, a.file_name,a.bytes/1024/1024
Order by a.tablespace_name, a.file_name;
you can run this query this may help.
Above are useful. Hope this may also helpful here:
https://ora-data.blogspot.in/2016/12/how-to-find-details-of-tablespace.html
Check the Tablespace details with different command, above command may not work:
SQL>select round((bytes/1024)/1024,0) "Used Space(MB)",
round(total,0) "Allocated size(MB)",
round(max,0) "Maximum allowable(MB)",
round(max-(BYTES/1024)/1024,0) "Effective free(MB)",
round(((max-(BYTES/1024)/1024)/max)*100,2) "FREE(%)"
from SYS.SM$TS_USED,
(select sum((BYTES/1024)/1024) total, sum((decode(MAXBYTES,0,bytes,maxbytes)/1024)/1024) max
from dba_data_files where tablespace_name='&1') where tablespace_name='&1';
In Oracle refer below link :
How do I calculate tables size in Oracle
https://forums.oracle.com/thread/2160787
COLUMN TABLE_NAME FORMAT A32
COLUMN OBJECT_NAME FORMAT A32
COLUMN OWNER FORMAT A10
SELECT
owner, table_name, TRUNC(sum(bytes)/1024/1024) Meg
FROM
(SELECT segment_name table_name, owner, bytes
FROM dba_segments
WHERE segment_type = 'TABLE'
UNION ALL
SELECT i.table_name, i.owner, s.bytes
FROM dba_indexes i, dba_segments s
WHERE s.segment_name = i.index_name
AND s.owner = i.owner
AND s.segment_type = 'INDEX'
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.segment_name
AND s.owner = l.owner
AND s.segment_type = 'LOBSEGMENT'
UNION ALL
SELECT l.table_name, l.owner, s.bytes
FROM dba_lobs l, dba_segments s
WHERE s.segment_name = l.index_name
AND s.owner = l.owner
AND s.segment_type = 'LOBINDEX')
WHERE owner in UPPER('&owner')
GROUP BY table_name, owner
HAVING SUM(bytes)/1024/1024 > 10 /* Ignore really small tables */
ORDER BY SUM(bytes) desc
;
In SQL refer below
Get size of all tables in database