Fetch sql query with Machine Name - oracle

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.

Related

Optimize multiple subselects with WITH clause in Oracle

I have a query like:
select
qsn.code,
(select prs.display_name from prs where prs.id = qsn.fk_prs) display_name,
(select prs.address from prs where prs.id = qsn.fk_prs) address,
(select prs.tel from prs where prs.id = qsn.fk_prs) tel
from
qsn
where
qsn.register_date between :x1 and :x2
When I look at the execution plan of the query, it queries prs table 3 times (each time using INDEX UNIQUE SCAN).
I wonder if I can query the prs table once using WITH clause? How can I write the query that way.
I shall mention that because each of the tables have millions of record, joining them makes the query so slow.
using with clause your query goes like this:
with abc as (select id,
display_name ,
address ,
tel
from prs)
select
qsn.code,
abc.display_name,
abc.address,
abc.tel
from qsn
inner join abc
on qsn.fk_prs = abc.id
where qsn.register_date between :x1 and :x2 ;
ps: not tested.
Use a join:
select qsn.code, prs.display_name, prs.address, prs.tel
from qsn
left join prs on prs.id = qsn.fk_prs
where qsn.register_date between :x1 and :x2

How to get machine name/ip address of a SQL query from which that was run using sql id in ORACLE

I have the sql id of a query. Now I want to get the machine name and IP of the machine from which this query was run.
I have already checked the sql id in V$SESSION and V$ACTIVE_SESSION_HISTORY but didn't get any results.
I am able to find the sql id in v$sql and LAST_LOAD_TIME is today(7 July 2016).
select LAST_LOAD_TIME from v$sql where SQL_ID='0jf4618m2u7aw' order by LAST_LOAD_TIME desc;
2016-07-04/17:26:02
2016-07-04/17:26:02
select * from V$SESSION where SQL_ID='0jf4618m2u7aw';
no rows selected
select * from V$ACTIVE_SESSION_HISTORY where SQL_ID='0jf4618m2u7aw';
no rows selected
Please help. Thanks in advance.
You have a couple of options...
If it is an active session/process, you can use v$session and v$process:
SELECT DISTINCT
MACHINE,
UTL_INADDR.GET_HOST_ADDRESS(MACHINE) AS IP_ADDR
FROM V$SESSION S,
V$PROCESS P
WHERE S.PADDR = P.ADDR
AND S.SQL_ID = '0jf4618m2u7aw';
If you want a historical view, the DBA_HIST_ACTIVE_SESS_HISTORY might be your friend:
SELECT DISTINCT
MACHINE,
UTL_INADDR.GET_HOST_ADDRESS(MACHINE) AS IP_ADDR
FROM DBA_HIST_ACTIVE_SESS_HISTORY DHASH
WHERE DHASH.SQL_ID = '0jf4618m2u7aw'
AND DHASH.SQL_EXEC_START > TRUNC(SYSDATE);

cascading Input Control sql query return error: "ORA-01427: single-row subquery returns more than one row"

looking for solution on my sql query error.I'm trying to create second cascading Input Control in JaspersoftServer. The first Input Control works fine, however when I try to create a second cascade IC it returns with the error. I have 3 tables (user, client, user_client), many to many, so 1 linked table (user_client) between them.The 1st Input Control (client) - works well, end user will select the client, the client can have many users, so cascade is the key. Also, as the output, I would like to get not the user_id, but user's firstname and the lastname as one column field. And here is where i'm stuck. I'm pretty sure it is simple syntaxis error, but spent a good couple of hours to figure out what is wrong with it. Is anyone can have a look at it please and indicate where is the problem in my query ?! So far I've done:
select distinct
u.user_id,(
SELECT CONCAT(first_name, surname) AS user_name from tbl_user ),
c.client_id
FROM tbl_user u
left join tbl_user_client uc
on uc.user_id = u.user_id
left join tbl_client c
on c.client_id = uc.client_id
where c.client_id = uc.client_id
order by c.client_id
Thank you in advance.
P.S. JasperServer + Oracle 11g
You're doing an uncorrelated subquery to get the first/last name from the user table. There is no relationship between that subquery:
SELECT CONCAT(first_name, surname) AS user_name from tbl_user
... and the user ID in the main query, so the subquery will attempt to return every first/last name for all users, for every row your joins find.
You don't need to do a subquery at all as you already have the tbl_user information available:
select u.user_id,
CONCAT(u.first_name, u.surname) AS user_name
c.client_id
FROM tbl_user u
left join tbl_user_client uc
on uc.user_id = u.user_id
left join tbl_client c
on c.client_id = uc.client_id
where c.client_id = uc.client_id
order by c.client_id
If you want to put a space between the first and last name you'll either need nested concat() calls, since that function only takes two arguments:
select u.user_id,
CONCAT(u.first_name, CONCAT(' ', u.surname)) AS user_name
...
... or perhaps more readably use the concatenation operator instead:
select u.user_id,
u.first_name ||' '|| u.surname AS user_name
...
If the first control has selected a client and this query is supposed to find the users related to that client, you're joining the tables the wrong way round, aren't you? And you aren't filtering on the selected client - but no idea how that's actually implemented in Jasper. Maybe you do want the entire list and will filter it on the Jasper side.

DBA_HIST_ACTIVE_SESS_HISTORY get sql by user and object schema

Hi I am learning ASH and AWR tables but any ideas as to how i can get list of sql, objects and schema owner accessed by a give user in last 30 days ? Basically get all SQL text, and then search within this SQL to see if a given object (table, package, function, view etc ) is accessed for a given schema and by which user ? Any ideas suggestion on where and how to start ?
You could join the following views -
DBA_HIST_ACTIVE_SESS_HISTORY
DBA_USERS
DBA_HIST_SQLTEXT
To filter the history for last 30 days, use sample_time of DBA_HIST_ACTIVE_SESS_HISTORY view.
Something like -
SELECT
h.sample_time,
u.username,
h.program,
h.module,
s.sql_text
FROM
DBA_HIST_ACTIVE_SESS_HISTORY h,
DBA_USERS u,
DBA_HIST_SQLTEXT s
WHERE sample_time >= SYSDATE - 30
AND h.user_id=u.user_id
AND h.sql_id = s.sql_iD
ORDER BY h.sample_time
/
The very best and simplest way to fetch related data using below query.
SELECT H.SAMPLE_TIME,
U.USERNAME,
H.PROGRAM,
H.MODULE,
S.SQL_TEXT,
H.SQL_ID,
H.TOP_LEVEL_SQL_ID,
H.BLOCKING_SESSION_STATUS
FROM DBA_HIST_ACTIVE_SESS_HISTORY H, DBA_USERS U, DBA_HIST_SQLTEXT S
WHERE H.SAMPLE_TIME >= SYSDATE - 30
AND H.SQL_ID = S.SQL_ID
--AND H.PROGRAM IN ('Toad.exe', 'SQL Developer')
--AND U.USERNAME ='YOUR_USERNAME'
ORDER BY H.SAMPLE_TIME DESC
In the above code you can also fetch data based on your requirements as below.
1. Custom user data: Just modify YOUR_USERNAME with your real username.
2. Program: Program name can be anything like SQL Developer or JDBC Thin client to identify from which client the queries are getting triggered, but optional.
Hope it will help and answer to your question. Thanks :)

Query to find all views/charts owned or shared with a user in Dynamics 2013

Is there a way to see all views / charts owned or shared with a user in Dynamics 2013? (DB query would be fine. I can access the base tables if needed.
#Ryan 's solution helped me quite a bit but was painful to transcribe. This is the solution in a more usable format (with minor edits):
DECLARE #userid varchar(100)
SELECT #userid = 'domain\user'
-- Get team membership for the user
IF OBJECT_ID(N'tempdb.dbo.#UserAndTeams') IS NOT NULL DROP TABLE #UserAndTeams
SELECT DISTINCT t.TeamId TeamOrUserId, t.[Name]
INTO #UserAndTeams
FROM
TeamBase t
INNER JOIN TeamMembership tm ON t.TeamId = tm.TeamId
INNER JOIN SystemUserBase su ON su.SystemUserId = tm.SystemUserId
WHERE
su.DomainName = #userid
INSERT INTO #UserAndTeams(TeamOrUserId, [Name])
SELECT su.SystemUserId, su.Firstname + ' ' + su.Lastname [Name]
FROM SystemUserBase su WHERE su.DomainName = #userid
-- Get a union of all teams and this user
IF OBJECT_ID(N'tempdb.dbo.#AllUsersAndTeams') IS NOT NULL DROP TABLE #AllUsersAndTeams
SELECT t.TeamId TeamOrUserId, t.[Name]
INTO #AllUsersAndTeams
FROM TeamBase t
INSERT INTO #AllUsersAndTeams(TeamOrUserId, [Name])
SELECT su.SystemUserId, su.Firstname + ' ' + su.Lastname [Name]
FROM SystemUserBase su
-- Extract share info from POA for selected entity types
SELECT DISTINCT su.[Name] SharedWith, objectIds.[Type], objectIds.[Name] Objectname, aut.[Name] Ownername
FROM
PrincipalobjectAccess poa WITH (NOLOCK)
INNER JOIN #UserAndTeams su WITH (NOLOCK) ON poa.PrincipalId = su.TeamOrUserId
INNER JOIN
(
SELECT 'Chart' [Type], UserQueryVisualizationId id, [Name], OwnerId FROM UserQueryVisualizationBase WITH (NOLOCK)
UNION SELECT 'View', UserQueryId id, [Name], OwnerId FROM UserQueryBase WITH (NOLOCK)
UNION SELECT 'Report', ReportId, [Name], OwnerId FROM Report WITH (NOLOCK)
UNION SELECT 'Dashboard', uf.userFormId id, [Name], OwnerId FROM UserForm uf WITH (NOLOCK) WHERE uf.[Type] = 0
) objectIds ON poa.ObjectId = objectIds.id
INNER JOIN #AllUsersAndTeams aut ON objectIds.OwnerId = aut.TeamOrUserId
ORDER BY
objectIds.[Type], objectIds.[Name]
I came up with this procedure:
Which works well for views/dashboards and charts. If a user can access an item via team membership the team name is displayed; if it's been shared directly with the user, the users' name is displayed.
It needs to be run for a user with access to the base tables.
(I can't post the full SQL to Stack Overflow! It's containted in the attached image.)
This is actually trickier then you might think - The information about shared views is contained within the principalobjectaccess table in database.
This table contains the object that's being shared, who it's being shared with, and what permissions they have on that object.
The hard part is that the guid that contains the object being shared does not also specify what object type is being shared as well. It might be possible to create a query that joins the POA table to the views created, and then put in a where clause for that particular user... but be careful and don't run this against a production system (and if you have to make sure to use a (nolock) on the POA table.)
Sorry I couldn't be more help, but I'm not using On-prem and cant test a query.

Resources