How to calculate size of table in DB2 - db2-400

I am working on db2 database first time.
My requirement is to get the size of each table in MB/GB in a given schema.
Can anyone please help?

on db2 iseries you can do it
SELECT NUMBER_ROWS, DATA_SIZE FROM qsys2.systablestat
WHERE
TABLE_SCHEMA ='YOURLIBNAME' and table_name='YOURTABLENAME'

One of the many solutions:
select tabschema || '.' || tabname "table",
decimal((data_object_p_size + index_object_p_size +
long_object_p_size + lob_object_p_size +
xml_object_p_size)/1024,10,2) "physical_space_mb",
decimal((data_object_l_size + index_object_l_size +
long_object_l_size + lob_object_l_size +
xml_object_l_size)/1024,10,2) "logical_space_mb"
from sysibmadm.admintabinfo
where tabschema not like 'SYS%'
order by 2 desc;

Related

DataGrip: How to get database and table size for MySQL database?

Using PhyMyAdmin for over a decade I am not looking into datagrip. On thing that I could not find is statistics on database and table size. How much size, how many rows (overwerview), index size in bytes and so on.
Where can I find data statistics in datagrip?
It seems like there is no such feature yet.
For those who came here from Google, you can try use SQL query:
MySql:
SELECT table_schema "Data Base Name", sum( data_length + index_length ) / (1024 * 1024) "Data Base Size in MB" FROM information_schema.TABLES GROUP BY table_schema;
SELECT table_name, round(((data_length + index_length) / (1024*1024)),2) as "size in megs" FROM information_schema.tables WHERE table_schema = "named_db";
PostgreSQL:
SELECT pg_size_pretty( pg_database_size('dbname') );
SELECT pg_size_pretty( pg_total_relation_size('tablename') );
Sources:
https://jonathanstreet.com/blog/disk-space-database-table-mysql-postgresql/
How to get size of mysql database?
For the table, it is impossible now, please follow and upvote: https://youtrack.jetbrains.com/issue/DBE-4281
For the database, there is no even a feature request in DataGrip's tracker. Please add a new one.

How to debug the error "Implicit conversion from datatype 'X' to 'Y' is not allowed"?

While running the below query, I am getting error for field error_num:
Implicit conversion from datatype 'VARCHAR' to 'INT' is not allowed.
Use the CONVERT function to run this query.
Below is the query
select top 100"Insert into KLG_TRN_SCE..dbBatchRequest values ('"
+ comp_nr
+"','"
+ ssn_nr
+"','"
+ convert(char(10),Version,101)
+"','"
+ plan_nr
+"','1"
+"','"
+ CAST(LEFT(error_num, 4) AS int)
+"',"
+ error_txt
+"',"
+ addname
+"',"
+ convert(char(10),adddate,101)
+"')"
From KLG_TRN_SCE..dcErrorBin
Where ssn_nr='603761193'
It appears you're trying to use Sybase or T-SQL against an oracle database. The syntax between databases vary slightly especially around dates, string concat, and string parsing.
So are you looking for execution against Oracle or another database? if oracle, the below should be close.
I'm not sure what you meant by version or what formats you wanted the dates to be in, but this seems to run. I used a with (Common table expression) to stage some data to ensure it ran after all the changes.
So your issues:
No such thing as top we could limit by a rowNum < 101; but an order by should be used
in oracle || is operator for string concat not +
convert(char(10),Version,101) you appear to believe is a date but this is not true in oracle unless version is a field with a date... in which case to_date(version,'DD/MM/YYYY') may be desired?
quotes "are used for field notation much like [] are in T-SQL so to build a dynamic insert, I concat chr(39).
CAST(LEFT(error_num, 4) AS int) is invalid you need to use substr(error_num, 1,4) in oracle
convert(char(10),adddate,101) is invalid in Oracle perhaps you mean to_date(adddate,'MM/DD/YYYY')
.
with dcErrorBin(comp_nr, ssn_nr, version,plan_nr, error_num, error_txt,Addname,adddate) as
(Select 1,'603761193',(SELECT WM_CONCAT(BANNER) FROM V$VERSION),'Three','1234-hello','Error_txt','AddName',sysdate from dual)
SELECT
'Insert into KLG_TRN_SCE..dbBatchRequest values (' || chr(39)
|| comp_nr||Chr(39)
||','
|| chr(39)||ssn_nr||Chr(39)
||','
|| chr(39)||replace(Version,',','~~') || chr(39)
||','
|| chr(39)||plan_nr||Chr(39)
||',1'
||','
|| CAST(substr(error_num,1,4) AS int)
||','
|| chr(39)||error_txt||Chr(39)
||','
|| chr(39)||addname||chr(39)
||','
|| 'to_date('||chr(39)||adddate||chr(39)||','||chr(39)||'DD-MON-YY'||chr(39)||')'
||')'
FROM dcErrorBin
WHERE ssn_nr='603761193'
and rowNum <= 100
ORDER BY ADDDate Desc; --Perhaps order by add date desc so you get most recent errors?
RESULTED IN:
Insert into KLG_TRN_SCE..dbBatchRequest values
('1'
, '603761193'
, 'Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
~~PL/SQL Release 11.2.0.4.0 - Production
~~CORE 11.2.0.4.0 Production
~~TNS for Linux: Version 11.2.0.4.0 - Production
~~NLSRTL Version 11.2.0.4.0 - Production'
, 'Three'
, 1
, 1234
, 'Error_txt'
, 'AddName'
, to_date('14-DEC-16','DD-MON-YY'))
The inserts would error out if
I'm using the wrong date formats
don't have the proper values wrapped in tics
error_num's 1st 4 characters are not numeric.

sysdate difference ( how to make query between sysdate and my table date)

I am new to oracle.
I have some problems to make query.
Im trying to make query that solves the difference between sysdate() and the date from my own table
select to_char(to_char(sysdate,'YYYYMMDDHH24MISS')
- to_char(S_DATE||S_HOUR||':00' , 'YYYYMMDDHH24MISS'))
from dual;
I'm doing like that.
In my table, I have two columns 'S_DATE' and 'S_HOUR' that means time.
So, I would like to know the time difference and how to make this query.
Thank you in advance.
You can get difference between two dates by simple - (minus) operator. However first you need to convert date string to date using TO_DATE.
Sample in SQL Fidlle is here
The sample query:
select
sysdate , S_DATE || ' ' || S_HOUR "Date",
round((sysdate - to_date(s_date || s_hour ,' YYYY/MM/DDHH24:MI') ) * 24 * 60, 2) "Dif In Min",
round((sysdate - to_date(s_date || s_hour ,' YYYY/MM/DDHH24:MI') ) * 24 * 60 * 60, 2) "Dif In Sec"
from myDate

PL/SQL query IN comma deliminated string

I am developing an application in Oracle APEX. I have a string with user id's that is comma deliminated which looks like this,
45,4932,20,19
This string is stored as
:P5_USER_ID_LIST
I want a query that will find all users that are within this list my query looks like this
SELECT * FROM users u WHERE u.user_id IN (:P5_USER_ID_LIST);
I keep getting an Oracle error: Invalid number. If I however hard code the string into the query it works. Like this:
SELECT * FROM users u WHERE u.user_id IN (45,4932,20,19);
Anyone know why this might be an issue?
A bind variable binds a value, in this case the string '45,4932,20,19'. You could use dynamic SQL and concatenation as suggested by Randy, but you would need to be very careful that the user is not able to modify this value, otherwise you have a SQL Injection issue.
A safer route would be to put the IDs into an Apex collection in a PL/SQL process:
declare
array apex_application_global.vc_arr2;
begin
array := apex_util.string_to_table (:P5_USER_ID_LIST, ',');
apex_collection.create_or_truncate_collection ('P5_ID_COLL');
apex_collection.add_members ('P5_ID_COLL', array);
end;
Then change your query to:
SELECT * FROM users u WHERE u.user_id IN
(SELECT c001 FROM apex_collections
WHERE collection_name = 'P5_ID_COLL')
An easier solution is to use instr:
SELECT * FROM users u
WHERE instr(',' || :P5_USER_ID_LIST ||',' ,',' || u.user_id|| ',', 1) !=0;
tricks:
',' || :P5_USER_ID_LIST ||','
to make your string ,45,4932,20,19,
',' || u.user_id|| ','
to have i.e. ,32, and avoid to select the 32 being in ,4932,
I have faced this situation several times and here is what i've used:
SELECT *
FROM users u
WHERE ','||to_char(:P5_USER_ID_LIST)||',' like '%,'||to_char(u.user_id)||',%'
ive used the like operator but you must be a little carefull of one aspect here: your item P5_USER_ID_LIST must be ",45,4932,20,19," so that like will compare with an exact number "',45,'".
When using it like this, the select will not mistake lets say : 5 with 15, 155, 55.
Try it out and let me know how it goes;)
Cheers ,
Alex
Create a native query rather than using "createQuery/createNamedQuery"
The reason this is an issue is that you cannot just bind an in list the way you want, and just about everyone makes this mistake at least once as they are learning Oracle (and probably SQL!).
When you bind the string '32,64,128', it effectively becomes a query like:
select ...
from t
where t.c1 in ('32,64,128')
To Oracle this is totally different to:
select ...
from t
where t.c1 in (32,64,128)
The first example has a single string value in the in list and the second has a 3 numbers in the in list. The reason you get an invalid number error is because Oracle attempts to cast the string '32,64,128' into a number, which it cannot do due to the commas in the string.
A variation of this "how do I bind an in list" question has come up on here quite a few times recently.
Generically, and without resorting to any PLSQL, worrying about SQL Injection or not binding the query correctly, you can use this trick:
with bound_inlist
as
(
select
substr(txt,
instr (txt, ',', 1, level ) + 1,
instr (txt, ',', 1, level+1) - instr (txt, ',', 1, level) -1 )
as token
from (select ','||:txt||',' txt from dual)
connect by level <= length(:txt)-length(replace(:txt,',',''))+1
)
select *
from bound_inlist a, users u
where a.token = u.id;
If possible the best idea may be to not store your user ids in csv! Put them in a table or failing that an array etc. You cannot bind a csv field as a number.
Please dont use: WHERE ','||to_char(:P5_USER_ID_LIST)||',' like '%,'||to_char(u.user_id)||',%' because you'll force a full table scan although with the users table you may not have that many so the impact will be low but against other tables in an enterprise environment this is a problem.
EDIT: I have put together a script to demonstrate the differences between the regex method and the wildcard like method. Not only is regex faster but it's also a lot more robust.
-- Create table
create table CSV_TEST
(
NUM NUMBER not null,
STR VARCHAR2(20)
);
create sequence csv_test_seq;
begin
for j in 1..10 loop
for i in 1..500000 loop
insert into csv_test( num, str ) values ( csv_test_seq.nextval, to_char( csv_test_seq.nextval ));
end loop;
commit;
end loop;
end;
/
-- Create/Recreate primary, unique and foreign key constraints
alter table CSV_TEST
add constraint CSV_TEST_PK primary key (NUM)
using index ;
alter table CSV_TEST
add constraint CSV_TEST_FK unique (STR)
using index;
select sysdate from dual;
select *
from csv_test t
where t.num in ( Select Regexp_Substr('100001, 100002, 100003 , 100004, 100005','[^,]+', 1, Level) From Dual
Connect By Regexp_Substr('100001, 100002,100003, 100004, 100005', '[^,]+', 1, Level) Is Not Null);
select sysdate from dual;
select *
from csv_test t
where ('%,' || '100001,100002, 100003, 100004 ,100005' || ',%') like '%,' || num || ',%';
select sysdate from dual;
select *
from csv_test t
where t.num in ( Select Regexp_Substr('100001, 100002, 100003 , 100004, 100005','[^,]+', 1, Level) From Dual
Connect By Regexp_Substr('100001, 100002,100003, 100004, 100005', '[^,]+', 1, Level) Is Not Null);
select sysdate from dual;
select *
from csv_test t
where ('%,' || '100001,100002, 100003, 100004 ,100005' || ',%') like '%,' || num || ',%';
select sysdate from dual;
drop table csv_test;
drop sequence csv_test_seq;
Solution from Tony Andrews works for me. The process should be added to "Page processing" >> "After submit">> "Processes".
As you are Storing User Ids as String so You can Easily match String Using Like as Below
SELECT * FROM users u WHERE u.user_id LIKE '%'||(:P5_USER_ID_LIST)||'%'
For Example
:P5_USER_ID_LIST = 45,4932,20,19
Your Query Surely Will return Any of 1 User Id which Matches to Users table
This Will Surely Resolve Your Issue , Enjoy
you will need to run this as dynamic SQL.
create the entire string, then run it dynamically.

Drop all the synonyms using cursor

I wanted to drop all the synonyms of a database (sql server 2008 r2) using cursor.
environment-database name- 'mydatabase', schema name- 'dbo'..
Can you please guide me as i did try but the statement of while .. end, is not able to drop the synonym.
what logic should be apply w.r.t cursor?
No need to use a cursor. Do it as set:
declare #n char(1)
set #n = char(10)
declare #stmt nvarchar(max)
select #stmt = isnull( #stmt + #n, '' ) +
'drop synonym [' + SCHEMA_NAME(schema_id) + '].[' + name + ']'
from sys.synonyms
exec sp_executesql #stmt
Similar to Jason's answer with some improvements
Use Quotename() function to wrap the names in square brackets
Initialize the #SQL variable to an empty string, this means that the isnull is not required, and means that when you concatenate the results of the query into a single string it doesn't get the type wrong. String literals in a concatenation can take the default nvarchar size and cause your resulting string to be truncated unexpectedly.
Ensure the string literals are also nvarchar by using the N in front of them.
Filter to the dbo schema only, as the OP requested.
Add the sys schema to the sp_executesql call
Totally agree this is not something where you need a cursor.
DECLARE #SQL NVARCHAR(MAX) = N''
SELECT #SQL += N'DROP SYNONYM ' + QUOTENAME(SCHEMA_NAME([schema_id])) + N'.' + QUOTENAME(name) + N';' + Char(13) + Char(10)
FROM sys.synonyms
WHERE SCHEMA_NAME([schema_id]) = N'dbo'
EXEC sys.sp_executesql #SQL

Resources