Oracle sql to print value if it exists else print 'value' does not exist - oracle

I am looking for help towards - How to write a select statement (Oracle) to print a column from a table checking against specific value? For value that do not exist it should print a record saying 'value' does not exist.
E.g.
select username from dba_users where username in ('a','b','c').
Expected output -
username
========
a
b does not exist
c

If you're on a recent version of Oracle you could use outer apply, with a collection to hold the values you're looking for:
select coalesce (u.username, t.column_value || ' does not exist') as username
from table(sys.odcivarchar2list('SYS', 'XYZ', 'OUTLN')) t
outer apply (select username from all_users u where u.username = t.column_value) u;
USERNAME
------------------------------
SYS
XYZ does not exist
OUTLN
or just an outer join, which would work on earlier versions too:
select coalesce (u.username, t.column_value || ' does not exist') as username
from table(sys.odcivarchar2list('SYS', 'XYZ', 'OUTLN')) t
left join all_users u on u.username = t.column_value;
USERNAME
------------------------------
SYS
XYZ does not exist
OUTLN
db<>fiddle

Related

Fetch sql query with Machine Name

I want to fetch sql query with machine name where sql query has been run and machine name can belong's to any user. Please guide how is it possible to get that by joing tables like DBA_hist_sql or any other table.
I can suggest such variant
select
s.sql_id,
s.sql_text,
d.machine
from
v$sql s,
dba_hist_active_sess_history d
where
d.sql_id = s.sql_id
Maybe there is better variant or more related to your question. I hope it wil be helpful for you.
I let you links on documentation of these views.
DBA_HIST_ACTIVE_SESS_HISTORY
V$SQL
You can join DBA_HIST_ACTIVE_SESS_HISTORY and DBA_HIST_SQLTEXT , as long as the sql has been captured in the workload repository.
In the DBA_HIST_ACTIVE_SESS_HISTORY you have the field MACHINE, where you got the value of SYS_CONTEXT('userenv','host') .
You can join both views by sql_id.
However, the query will not be registered on the workload repository if it's not meaningful. You can modify this behaviour by changing settings of AWR using DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS
An example
select
distinct s.sql_id,
s.sql_text,
d.machine ,
u.username ,
d.program
from
gv$sql s inner join dba_hist_active_sess_history d
on ( d.sql_id = s.sql_id and S.INST_ID = D.INSTANCE_NUMBER )
inner join dba_users u on ( D.USER_ID = U.USER_ID )
where
u.username = '&1'
S.SQL_ID = '&2'
order by D.SAMPLE_TIME desc
You can apply the filter by username or sql_id, or both. keep in mind that the field USERNAME will show you the Oracle user who executed the query, not the operating system user behind that connection.

Oracle Invalid Identifier (with Inner Join)

I'm having an "Invalid Identifier" in Oracle because of the "B.username" (username column does exist in USER table). When i remove this, it's working fine. How to resolve this issue? I came from a MySQL background.
SELECT * FROM (SELECT qNA.assignment, qNA.regDate, B.username, (
SELECT DISTINCT NVL(idx, 0)
FROM EK_USERGRADE
WHERE year = (SELECT DISTINCT userGradeNo FROM EK_USER WHERE ID = qNA.userIdx)
) AS userGradeIdx
FROM EK_NEWTESTAPPLICANT qNA
WHERE IDX = :idx ) A
INNER JOIN EK_USER B ON (A.userIdx = B.ID)
Let's try this with a simplified version of your query:
-- test tables
create table NEWTESTAPPLICANT as select 1 useridx from dual ;
create table B as select 1 id, 'name1' username from dual ;
-- query
select *
from (
select B.username
from NEWTESTAPPLICANT qNA
) A join B on A.useridx = B.id ;
-- ORA-00904: "B"."USERNAME": invalid identifier
There's no "username" column in the NEWTESTAPPLICANT table, which causes the error. A LATERAL inline view (examples see here) may do the trick ...
-- query
select
*
from B, lateral (
select B.username
from NEWTESTAPPLICANT qNA
) A ;
-- result
ID USERNAME USERNAME
1 name1 name1
This works with Oracle 12c.
The problem is, that both your virtual table A and users B have the same column name "username". Specify alias in the main select, like "Select A.* , B.* from(...".
Is it ORA-00903?
User is a reserved word are you sure you created this table? Table name cannot be a reserved word.

How to extract ddl for oracle db links?

Is there anyway to extract ddl for all database links?
I would like to get in sql and recreate them via sql.
I can use below and it works for PUBLIC user but for non public user it doesn't give me db link owner.
Set long 1000
SELECT DBMS_METADATA.GET_DDL('DB_LINK',db.db_link,db.owner) from dba_db_links db;
Sample link owner and name
Owner db_link
public link1
public link2
user1 link3
If I ran above select it will give me below, #3 doesn't have username in it.
Output from above SELECT
1. create public database link "link1" using "db_alias"
2. create public database link "link2" using "db_alias"
3. create database link "link3" using "db_alias"
I recreate links using SYS and don't want to create #3 as SYS user.
Seems that even as SYS user you can't easity create dblink for another user (except of public dblink).
Even if you run create database link your_user.link3 using "db_alias" it's owner will be SYS.
Possible hacks are connect as another user (you may add conn into SQL*Plus script if you have credentials)
Or create procedure for user that need to have dblink that run create database link command with parameters and call it from sys.
this should help with links that do a "connect to"
SELECT MYCOMMAND
FROM
(
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username) ||'__'||trim(l.host) , '10'
, ' connect '||trim(l.owner)||'/CCCCCCCC#'||TRIM(INSTANCE_NAME)
AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
UNION ALL
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username)||'__'||trim(l.host) , '20'
, ' DROP DATABASE LINK '||trim(l.db_link)||' ; ' AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
UNION ALL
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username)||'__'||trim(l.host) , '30'
, ' CREATE DATABASE LINK '||trim(l.db_link)
||' CONNECT TO "'||trim(l.username)||'"'
||' IDENTIFIED BY "NNNNNNNN" '
||' USING '||trim(l.host) ||' ; 'AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
ORDER BY 1,2,3
)
To get ddl from db links, run the output of the command below:
set pages 999;
set long 90000;
SELECT 'SELECT dbms_metadata.get_ddl(''DB_LINK'',''' || db_link || ''',''' || owner || ''') FROM dual;'
FROM dba_db_links
WHERE db_link
IN ('DB_LINK1',
'DB_LINK2',
'DB_LINK3');
For create a db link for other user, with user SYS execute the DDL below:
CREATE DATABASE LINK "OWNER.DBLINK_NAME"
CONNECT TO "USER" IDENTIFIED BY "Password_user"
USING 'ALIAS';

Why can't hive recognize alias named in select part?

Here's the scenario: When I invoke hql as follows, it tells me that it cannot find alias for u1.
hive> select user as u1, url as u2 from rank_test where u1 != "";
FAILED: SemanticException [Error 10004]: Line 1:50 Invalid table alias or column reference 'u1': (possible column names are: user, url)
This problem is the same as when I try to use count(*) as cnt. Could anyone give me some hint on how to use alias in where clause? Thanks a lot!
hive> select user, count(*) as cnt from rank_test where cnt >= 2 group by user;
FAILED: ParseException line 1:58 missing EOF at 'where' near 'user'
The where clause is evaluated before the select clause, which is why you can't refer to select aliases in your where clause.
You can however refer to aliases from a derived table.
select * from (
select user as u1, url as u2 from rank_test
) t1 where u1 <> "";
select * from (
select user, count(*) as cnt from rank_test group by user
) t1 where cnt >= 2;
Side note: a more efficient way to write the last query would be
select user, count(*) as cnt from rank_test group by user
having count(*) >= 2
If I remember correctly, you can refer to the alias in having i.e. having cnt >= 2
I was able to use Alias in my Hive select statement using backtick symbol ``.
SELECT COL_01 AS `Column_A`;
The above solution worked for Hive version 1.2.1.
reference link

Query Oracle for running sql and value of bind variables

If I run the SQL in Fig. 1 below, it may return something like this:
Select fname, lname from name_tbl where nam_key = :key
Without using some fancy DBA trace utility, how can I query an Oracle system table to find the value of the bind variable “:key”?
Figure 1. - List the current running sql statement.
select sid, username, sql_text
from v$session,
v$sqltext
where sql_address = address
and sql_hash_value = hash_value
order by sid, piece;
select name, value_string
from v$sql_bind_capture
where sql_id = your_query_id
Upd. or, of course:
select sql_id, value_string
from v$sql_bind_capture
where name = ':key'

Resources