Oracle- Noforce - oracle

I am using Sql Developer to access a oracle database. Recently I created a View with the option NOFORCE CREATE OR REPLACE NOFORCE VIEW XXXX (...)
Afterwards I looked into the definition of the newly created view and I got a statement looking like CREATE OR REPLACE FORCE VIEW "name"."XXXX"
Now I am not quite sure, if this is a wrong display setting for the Sql Developer or if the view is created with the force.

This just appears to be how Oracle handles views once they've been created, as you can see from the following example:
create or replace noforce view dummy_vw as select dummy from dual;
select * from user_views where view_name = 'DUMMY_VW';
VIEW_NAME TEXT_LENGTH TEXT TYPE_TEXT_LENGTH TYPE_TEXT OID_TEXT_LENGTH OID_TEXT VIEW_TYPE_OWNER VIEW_TYPE SUPERVIEW_NAME EDITIONING_VIEW READ_ONLY
--------- ----------- ---------------------- ---------------- --------- --------------- -------- --------------- --------- ------------------------------ --------------- ---------
DUMMY_VW 22 select dummy from dual N N
select DBMS_METADATA.GET_DDL('VIEW','DUMMY_VW') from DUAL;
CREATE OR REPLACE FORCE VIEW "SCHEMA"."DUMMY_VW" ("DUMMY") AS
select dummy from dual;
Since force/noforce only affects the view at the point when it's created, it doesn't really matter if the script is returned with or without the FORCE keyword, so I guess they just defaulted it to show with the FORCE keyword, since the view exists (if the view script had errors and NOFORCE was used, the view wouldn't have been created).

Related

Oracle - denie columns in where clause

Is there a way to disable/restrict/alert-when-using some column in Oracle in a where clauses?
The reason that I'm asking this is because I have a very complex system (~30 services span cross millions of lines of code with thousends of sqls in it, in a sensitive production environment) working with an Oracle DB I need to migrate from using one column that is part of a key (and have a very not uniqu name) to another column.
Simple search is impossible....
The steps I'm having are:
populate new column
Add indexes on with the second column whenever there's an index with the first one.
Migrate all uses in where caluses from old to new column
Stop reading from the first column
Stop writing to the first column
Delete the column
I'm currently done step 3 and want to verify I've found all of the cases.
So, you're replacing one column with another. Which benefit do you expect once you're done? How will that improve overall experience with that application? I hope it is worth the effort.
As of your question: query user_source (or expand it to all_source or even dba_source, but you'll need additional privileges to do that) and see where's that very not unique name used. Something like this:
SQL> select * from user_source where lower(text) like '%empno%';
NAME TYPE LINE TEXT
--------------- ------------ ----- --------------------------------------------------------------------------------
P_RAISE PROCEDURE 22 WHERE empno = par_empno;
P_RAISE PROCEDURE 14 WHERE empno = par_empno;
P_RAISE PROCEDURE 1 PROCEDURE p_raise (par_empno IN emp.empno%TYPE)
GET_LIST FUNCTION 7 'select empno, ename, job, sal from emp where deptno = 10 order by '
SQL>

Is it possible to set default ORACLE dblink for session and avoid #dblink_name suffixes

I have an Oracle database with a couple of public dblinks for various customers. All linked databases for all customers are identical. Also I have a schema on my host machine only, where I stored DB views with some data retrieval logic.
Currently, if I want to retrieve the same data from various customers, I have to create separate almost identical views for every client:
CREATE VIEW my_view_for_cliet1 AS
SELECT *
FROM table1#dblink1;
CREATE VIEW my_view_for_cliet2 AS
SELECT *
FROM table1#dblink2
Is it possible to set default dblink for session (or something similar) and have only one DB view without explicit dblink, for example:
CREATE VIEW my_view AS
SELECT *
FROM table1;
-- below I want to retrieve data from 3rd client
ALTER SESSION SET DEFAULT DBLINK dblink3;
SELECT * FROM my_view;
P.S. I have only SELECT rights on linked machines so I can't create any views or other objects.
No, that is not possible. Every reference to a dblink must be explicit.
Note that each of the other solutions presented (so far) can give the appearance of what you're asking, but still require explicit dblink references in all of the actual views and thus the same DDL changes for every new link and/or client user. There's no way to avoid creating those individual views or explicit references at some level (which is what I believe you were asking), even if you hide them somewhat from the user.
I'd suggest using synonyms, and set up a procedure to change them all at once, e.g.
create or replace procedure SET_DBLINK ( target_link IN VARCHAR2 ) is
begin
execute immediate 'create or replace synonym TABLE1 for TABLE1#' || target_link;
execute immediate 'create or replace synonym TABLE2 for TABLE2#' || target_link;
-- ...etc...
end;
/
That way you could do:
exec SET_DBLINK('dblink3');
select * from table1;
You'd probably want to add validation and exception handling to the procedure, but I left it simple for readability.
For example, user manager
CREATE OR REPLACE VIEW manager.example1 (
column1,
column2
)
AS
select 1, user from dual#dblink1
where 'SCOTT'=user
union all
select 2, user from dual#dblink2
where 'MANAGER'=user
union all
select 3, user from dual#dblink3
where 'HR'=user;
grant select on example1 to scott;
grant select on example1 to hr;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
2 MANAGER
user scott
create synonym example1 for manager.example1;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
1 SCOTT
user hr
create synonym example1 for manager.example1;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
3 HR

How to show stored trigger in sql?

I was working on a trigger, now I want to make some changes and see the code, is it possible to see, if so then how? the trigger is working fine, is there any command in plsql to where I can check out the code? I am using sql command line
user_triggers (or all_triggers) have the trigger source code. Similarly user_source (or all_source) have other source code.
General rule though that I follow is to always always always have a file structure where I keep the source. 100% rule that no one in the team is allowed to violate ever. Then I view the act of creating trigger equivalent to "compiling" in traditional programming. In that model, you would have a directory tree for example
<project>/src
<project>/src/plsql
<project>/src/plsql/<folder for each package>/<files>
<project>/src/plsql/<folder for each table>/<triggers>
And then "modifying" is simply changing them here and "compiling" again (compiling will imply running these via sqlplus - or still better creating a shell script.
In this model, you can easily incorporate several available version control tools as well.
GUI would display it prettier, but SQL*Plus can do it as well. Here's an example:
Creating a sample trigger:
SQL> create or replace trigger trg_update_percentage
2 after update or insert on item
3 for each row
4 begin
5 insert into students_percentage (sid, total_per)
6 select sid, total from student_report
7 where sid = :new.sid;
8 end;
9 /
Trigger created.
Fetch its description from USER_TRIGGERS; as the body is stored into the LONG datatype column, set long should be used (otherwise you won't see the complete code).
SQL> set long 4000
SQL> select trigger_name, trigger_type, triggering_event, table_name, trigger_body
2 from user_Triggers where trigger_name = upper('trg_update_percentage');
TRIGGER_NAME TRIGGER_TYPE TRIGGERING_EVENT TABLE_NAME
------------------------- -------------------- -------------------- ----------
TRIGGER_BODY
--------------------------------------------------------------------------------
TRG_UPDATE_PERCENTAGE AFTER EACH ROW INSERT OR UPDATE ITEM
begin
insert into students_percentage (sid, total_per)
select sid, total from student_report
where sid = :new.sid;
end;
SQL>

Oracle - drop errored view

I have a Oracle view where when trying to view, replace, or even drop the view it shows below error:
DROP X.z force
*
ERROR at line 1:
ORA-06553: PLS-707: unsupported construct or internal error [2604], [403]
ORA-06553: PLS-103: Encountered the symbol "Vendor " when expecting one of
the following:
<an identifier> <a double-quoted delimited-identifier>
ORA-06553: PLS-112: end-of-line in quoted identifier
The column mentioned mistakenly have a break line
(it is: "Vendor
Name"). The problem that I cannot replace, rename or even drop to fix the issue.
Is there any way I can forcedly drop it or recreate ?!
Based on what is described in My Oracle Support Doc ID 2254717.1, which seems to be about exactly this problem, you should be able to do something like:
column object_id new_value bad_object_id;
select object_name, object_type, owner, status, object_id
from all_objects
where object_type='VIEW' and owner='X' and object_name = 'Z';
OBJECT_NAME OBJECT_TYPE OWNER STATUS OBJECT_ID
------------------------------ ------------------- ------------------------------ ------- ----------
Z VIEW X VALID 445264
exec dbms_utility.invalidate(&bad_object_id);
PL/SQL procedure successfully completed.
select object_name, object_type, owner, status, object_id
from all_objects
where object_type='VIEW' and owner='X' and object_name = 'Z';
OBJECT_NAME OBJECT_TYPE OWNER STATUS OBJECT_ID
------------------------------ ------------------- ------------------------------ ------- ----------
Z VIEW X INVALID 445264
drop view X.z;
View X.Z dropped.
I've used substitution variables but you can just manually enter the object ID of course.
I haven't been able to figure out how to recreate the issue - the MoS doc seems to also not know how it happened, though in that case was from an 11g to 12c upgrade, and can only speculate vaguely about corruption. I tried exporting and importing a view using the same versions but it still didn't complain. So I haven't been able to verify this will actually work as advertised, but it looks like it should...

Copying fields in Oracle

I am not a programmer, but have a task of automatically copying one field in a table to another field in the same table (it's a long story... :-) ). This should be done on update and insert and I really do not know how to go about it.
I should point out that data is entered to the DB through a user-interface which we do not have the source code for, and therefore we want to do this change on a DB level, using a trigger or likes.
I have tried creating a simple trigger that will copy the values across, but came up with an error message. After Googling the error, I found that I need to create a package which will be used as a variable. Now I am really lost!!!! :-)
I want to also point out that I need a solution that will update this field automatically from now on, but not override any data that already exists in the column.
Could someone show me the easiest and simplest way of doing this entire procedure? I really need a 'Guide for dummies' approach.
Thanks,
David
A simple trigger will be adequate if both fields are on the same table.
Consider:
SQL> CREATE TABLE t (ID NUMBER, source_col VARCHAR2(10), dest_col VARCHAR2(10));
Table created
SQL> CREATE OR REPLACE TRIGGER trg_t
2 BEFORE INSERT OR UPDATE OF source_col ON t
3 FOR EACH ROW
4 BEGIN
5 IF :old.dest_col IS NULL THEN
6 :NEW.dest_col := :NEW.source_col;
7 END IF;
8 END;
9 /
Trigger created
We check if the trigger works for insert then update (the value we inserted will be preserved):
SQL> INSERT INTO t(ID, source_col) VALUES (1, 'a');
1 row inserted
SQL> SELECT * FROM t;
ID SOURCE_COL DEST_COL
---------- ---------- ----------
1 a a
SQL> UPDATE t SET source_col = 'b';
1 row updated
SQL> SELECT * FROM t;
ID SOURCE_COL DEST_COL
---------- ---------- ----------
1 b a
Edit: I updated the trigger to take into account the requirement that the existing data on dest_col is to be preserved.
If you just need the new column to show the exact same data as the old column I think (if you're using Oracle 11g) that you can create a virtual column.
There's an example here.

Resources