How to extract ddl for oracle db links? - oracle

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

Related

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

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

How to export users in Oracle with its roles and system privileges using expdp?

I am trying to export a schema/user in Oracle with its roles and system privileges. I don't want to export any data or any table. I have tried to export users using the following command.
expdp system/system#gisdblocal include=user DIRECTORY = TestBack
logfile=test12.log DUMPFILE=test12.dmp SCHEMAS=test_replication
When I import this in other database or in the same database with a different name i.e
impdp system/system#gisdblocal DIRECTORY = TestBack DUMPFILE = test12.dmp
SCHEMAS = test_replication REMAP_SCHEMA =
test_replication:test_replication_copy
the user or schema is created but it has not been granted any role or system privileges.
I am doing this because I have created a backup of a schema using the user that did not have the required rights DATAPUMP_IMP_FULL_DATABASE or DATAPUMP_EXP_FULL_DATABASE. When I restore that backup in another database, it says the user does not exist. Therefore, I am thinking to create a user with the same privileges first and then restore the backup.
Using SQL...
SELECT dbms_metadata.get_ddl('USER', :name)
FROM dual
UNION ALL
SELECT dbms_metadata.get_granted_ddl('ROLE_GRANT', grantee)
FROM dba_role_privs
WHERE grantee = :name
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('DEFAULT_ROLE', grantee)
FROM dba_role_privs
WHERE grantee = :name
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('SYSTEM_GRANT', grantee)
FROM dba_sys_privs sp,
system_privilege_map spm
WHERE sp.grantee = :name
AND sp.privilege = spm.name
AND spm.property <> 1
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('OBJECT_GRANT', grantee)
FROM dba_tab_privs
WHERE grantee = :name
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('TABLESPACE_QUOTA', username)
FROM dba_ts_quotas
WHERE username = :name
AND ROWNUM = 1
:name being...a bind variable for the USER you want to re-create.

getting the currently logged on user and the number of valid stored procedure in sql

I would like to find out if its possible to get the number of valid and invalid stored procedures in SQL. Also the currently logged on user and the current time
To get the invalid objects use
SELECT *
FROM dba_objects
WHERE object_type IN ('PACKAGE'
, 'PACKAGE BODY'
, 'PROCEDURE'
, 'FUNCTION')
AND status <> 'VALID';
OR
SELECT STATUS, COUNT(*)
FROM dba_objects
WHERE object_type IN ('PACKAGE'
, 'PACKAGE BODY'
, 'PROCEDURE'
, 'FUNCTION')
GROUP BY status
for just a count of the statuses.
You might need to tweak the list of object types depending on what you want and you may want to limit it by OWNER as well.
The following shows the current time and a few methods of getting the user (schema, OS and the user from 'client identifier').
I suggest you try it and see which one you actually want and/or have populated.
SELECT TO_CHAR(SYSDATE, 'HH24:MI:SS') AS current_NLS
, TO_CHAR(SYS_EXTRACT_UTC(SYSTIMESTAMP),'HH24:MI:SS') AS UTC_TIME
, USER
, SYS_CONTEXT('USERENV', 'OS_USER')
, REGEXP_SUBSTR(SYS_CONTEXT('userenv', 'client_identifier'), '^[^:]*')
FROM DUAL;

DBMS_APPLICATION_INFO.SET_CLIENT_INFO not working

I need to set the client_info value to differentiate between different clients.
These are the scripts that I am running to test.
Step 1:SYS SCHEMA
ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
Step 2:HR SCHEMA
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO(UTL_INADDR.GET_HOST_NAME );
EXEC DBMS_APPLICATION_INFO.SET_MODULE( 'CHECK','select' );
select
a.FIRST_NAME || ' ' || LAST_NAME AS FULL_NAME
from
HR.EMPLOYEES a
where
a.DEPARTMENT_ID = '40'
;
Step 3:SYS SCHEMA
select
*
from
(
select
a.SQL_ID
,a.SQL_FULLTEXT
,to_char( a.LAST_ACTIVE_TIME,'DD-MON-YYYY HH24:MI:SS' ) as LAST_ACTIVE_TIME
,a.SERVICE
,b.SCHEMANAME
,b.CLIENT_INFO
,a.MODULE
,a.ACTION
from
GV$SQL a
left outer join GV$SESSION b
on
(
b.SQL_ID = a.SQL_ID
)
where
a.EXECUTIONS != 0
)
c
where
c.MODULE like '%CHECK%'
order by
c.LAST_ACTIVE_TIME desc ;
The MODULE and ACTION columns are getting the values but the CLIENT_INFO is not showing anything.
Is there anything I am missing?
Update:
I have also tried with no luck
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO( SYS_CONTEXT('userenv','ip_address') );
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO( '10.10.10.10' );
SET_CLIENT_INFO is related to a Session, not to a single SQL Statement.
DO THIS
Step 1:SYS SCHEMA
ALTER SYSTEM FLUSH SHARED_POOL;
ALTER SYSTEM FLUSH BUFFER_CACHE;
Step 2:HR SCHEMA
EXEC DBMS_APPLICATION_INFO.SET_CLIENT_INFO(UTL_INADDR.GET_HOST_NAME );
EXEC DBMS_APPLICATION_INFO.SET_MODULE( 'CHECK','select' );
Step 3:SYS SCHEMA
SELECT
a.SQL_ID
,a.CLIENT_INFO
,a.MODULE
,a.ACTION
,a.SCHEMANAME
,a.USERNAME
FROM
V$SESSION a
WHERE
a.MODULE = 'CHECK';

SQL Server 2005 Express - generate script to create VIEW based on relational tables?

Is there a way in SQL Server 2005 Express to generate a script that would create a VIEW based on tables primary/foreign key relationships?
I have multiple databases with thousands of tables, and its very time consuming to look at the "table dependencies" and try to JOIN data in the query window.
Thanks
This Query return Create statement for tables, but you must first note that:
1. only works for 1 column foreign key references
2. has not been tested for sql server express 2005, but works fine for Sql server 2005
create function dbo.func59C217D64BC54EA0B841BF1AB43D9398(#table1 nvarchar(1000), #table2 nvarchar(1000))
returns nvarchar(max)
as
begin
declare #sql nvarchar(max)
set #sql = ''
select #sql = #sql + dr + '.[' +cc +'] AS ['+ cc+ ISNULL(rr,'') + '],'
from (
select column_name cc,
dr = case when table_schema + '.' +table_name = #table1 then 'a' else 'b' end,
cast(NULLIF(row_number() over (partition by column_name order by table_name),1) as nvarchar) rr
from INFORMATION_SCHEMA.COLUMNS where table_schema + '.' +table_name in
(#table1,#table2)
) i
return substring(#sql,1,len(#sql) - 1)
end
GO
select cast(
'CREATE VIEW ['+r.CONSTRAINT_SCHEMA+'].[vw' +cp.TABLE_NAME+cf.TABLE_NAME+ ']
AS SELECT '+dbo.func59C217D64BC54EA0B841BF1AB43D9398(cp.TABLE_SCHEMA+'.' +cp.TABLE_NAME,cf.TABLE_SCHEMA+ '.' +cf.TABLE_NAME)+' FROM ['+cp.TABLE_SCHEMA+'].['+cp.TABLE_NAME+'] AS a
JOIN ['+cf.TABLE_SCHEMA+'].['+cf.TABLE_NAME +'] AS b
ON a.['+cp.COLUMN_NAME+'] = b.['+cf.COLUMN_NAME +']' as ntext) as sql
from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS r
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cf ON r.CONSTRAINT_NAME = cf.CONSTRAINT_NAME
JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cp ON r.UNIQUE_CONSTRAINT_NAME = cP.CONSTRAINT_NAME
GO
DROP function dbo.func59C217D64BC54EA0B841BF1AB43D9398
hope I helped, or at least make you started

Resources