Oracle SQL: selecting from all_tab_columns does not find existing column - sql

If I run the following query:
select count(*) from all_tab_columns
where column_name = 'foo'
and table_name = 'VIEW0';
I get 0 for a result. I expect 1.
But if I run the following query I get many (expected) rows returned:
select foo from VIEW0;
Why? I'm assuming I'm making some dumb syntax mistake or my understanding is way off.

Probably the reason is that you have case sensitive setting.
Try to add UPPER function as below.
select count(*) from all_tab_columns
where column_name = upper('foo')
and table_name = 'VIEW0';

ALL_TAB_COLUMNS describes the columns of the tables, views, and clusters accessible to the current user. Check, if user under whom you running this query have access to the desired table.

It appears, at least in 11g, that you cannot access the data dictionary tables from PL/SQL. Running any select on all_tab_columns inside PL/SQL always returns no results. Attempting to access dba_tab_columns will not compile, because the compiler believes the table (or view) does not exist.
I'd love to see how to access the data dictionary from PL/SQL.

Related

How to list the user created table name in sql?

I created like 20 tables in sql 11g and lost the record of them. Is there any way I can list the table names I created.
SELECT table_name FROM user_tables is not the solution.
First, log on as sys before you can view the tables in the entire database.
Second, run this query using the sys
SELECT owner, table_name FROM dba_tables WHERE owner='HR';
This should display all tables owned by the HR schema. Remember to use uppercase for the owner (HR) else you will receive error.
Hope this helps.
The Best approach to solve this issue is considering the attribute of ALL_ALL_TABLES named
LAST_ANALYZED
It gives Date on which the table was most recently analyzed.
So you could easily query the database with the help of DATE Functions.
The Oracle Database Reference helps you.
SELECT TABLE_NAME FROM USER_ALL_TABLES
Well, if user_all_tables is not your desired result, you will have to rely on dba_tables via:
SELECT owner, table_name
FROM dba_tables
But for this you need more privs than for user_tables obviously

Select column_name from cols return nothing although column exists

i am trying to execute this statement in Oracle 9i. However it seems that the result set is empty although J am very sure that there are many columns with the name ID.
select * from cols where column_name like '%ID%';
Also, the following statement returns an empty result set.
select * from cols;
May I ask if this could be due to user privilege?
Thanks!
The Oracle Reference says of COLS:
"COLS is a synonym for USER_TAB_COLUMNS."
This suggests a simple answer to your conundrum: you are connected to the database through a user which owns no tables (or views). Either change your user or try selecting from ALL_TAB_COLUMNS (which shows results from all the tables/views you have privileges on).

SQL/JDBC : select query on variable tablenames

I'm using Oracle DB and I would like to write a SQL query that I could then call with JDBC. I'm not very familiar with SQL so if someone can help me, that could be great ! Here is the problem. I have a table MY_TABLE wich contains a list of another tables, and I would like to keep only the nonempty tables and those that their names start by a particular string.
The query I wrote is the following :
select TABLE_NAME
from MY_TABLE
where TABLE_NAME like '%myString%'
and (select count(*) from TABLE_NAME where rownum=1)<>0
order by TABLE_NAME;`
The problem comes from the second SELECT, but I don't know how can I do to use the TABLE_NAME value.
Does someone have an idea ?
Thanks.
[Added from comments]
Actually, I need to test the V$ views contained in the ALL_CATALOG table. But if I can find another table where all these views are contained too and with a NUM_ROWS column too, it would be perfect !
Standard versions of SQL do not allow you to replace 'structural elements' of the query, such as table name or column name, with variable values or place-holders.
There are a few ways to approach this.
Generate a separate SQL statement for each table name listed in MY_TABLE, and execute each in turn. Brute force, but effective.
Interrogate the system catalog directly.
Investigate whether there are JDBC metadata operations that allow you to find out about the number of rows in a table without being tied to the system catalog of the specific DBMS you are using.
Can you use oracle view USER_TABLES? then query will be much easier
select TABLE_NAME
from USER_TABLES
where TABLE_NAME like '%myString%'
and Num_ROWS > 0
order by TABLE_NAME;`

How does one cheaply validate the existance of a column in a table in another schema with Oracle?

The environment is Oracle 9 & 10. I do not have DBA level access.
The problem is to verify that a specific column exists in a specific table, in another schema.
There are two cases to deal with.
Another schema in the same instance
A schema in a different instance, using a db_link
Given my schema FRED and another schema BARNEY, I tried something like this
SELECT 1
FROM BARNEY.USER_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE'
AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
Which yielded [1]: (Error): ORA-00942: table or view does not exist
After vegging on this awhile, I realized that USER_TAB_COLS, is not really a table. It is a view. I have been selecting from tables all along, but not from a view.
I tried the same thing with my db_link, and was surprised to see data come back. A db_link has an embedded schema_name/password in it, so it seems reasonable to me that it worked, as it effectively logs in to the other schema, which should make the views reachable.
Having Googled around, and worn out my eyeballs on on the mountain of Oracle doc,
I am looking for someone to point me in the correct direction, or at least point out what I am missing.
What techniques are available for getting user table related metadata from a schema in the same instance in order to validate that a specific column exists?
Thanks in advance.
Evil.
+1 for good answers.
Thank you.
You can use the following query:
SELECT 1
FROM ALL_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE'
AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
AND OWNER = 'BARNEY';
(User_Tables and User_Tab_Cols are just views on all_tables and all_tab_coumns with a where owner = <Current User> attached to it)
If you're allowed to see the Barney's some_table (i.e. you have been GRANTed at least SELECT privileges on it), then you'll know if the column is there. If you have no rights on the table, you won't be able to get meta information on it.
As with the other replies, normally I use ALL_TAB_COLUMNS for a query like this. But that will only show columns in tables where you have SELECT. And it's select on that column -- in the unlikely event that they've implemented column-level privileges for that table, you may be able to see the table, but not see the specific column of interest. For most of us, that's extremely rare.
DBA_TAB_COLUMNS will show all columns, but you'll need select on it granted to your schema by your DBA. (Actually, you'll need a grant on ALL_TAB_COLUMNS to use it, but that's common in most shops). The DBMS_METADATA PL/SQL Built-in package can also be used, with similar limitations, but I think you'll find it more complicated.
Of course, you can also just try to select a record from barney.some_table.some_column#my_dblink (or whatever pieces of that you're interested in). And then handle the exception. Ugly, I wouldn't recommend it in most situations.
You would use all_tab_columns for that.
But beware that you'll only see what you are allowed to see.
Same instance, different schema:
Select Count(*)
From all_tab_cols
Where owner = 'BARNEY' and
table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';
The count(*) has the advantage of always returning a single row with a value of either 1 or 0, so you do not have to deal with NO_DATA_FOUND errors in PL/SQL.
Across a DB Link, same schema as the one you connect as:
Select Count(*)
From user_tab_cols#MY_DB_LINK
Where table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';
Across a DB Link, different schema than the one you connect as:
Select Count(*)
From all_tab_cols#MY_DB_LINK
Where owner = 'BARNEY' and
table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';

What's the preferred way to return an empty table in SQL?

I know I can return an empty table using the following query :
select * from tbFoo where 1=2
but that code doesn't look nice to me.
Is there a 'standard' way of doing this?
If you're wondering why I want to do such a strange thing, it's because I can't name the datatables I return from a stored procedure, so I need empty placeholders.
Having just run both:
SELECT TOP 0 * FROM Table
and
SELECT * FROM Table WHERE 1=0
They produce exactly the same execution plan.
Most of the time I see 1=0 but yes thats pretty much the standard approach when you really have to. Although really having to is rare.
What you really need is information_schema, using it will allow you to find out the definition of a table.
You don't mention which database you are using, so here is a link about information_schema Support in MySQL, PostgreSQL (and MSSQL, Oracle, Etc)
An example from the site;
SELECT table_name, column_name, is_nullable, data_type, character_maximum_length
FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'employees'
In your case, all you need are the column names;
SELECT column_name
FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'employees'