Firstly
I am an oracle newbie, and I don't have a local oracle guru to help me.
Here is my problem / question
I have some SQL scripts which have to be released to a number of Oracle instances.
The scripts create stored procedures.
The schema in which the stored procedures are created is different from the schema which contains the tables from which the stored procedures are reading.
On the different instances, the schema containing the tables has different names.
Obviously, I do not want to have to edit the scripts to make them bespoke for different instances.
It has been suggested to me that the solution may be to set up synonyms.
Is it possible to define a synonym for the table schema on each instance, and use the synonym in my scripts?
Are there any other ways to make this work without editing the scripts every time?
Thank you for any help.
Yes, you can create synonym for a schema.
select ksppinm, ksppstvl from x$ksppi a, x$ksppsv b where a.indx=b.indx and ksppinm like '%schema%synonym%'
ALTER SYSTEM SET "_enable_schema_synonyms" = true SCOPE=SPFILE;
STARTUP FORCE
show parameter synonym
Assuming you already have a schema named ORA...
CREATE SCHEMA SYNONYM ORASYN for ORA; -- create synonym for schema
CREATE TABLE ORASYN.TAB1(id number(10)); -- create table in schema
More information here: https://dbaclass.com/article/how-to-create-synonym-for-a-schema/
It'd help to know what version of Oracle, but as of 10g--No, you can't make a synonym for a schema.
You can create synonyms for the tables, which would allow you not to specify the schema in the scripts. But it means that the synonyms have to be identical on every instance to be of any use...
The other option would be to replace the schema references with variables, so when the script runs the user is prompted for the schema names. I prefer this approach, because it's less work. Here's an example that would work in SQLPlus:
CREATE OR REPLACE &schema1..vw_my_view AS
SELECT *
FROM &&schema2..some_other_table
The beauty of this is that the person who runs the script would only be prompted once for each variable, not every time the variable is encountered. So be careful about typos :)
Yes, there is a hidden way to create a schema synonym.
There is a hidden parameter _enable_schema_synonyms. It's false by default , but you can set it to true and create a synonym.
Related
I have created a stored procedure without having synonym , because i don't know the importance of synonym. In my project we use two databases for development and another just to create synonyms.I had created stored proc with three input parameters and two output parameters in development database and also I executed my stored proc, it compiled successfully and got output. My question is can I create in this fashion? what happens if there isn't synonym created for a stored procedure. If it is a must then how did I get the output?. can we create synonym for a stored procedure which has input and output parameters. can any one help me out from this. Thanks in advance. :)
Generally speaking, you do not need to create synonyms for stored procedures.
However there might be cases when synonym is needed.
A synonym is an alternative name for objects such as tables, views,
sequences, stored procedures, and other database objects.
You generally use synonyms when you are granting access to an object
from another schema and you don't want the users to have to worry
about knowing which schema owns the object.
So just read on oracle synonyms and decide whether you need to use them or not.
(synonyms, create synonym)
I want to create a table (lets say table_copy) which has same columns as other table (lets call it table_original) in Oracle database, so the query will be like this :
create table table_copy as (select * from table_original where 1=0);
This will create a table, but the constraints of table_original are not copied to table_copy, so what should be done in this case?
Only NOT NULL constraints are copied using Create Table As Syntax (CTAS). Others should be created manually.
You might however query data dictionary view to see the definitions of constraints and implement them on your new table using PL/SQL.
The other tool that might be helpful is Oracle Data Pump. You could import the table using REMAP_TABLE option specifying the name for the new table.
Use a database tool to extract the DDL needed for the constraints (SQL Developer does the job). Edit the resulting script to match the name of the new class.
Execute the script.
If you need to do this programmatically you can use a statement like this:
DBMS_METADATA.GET_DDL('TABLE','PERSON') from DUAL;
I've database with 15 tables. Now due to development process one column has to added to all the tables in the database. This changes should not affect the existing process because some other services are also consuming this database. So to accomplish it I thought of creating a new database. Is there are any other way to do it.
Usually it should be enough to create a new schema ("user") and create the tables in that new schema. In Oracle, identically named tables can exist in several schemas.
CREATE USER xxx IDENTIFIED BY yyy
you can create another schema for development and import the table to new schema.Developer should use the development schema instead of production schema.you can also create new database and import from current database but it might be last option
What's wrong with alter table T add (COL varchar2(5)); ?
Of course dependend stored procedures or packages become invalid.
You can leave them alone, then the first call would return an exception and auto-recompile the called procedure. Or you can alter procedure P compile;.
I was given an oracle dump file for an existing system. The dump file contained the table PARTS but when I look on the queries being done by the code. It uses mostly M_PARTS and just on one occasion, it uses PARTS. Does oracle allow multiple name on a table?
Note that I am not talking about the alias feature. ie.
Select M_PARTS.*
from PARTS M_PARTS
I want to know if there is a setting to make permanent alias in oracle. Where I just create a table PARTS and I can refer to it as either PARTS or M_PARTS in my query.
Kind of, as you can create synonyms:
CREATE SYNONYM PARTS FOR THE_SCHEMA.M_PARTS;
It is weird however, that the dump file would be inconsistent that way. Are you sure it is the same table? How was the file created?
Yes using synonyms.
Although a synonym was a solution, I found the actual script to build the database and it uses a materialized view instead of a synonym.
create materialized view M_Parts
tablespace USERS
refresh fast
as select * from Parts
I have a schema called "CUSTOMERS". In this schema there is a table called RECEIVABLES.
There is another schema called "ACCOUNTS". In this schema, there is a table called RECEIVABLES_AC.
RECEIVABLES_AC has a public synoym called RECEIVABLES.
The table structure of both the tables is exactly the same.
If your front-end uses the customer schema credentials to establish a connection, how can you ensure that the record will get inserted in RECEIVABLES_AC without changing the front-end code.
I think this is a trick question. Short of renaming the table RECEIVABLES in the CUSTOMERS schema, I don't see how this can be done.
The only way that I can think of (without changing the login or insert statement) is to use a database trigger that runs on login and changes the current schema to ACCOUNTS:
create or replace trigger logon_set_schema
AFTER LOGON ON DATABASE
BEGIN
if sys_context('USERENV','SESSION_USER') = 'CUSTOMERS' then
execute immediate 'alter session set current_schema=accounts';
end if
END;
/
However, this would likely break other aspects of the code, so changing the application to specify the schema name would be vastly preferable.
What isn't specified is if the behavior is supposed to be instead-of or in-addition-to.
Use replication on ACCOUNTS.RECEIVABLES to propagate DML to CUSTOMER.RECEIVABLES_AC. Triggers, streams, what have you.
Use the ALTER SESSION SET CURRENT_SCHEMA statement to change the default namespace of the user's session.
The right way to respond is to fix the design, and to not have multiple receivables tables with public schemas floating about.
Two good ways to solve this problem are:
Option 1
Rename CUSTOMERS.RECEIVABLES.
Drop the public synonym.
Create a private synonym in the CUSTOMERS schema, called RECEIVABLES that points to ACCOUNTS.RECEIVABLES_AC.
Option 2
Change the front-end to refer to RECEIVABLES_AC instead of RECEIVABLES.
Create a private synonym in the CUSTOMERS schema, called RECEIVABLES_AC that points to ACCOUNTS.RECEIVABLES_AC.
I would prefer Option 2. Private synonyms are a great way of controlling which tables are used by a particular schema, without having to hard-code the schema name in the app.