Retrieving column and other metadata information in Teradata - sql

I have a half dozen views in SQL Server that I need to replicate in Teradata, but I haven't been able to find the TD equivalent of the SQL metadata tables. I'd like to replicate the following functionality (which I assume is fairly self-explainatory):
select table_name, column_id ordinal_position, column_name,
data_type, char_length char_max_length,
data_precision numeric_precision, data_scale numeric_scale
from user_tab_columns
select name as FUNCTION_NAME
from sys.objects
where type_desc='SQL_SCALAR_FUNCTION'
select TABLE_NAME as VIEW_NAME
from INFORMATION_SCHEMA.VIEWS
I'd also like to know if there are any usable Teradata references online; everything I run across seems to be advertising rather than practical information.

All Teradata system tables are stored under DBC schema.
For columns, it is dbc.columns
select * from dbc.columns
For views, it is dbc.tables with a filter on a column something named table_type 'V' (where V stands for Views)
select * from dbc.tables
I am not sure about how to get all functions in Teradata. Whoever knows it, please edit this answer.
In Teradata DBC.Tables contains many of the objects that exist on the system. (e.g. Stored Procedures, UDF, Triggers, Macros, Views, Tables, Hash Index, Join Index, etc.) The column Table Kind is used to identify the type of object.
SELECT *
FROM DBC.TABLES
WHERE TABLEKIND = '<see below>'
A = Aggregate Function
B = Combined Aggregate Function and ordered analytical function
D = JAR
E = External Stored Procedure
F = Standard Function
G = Trigger
H = Instance or Constructor Method
I = Join Index
J = Journal
M = Macro
N = Hash Index
O = No Primary Index (Table)
P = Stored Procedure
Q = Queue Table
R = Table Function
S = Ordered Analytical Function
T = Table
U = User-defined data type
V = View
X = Authorization
Y = GLOP Set

Related

Dynamic column query for test script

I am testing tables (and data therein) acquired into our data lake against the source application tables. We do not transform any of the data on acquisition but we do not always acquire all columns of a table and the acquisition process adds several data lake columns to the table (date acquired etc.)
So I have to compare two tables where most of the columns are the same but some aren't. Obviously I can deal with this by manually specifying the columns for each SELECT statement. I want to make a testing script that will do this automatically, comparing the common columns and then allowing me to do further queries using that list of columns.
I already test common columns to ensure data type integrity between columns:
SELECT /*fixed*/
b.column_name,
a.data_type AS source_data_type,
b.data_type AS acquired_data_type,
CASE
WHEN a.data_type = b.data_type THEN 'Pass'
ELSE 'Fail'
END AS DATA_TYPE_TEST
FROM
all_tab_cols#&sourcelink a
INNER JOIN all_tab_cols b ON a.column_name = b.column_name
WHERE
a.owner = '&sourceschema'
AND b.owner = 'DATALAKE'
AND a.table_name = '&tableName'
AND b.table_name = '&tableName';
The above works as intended and gets only common columns. How can I save this list of common columns so that when I'm querying the tables directly I can use them in a further query, such as:
SELECT
<my dynamic list of columns here>
FROM
&sourceschema..&tablename#&sourcelink a
INNER JOIN datalake.&tablename b ON a.id = b.id;
Is this possible with Oracle PL/SQL or should I use python instead?
LISTAGG can reduce this to a column list for you
SQL> select listagg(column_name,',') within group ( order by column_id)
2 from user_tab_columns
3 where table_name = 'EMP';
LISTAGG(COLUMN_NAME,',')WITHINGROUP(ORDERBYCOLUMN_ID)
--------------------------------------------------------------------------
EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO
and then you could return a dynamic ref cursor to whatever client you want to, ie
open my_ref_cur for
'select '||col_list||' from ....';

SQL multiple tables query for column names

I have multiple tables (number > 100) within a database in SQL, each table may have a few hundred entries.
For every table, I am seeking to retrieve simply the names of the columns from the tables which have at least 1 non-null entry.
How can I do this?
To return table/column name:
SELECT table_name, column_name
FROM information_schema.columns
That's pretty easy, here's a solution for nulls depending on if you have permissions:
select a.table_name
, schema_name
, sum(c.rows) total_rows
from
information_schema.tables a
join information_schema.schemas b on (a.schema_id = b.schema_id)
join information_schema.partitions c on (a.object_id = c.object_id)
where c.index_id in (0,1)
group by a.name,b.name
having sum(c.rows) = 0;
Note: I did this in vertica, and you have to have access to partitions. Also, some dbs use sys instead of information_schema, but the idea is the same.

Programmatically get all tables of a database owned by a user

I created the following query:
select
is_tables.table_name
from information_schema.tables is_tables
join pg_tables
on is_tables.table_name=pg_tables.tablename
where
is_tables.table_catalog='<mydatabase>'
and is_tables.table_schema<>'information_schema'
and is_tables.table_schema<>'pg_catalog'
and pg_tables.tableowner='<myuser>';
I assume there is no database vendor independent way of querying this. Is this the easiest/shortest SQL query to achieve what I want in PostgreSQL?
I think you're pretty close. Object owners don't seem to appear in the information_schema views, although I might have overlooked it.
select is_tables.table_schema,
is_tables.table_name
from information_schema.tables is_tables
inner join pg_tables
on is_tables.table_name = pg_tables.tablename
and is_tables.table_schema = pg_tables.schemaname
where is_tables.table_catalog = '<mydatabase>'
and is_tables.table_schema <> 'information_schema'
and is_tables.table_schema <> 'pg_catalog'
and pg_tables.tableowner = '<myuser>';
You need to join on both the table name and the schema name. Table names are unique within a schema; they're not unique within a database.

How to get table comments via SQL in Oracle?

I've tried :
select * from user_tab_comments;
and it returns me 3 columns "TABLE_NAME", "TABLE_TYPE", and "COMMENTS", but the "TABLE_NAME" column is like "encrypted", I need clear table names :
TABLE_NAME TABLE_TYPE COMMENTS
BIN$IN1vjtqhTEKcWfn9PshHYg==$0 TABLE Résultat d'intégration d'une photo numérisée
BIN$PUwG3lb3QoazOc4QaC1sjw==$0 TABLE Motif de fin d'agrément de maître de stage
When I use select * from user_tables; TABLE_NAME is not "encrypted".
Since 10g Oracle doesn't immediately drop tables when we issue a DROP TABLE statement. Instead it renames them like this BIN$IN1vjtqhTEKcWfn9PshHYg==$0 and puts them in the recycle bin. This allows us to recover tables we didn't mean to drop. Find out more.
Tables in the recycle bin are still tables, so they show up in ALL_TABLES and similar views. So if you only want to see comments relating only to live (non-dropped) tables you need to filter by table name:
select * from all_tab_comments
where substr(table_name,1,4) != 'BIN$'
/
"I can't believe there isn't a flag column so you could do and is_recycled = 0 or something. "
You're right, it would be incredible. So I checked the documentation it turns out Oracle 10g added a column called DROPPED to the USER_/ALL_/DBA_TABLES views.
select tc.*
from all_tab_comments tc
join all_tables t
on tc.owner = t.owner
and tc.table_name = t.table_name
where t.dropped = 'NO'
/
Check out the documentation. Obviously the need to join to the ALL_TABLES view requires more typing than filtering on the name, so depending on our need it might just be easier to keep the original WHERE clause.
SELECT t.table_name,t.comments FROM USER_TAB_COMMENTS t WHERE TABLE_NAME = 'SS_DEPT';

How to search informix database for a column

I want to be able to search an Informix DB for a column. In the main table there is a cust_nbr column, that is then referenced in a unknown number of tables.
In Informix, is there a way to query the DB and get all the tables that use the cust_nbr?
SELECT tabname, colno, colname
FROM systables a, syscolumns b
WHERE a.tabid = b.tabid
and colname = "cust_nbr"
ORDER BY colno;
I found this code in the same place and added the extra restriant with colname = cust_nbr.
This seems to have worked for me. i will verify it, but all signs look like it worked.
i found that in the Using the Informix Catalogs mentioned in the other post
You should be able to get this type of thing from the system catalog tables, sysreferences in particular. As taken from Using the Informix System Catalog:
SELECT a.tabname, constrname, d.tabname
FROM systables a, sysconstraints b, sysreferences c,
systables d
WHERE b.constrtype = 'R'
AND a.tabid = b.tabid
AND b.constrid = c.constrid
AND c.ptabid = d.tabid
AND a.tabname = ?;