save view in a certain schema instead of PUBLIC - view

I create a VIEW in Snowflake:
USE DATABASE PROD_DWH;
CREATE VIEW new as
SELECT
cast(dwh as int) AS dwh_masterclient_id,
FROM INGEST.ISSUE
currently, it gets saved in the PUBLIC schema. How can I save it in another location? For example under the Views section of the schema "DBT_USER_MARKT" within the "PROD_DWH" database?

You have to change context to use the schema you want:
USE DATABASE PROD_DWH;
USE SCHEMA DBT_USER_MARKT;
CREATE VIEW new as
SELECT
cast(dwh as int) AS dwh_masterclient_id,
FROM INGEST.ISSUE
You could also specify the schema in the create statement, or depending on usage the three-part qualifier for the name. Then it won't matter what context is set, it will be created where you want it.
CREATE VIEW PROD_DWH.DBT_USER_MARKT.new as
SELECT
cast(dwh as int) AS dwh_masterclient_id,
FROM INGEST.ISSUE

Related

How can I create a table with same attributes of a View another system delivers me?

An external system granted to my system a view named V_EXT so that I can make selections on it, reading all its content:
SELECT *
FROM V_EXT;
this view has a lot of fields and I would like to create an empty table in my system with the exactly same attributes of this view (same names and same types). Is there a way to do this without simply guessing from the content I received what each attribute is?
I am using Oracle SQL Developer.
With Code.
create table objects_copy2
as
select *
from all_objects
where 1=2; -- add this line if you want NO data, otherwise you get all the data too
With SQL Developer specifically, it's actually harder. You would need to find the underlying OBJECT(s) used in the query. Then look up those data types, and manually build out your CREATE TABLE statement.
CREATE TABLE AS SELECT is the way to go. (Docs)
Note there are some limitations, for example this won't pick up Identity Column definitions from the source table used in the view.
An example:

How to create a table identical to other table in structure and constraints in Oracle?

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;

Where will the record get inserted first?

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.

Can I create an Oracle view that automatically checks for new monthly tables?

I'm wondering if its possible to create a view that automatically checks if there is a new monthly created table and if there is include that one?
We have a new table created each month and each one ends with the number of the month, like
table for January: table_1
table for February: table_2
etc...
Is it possible to create a view that takes data from all those tables and also finds when there is a new one created?
No, a view's definition is static. You would have to replace the view each month with a new copy that included the new table; you could write a dynamic PL/SQL program to do this. Or you could create all the empty tables now and include them all in the view definition; if necessary you could postpone granting any INSERT access to the future tables until they become "live".
But really, this model is flawed - see Michael Pakhantsov's answer for a better alternative - or just have one simple table with a MONTH column.
Will be possible if you instead of creating new table each month will create new partition for existing table.
UPDATE:
If you have oracle SE without partitioning option you can create two tables: LiveTable and ArchiveTable. Then each month you need move rows from Live to ArchiveTable and clean live table. In this case you need create view just from two tables.
Another option is to create the tables in another schema with grants to the relevant user and create public synonyms to them.
As the monthly tables get created in the local schema, they'll "out-precedence" the public synonyms and the view will pick them up. It will still get invalidated and need recompiling, but the actual view text should need changing, which may be simpler from a code-control point of view.
You can write a procedure or function that looks at USER_TABLES or ALL_TABLES to determine if a table exists, generate dynamic sql, and return a ref cursor with the data. The same can be done with a pipelined function.

view with the tables from multiple user schema

I have a view that is built on multiple tables from different users schema. By virtue of the currently logged in user, he is able to see the table from different schema. When the view is created the table name becomes ambiguous as the user have access to the same tables from the different schema.
Is there any way to specify to use the table from current user schema while creating the view?
Can we do it for one of the tables from the view definition while other tables can be selected from any schema?
"When the view is created the table
name becomes ambiguous as the user
have access to the same tables from
the different schema"
It isn't ambiguous to Oracle.
The view exists in a schema, SCHEMA_1. If that view refers to an object TABLE_A, Oracle will first look for an object TABLE_A in SCHEMA_1. If it finds a table, it will use that. If it finds a SYNONYM it will use whatever the synonym points to. If there is nothing in SCHEMA_1, it will look for a PUBLIC SYNONYM for TABLE_A and use whatever that points to.
SYNONYMS can point to other synonyms, views or tables.
You can query USER_DEPENDENCIES to see what objects the view is actually based on.
You cannot have a view in SCHEMA_1 that uses TABLE_A in SCHEMA_2 if queried from SCHEMA_2 but uses a different TABLE_A in SCHEMA_3 if queried from SCHEMA_3.
You should be able to access schema (with correct permissions) by prefixing the schema name.
schemaname.tablename
Hope I understood your question correctly.

Resources