How to update value of fields in a table found in every schema on an Oracle Server - oracle

I need to update the value of two fields in a table and in every schema containing that table on an Oracle Server (11g). I am from the SQL Server world, but recognize that the architecture is different with multiple schemas under a single instance, not multiple databases under a single instance. The reason for this update is to ensure that while database development and testing takes place on copies of client databases, the clients do not accidentally receive emails (according to settings defined in certain columns of a table in each schema/database).
I am using SQL Developer, but could also apply SQLplus instead. Assuming the Server name is "myServer", the tablename is "myTable" and the fields are "Field1" and "Field2" of this table, can somebody help in providing some SQL that will perform a global update of all schemas on myServer setting Field1 = 'N' and Field2 = NULL in myTable? Or direct me to a link that does answer this question? I first ran multiple searches and found nothing.
Thanks

You can use dynamic SQL
FOR tbl IN (SELECT owner, table_name
FROM dba_tables
WHERE table_name = 'MYTABLE')
LOOP
EXECUTE IMMEDIATE 'update ' || tbl.owner || '.' || tbl.table_name ||
' set field1 = ''N'', ' ||
' field2 = null ';
END LOOP;
You can add some additional logging and you probably want to build the SQL statement in a local variable so that you can log it if something goes wrong. This also assumes that you're running as a user that has access to dba_tables. You could use all_tables if you want to update every table with that name that you have access to (which might not cover every table in the database).

Related

Extract table names from oracle database server

I have access to an oracle11g server that blongs to a store and have a software to get reports inside softare but the software is closed source.
bacause i have a username inside database i can access from the software to all reports but i want to automate some works and want to write a python3 script to do that.all i need is that know the table names in DB. i want a code in oracle that returns me the table name.
I have access to database from "PLSQL Developer" and from my notcompleted code in python.
import cx_Oracle
con = cx_Oracle.connect('username/password#serveraddress/dbname')
print (con.version)
cur =con.cursor()
cur.execute(" SOME ORACLE CODE")
#cur.execute('select * from tablesname orderby id' )
for i in cur:
print (i)
con.close()
so what is a code that can execute and return table names to me?
p.s : i even used wireshark to find out what was the code that program sent to server but table names was not there in packet. :(
p.s 2 : any creative and unusual answer is welcome.
You can use
select table_name
from user_tables
order by table_name
or
select table_name
from cat
where table_type = 'TABLE'
order by table_name
to derive the names of all tables in your current user. Where cat is synonym of user_catalog data dictionary view and user_tables is another data dictionary view automatically created by database during installation.

I am facing an issue with deletion operation in Stored procedures(packages)

I am facing an issue here. I have a table Products where there are columns called prod_trkg_tran_id and cntr_nbr etc. I also have two tables instance1 and instance2 which also contains prod_trkg_tran_id and cntr_nbr and they have one row of data each with same cntr_nbr. I ran a query like below in Oracle SQLDeveloper. It worked fine and deleted a row from prod_trkg_tran. Can you explain this??
But when i tried this in SP by assigning:
p_where_clause:= 'WHERE t.prod_trkg_tran_id in (
select distinct tp82.PROD_TRKG_TAN_ID
from instance_1 tp21
join instance_2 tp82 on tp21.cntr_nbr=tp82.cntr_nbr
)'
and called a method delete_table which a statement contains
'DELETE FROM ' || p_table_name ||' t ' || p_where_clause;
p_table_name is prod_trkg_tran and p_where_clause is the one which I defined earlier.
If I run this, SP records are not getting deleted from prod_trkg_tran.
Ideally it was supposed to delete like I tried in SQLDeveloper. Can you explain this?
delete from prod_trkg_tran t
WHERE t.prod_trkg_tran_id in (
select distinct tp82.PROD_TRKG_TRAN_ID
from instance_1 tp21
join instance_2 tp82 on tp21.cntr_nbr=tp82.cntr_nbr
);
It is most probably a grant issue where executing schema/user does not have grant for delete or select aforamentioned tables.
If your user have DBA privileges you do not encounter with this error while using SQL Developer, however Stored Procedure does.
In your case, your tables may be synonyms to another schema table and you may not have grants on these tables.
Please make sure that you have sufficient grants.
By the way, what is the error that you are facing?

sqldeveloper query other users

I have a database that has say 100 other_users.
I am logged in as the database owner and I want to query a specific table in all the other users schemas.
So let's say each schema has a table called propertyvalue.
I want to find out which schemas have this value set to TRUE.
Is there a way I can run a select statement against all the other users schemas without specifically pointing to an individual schema.
Something like:
select * from otherusers.propertyvalue where value = 'TRUE', which doesn't work as I have tried that.
Thanks.
You can write a statement that will write select statements to do this
SELECT 'SELECT '||owner||'.'||table_name||'.'||column_name ||
' FROM '||owner||'.'||table_name||';'
FROM All_Tab_Cols atc
WHERE atc.column_name = 'PROPERTYVALUE';
Run this statement as a user with select privilege on the table and then run the selects that are the output.
However tables with multiple rows will return all rows. Are you expecting that there is only one row in each table?
You could also write an anonymous block that will open a cursor with the same statement and output the results to a file/table/output.

How to retrieve parsed dynamic pl Sql

I have many PL/SQL functions and procedures that execute dynamic sql.
Is it possible to extract the parsed statements and dbms_output as an debugging aid ?
What I really want is to see the parsed sql (sql statement with substituted parameters).
Example:
I have a dynamic SQL statement like this
SQ:='SELECT :pComno as COMNO,null t$CPLS,t$CUNO,t$cpgs,t$stdt,t$tdat,t$qanp,t$disc,:cS Source FROM BAAN.TTDSLS031'||PCOMNO --1
|| ' WHERE' ||' TRIM(T$CUNO)=trim(:CUNO)' --2
|| ' AND TRIM(T$CPGS)=trim(:CPGS)' --3
|| ' AND T$QANP = priceWorx.fnDefaultQanp ' --4
|| ' AND priceWorx.fdG2J(sysdate) between priceWorx.fdG2J(t$stdt) and priceWorx.fdG2J(t$tdat)' --5
|| ' AND rownum=1 order by t$stdt';--6
execute immediate SQ into R using
PCOMNO,'C' --1
,PCUNO-- 2
,PCPGS;-- 3
What will be the statement sent to the server ?
You can display the bind variables associated with a SQL statement like this:
select v$sql.sql_text
,v$sql_bind_capture.*
from v$sql_bind_capture
inner join v$sql on
v$sql_bind_capture.hash_value = v$sql.hash_value
and v$sql_bind_capture.child_address = v$sql.child_address
--Some unique string from your query
where lower(sql_text) like lower('%priceWorx.fdG2J(sysdate)%');
You probably would like to see the entire query, with all the bind variables replaced by their actual values. Unfortunately, there's no easy way to get exactly what you're looking for, because of the following
issues.
V$SQL_BIND_CAPTURE doesn't store all of the bind variable information. The biggest limitation is that it only displays data "when the bind variable is used in the WHERE or HAVING clauses of the SQL statement."
Matching the bind variable names from the bind capture data to the query is incredibly difficult. It's easy to get it working 99% of the time, but that last 1% requires a SQL and PL/SQL parser, which is basically impossible.
SQL will age out of the pool. For example, if you gather stats on one of the relevant tables, it may invalidate all queries that use that table. You can't always trust V$SQL to have your query.
Which means you're probably stuck doing it the ugly way. You need to manually store the SQL and the bind variable data, similar to what user1138658 is doing.
You can do this with the dbms_output package. You can enable and disable the debug, and get the lines with get_line procedure.
I tested with execute immediate, inserting in a table and it works.
I recently answered another question with a example of using this.
One possible solution of this is to create a table temp(id varchar2,data clob); in your schema and then put the insert statement wherever you want to find the parsed key
insert into temp values(seq.nextval,v_text);
For example
declare
v_text varchar2(2000);
begin
v_text:='select * from emp'; -- your dynamic statement
insert into temp values(seq.nextval,v_text); --insert this script whenever you want to find the actual query
OPEN C_CUR FOR v_text;
-----
end;
Now if you see the table temp, you'll get the data for that dynamic statement.

Oracle sample data problems

So, I have this java based data trasformation / masking tool, which I wanted to test out on Oracle 10g. The good part with Oracle 10g is that you get a load of sample schemas with half a million records in some. The schemas are : SH, OE, HR, IX and etc. So, I installed 10g, found out that the installation scripts are under ORACLE_HOME/demo/scripts.
I customized these scripts a bit to run in batch mode. That solves one half of my requirement - to create source data for my testing my data transformation software.
The second half of the requirement is that I create the same schemas under different names (TR_HR, TR_OE and so on...) without any data. These schemas would represent my target schemas. So, in short, my software would pick up data from a table in a schema and load it up in to the same table in a different schema.
Now, I have two issues in creating my target schema and emptying it.
I would like this in a batch job. But the oracle scripts you get, the sample schema names are not configurable. So, I tried creating a script, replacing OE with TR_OE, HR with TR_HR and so on. However, this approach is kind of irritating coz the sample schemas are kind of complicated in the way they are created; Oracle creates synonyms, views, materialized views, data types and lot of weird stuff.
I would like the target schemas (TR_HR, TR_OE,...) to be empty. But some of the schemas have circular references, which would not allow me to delete data. The only work around seems to be removing certain foreign keys, deleting data and then adding the constraints back.
Is there any easy way to all this, without all this fuss? I would need a complicated data set for my testing (complicated as in tables with triggers, multiple hierarchies.. for instance.. a child table that has children up to 5 levels, a parent table that refers to an IOT table and an IOT table that refers to a non-IOT table etc..). The sample schemas are just about perfect from a data set perspective. The only challenge I see is in automating this whole process of loading up the source schemas, and then creating the target schemas and emptying them. Appreciate your help and suggestions.
UPDATE
The main script that you are required to run for manually installing oracle sample schemas is mkplug.sql. Here is the line that loads the schemas up from a dmp file:
host imp "'sys/&&password_sys AS SYSDBA'" transport_tablespace=y file=&imp_file log=&imp_logfile datafiles='&datafile' tablespaces=EXAMPLE tts_owners=hr,oe,pm,ix,sh
Well, I tried modifying this line (after patching up path related issues on mkplug.sql and all other sql files) to this:
host imp "'sys/&&password_sys AS SYSDBA'" rows=n transport_tablespace=y file=&imp_file log=&imp_logfile datafiles='&datafile' tablespaces=EXAMPLE tts_owners=hr,oe,pm,ix,sh
And... it did NOT help. The schema got created with row data, despite rows=n attribute :(
Since you're already familiar with exp/imp (or expdp/impdp) from the Oracle scripts that use the .dmp file, why not just:
Create the empty TR_xxx schemas
Populate the TR_xxx schema from the
xxx .dmp file with the FROMUSER/TOUSER
options and ROWS=N (similar options
exist for expdp/impdp)
[Edit after reading your comment about the transportable tablespaces]
I didn't know that the Oracle scripts were using transportable tablespaces and that multiple schemas were being imported from a single file. This is probably the most straightforward way to create your new empty TR schemas:
Start with the standard, populated
database built with the Oracle
scripts
Create no-data export files on a
schema-by-schema basis (OE shown) by:
exp sys/&&password_sys AS SYSDBA
file=oe_nodata.dmp
log=oe_nodata_exp.log owner=OE rows=N
grants=N
(You should only have to do this once
and this dmp file can be reused)
Now, your script should:
Drop any TR_ users with the CASCADE
option
Re-create the TR_ users
Populate the schema objects (OE
shown) by:
host imp "'sys/&&password_sys AS
SYSDBA'" file=oe_nodata.dmp
log=tr_oe_imp.log fromuser=OE
touser=TR_OE
Here is an anonymos block which - for a given schema - disables triggers and foreign keys, truncates all the tables and then re-enables triggers and foreign keys. It uses truncate for speed but obviously this means no rollback: so be careful which schema name you supply! It's easy enough to convert that call into a delete from statement if you prefer.
The script is a fine example of cut'n'paste programming, and would no doubt benefit from some refactoring to remove the repetition.
begin
<< dis_triggers >>
for trgs in ( select owner, trigger_name
from all_triggers
where table_owner = '&&schema_name' )
loop
execute immediate 'alter trigger '||trgs.owner||'.'||trgs.trigger_name
||' disable';
end loop dis_triggers;
<< dis_fkeys >>
for fkeys in ( select owner, table_name, constraint_name
from all_constraints
where owner = '&&schema_name'
and constraint_type = 'R')
loop
execute immediate 'alter table '||fkeys.owner||'.'||fkeys.table_name
||' disable constraint '||fkeys.constraint_name;
end loop dis_fkeys;
<< zap_tables >>
for tabs in ( select owner, table_name
from all_tables
where owner = '&&schema_name' )
loop
execute immediate 'truncate table '||tabs.owner||'.'||tabs.table_name
||' reuse storage';
end loop zap_tables;
<< en_fkeys >>
for fkeys in ( select owner, table_name, constraint_name
from all_constraints
where owner = '&&schema_name'
and constraint_type = 'R')
loop
execute immediate 'alter table '||fkeys.owner||'.'||fkeys.table_name
||' enable constraint '||fkeys.constraint_name;
end loop en_fkeys;
<< en_triggers >>
for trgs in ( select owner, trigger_name
from all_triggers
where table_owner = '&&schema_name' )
loop
execute immediate 'alter trigger '||trgs.owner||'.'||trgs.trigger_name
||' enable';
end loop en_triggers;
end;
/

Resources