Select a column that potentially doesn't exist in Oracle dictionary views - sql

I want to create a backwards compatible query on SYS.ALL_ARGUMENTS. In Oracle 11g, the useful ALL_ARGUMENTS.DEFAULTED column was added. Now if I run this query against Oracle 10g:
SELECT defaulted FROM all_arguments
I get an error, of course.
ORA-00904: "SYS"."ALL_ARGUMENTS"."DEFAULTED": invalid identifier
What I'd like to do is this:
SELECT CASE WHEN column_exists("defaulted")
THEN defaulted
ELSE 'N'
END
FROM all_arguments
Or even better
SELECT evaluate_column_on_current_row(column_name => "defaulted",
default_if_not_exists => 'N')
FROM all_arguments
Is there some way to do that in a single SQL query, without resorting to PL/SQL? Or should I check the Oracle version first like this:
SELECT count(*)
FROM all_tab_cols
WHERE owner = 'SYS'
AND table_name = 'ALL_ARGUMENTS'
AND column_name = 'DEFAULTED'

A query that references a column that doesn't exist can't generate a valid plan.
You need to choose an approach where the queries submitted are always valid. Be that dynamically generating/executing them, or some other approach.
But if you submit a query to be parsed, and it contains a non existant field on an existant table, the parser will throw it back at you.

Related

SQL - conditionally select a column if exists

I need to select a column only if it exists in table, else it can be set to null.
Sample table below, lets say the marks col is not necessary be there, so need to be checked if it exists
Table1:
name marks
joe 10
john 11
mary 13
Query:
select
name,
marks if it exists else null as marks1 -- pseudo code
from
table1
What should go in line to select marks ?
SQL Doesn't permit that. Your result set has two options:
Static inclusion
All from table or subquery through column-expansion with * and tbl.*
Perhaps this will suit your needs, SELECT * FROM table1; You'll always get that column, if it exists.
try this
IF COL_LENGTH('your_table_name','column_name_you_want_to_select') IS NULL BEGIN
--This means columns does not exist or permission is denied
END
else
--Do whatever you want
It is possible to achieve this in PostgreSQL using JSON. Consider the following SQL query:
SELECT c.relname, c.relkind, c.relispartition
FROM pg_class c
WHERE c.relkind IN ('r','p') AND
c.relnamespace=(SELECT oid FROM pg_namespace WHERE nspname='public')
In PostgreSQL 10+, that will show you the names of all the tables in public schema, including whether they are partitioned and if so whether the table is the partitioned table or one of the partitions of it. However, if you try to run the same query on PostgreSQL 9.6 or earlier, it will fail since the relispartition column does not exist on the pg_class table prior to PostgreSQL 10.
An obvious solution would be to dynamically generate the SQL based on a condition, or have two different versions of the SQL. However, suppose you don't want to do that, you want to have a single query which works on both versions – in other words, you want to conditionally select the relispartition column if it exists.
The core SQL language does not have any facility to conditionally select a column, but it is achievable in PostgreSQL using the row_to_json function, as follows:
SELECT c.relname, c.relkind,
(row_to_json(c)->>'relispartition')::boolean AS relispartition
FROM pg_class c
WHERE c.relkind IN ('r','p') AND
c.relnamespace=(SELECT oid FROM pg_namespace WHERE nspname='public')
If you try running that, you will find on PostgreSQL 10+ the relispartition column is returned as true/false, whereas in pre-10 versions it is NULL. You could make it return false instead of NULL in pre-10 versions by doing COALESCE((row_to_json(c)->>'relispartition')::boolean,false).
What this is doing, is row_to_json(c) turns all the data of the row into JSON. Next, ->>'relispartition' selects the value of the relispartition JSON object key as text, which will be the same as the value of the relispartition column; if there is no such key in the JSON, the result of that will be NULL. Then, ::boolean converts the string value true/false back into a PostgreSQL boolean value. (If your column is of some other type, use the appropriate cast for the type of your column.)
(Obviously this approach will not work in Postgres versions which are too old to have the necessary JSON support – I have tested it works in Postgres 9.4; while I haven't tested it in Postgres 9.3, it probably works there. However, I would not expect it to work in 9.2 or earlier – the ->> operator was added in 9.3, and the JSON type and row_to_json function was added in 9.2. However, I expect few people will need to support those old unsupported versions–9.3 was released in 2013, and 9.2 supported ended in 2017.)
Try this:
IF EXISTS( SELECT 1
FROM information_schema.columns
WHERE table_name='your_table' and column_name='your_column') THEN
SELECT your_column as 'some_column'
ELSE
SELECT NULL as 'some_column'
END IF
Replying to an old question yet again but here's my hacky solution to this problem since I don't know how to write SQL functions... yet! %I formats the string as an identifier, and if there is no such table the return value is NULL and the alias is used!
SELECT (SELECT format('%I', 'my_column')
AS my_column_alias
FROM information_schema.columns
WHERE table_name='my_table'
AND column_name='my_column')
FROM source_table
Hope this helps everybody out there =)

Mysql Query data filled check

I had created the table with 200 columns and i had inserted data
Now i need to check that specific 100 columns in one row are filled or not,how can we check this using mysql query .the primary key is defined .please help me out how to resolve this.
select * from tablename where column1 != null or column2 != null ......
That is a lot of columns so at the risk of being mysql server version specific you can use the information schema to get the column names and then write a SQL procedure or something in your chosen shell / language that iterates over them performing a test.
select distinct COLUMN_NAME as 'Field', IS_NULLABLE from information_schema.columns where TABLE_SCHEMA="YourDatabase" and TABLE_NAME="YourTableName" and TABLE_NAME not like "%view%" escape '!' ;
The example above will tell you the column name as "Field" and tell you if it can hold a NULL. Having the field name may give you a better way of automating a field name specific test.

Oracle SQL: selecting from all_tab_columns does not find existing column

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.

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;`