Role to access the table only but not data from Table in Oracle Exadata - sql

Users have create table statement with select statement from multiple tables from multiple schema. I want to restrict them to read data and allow them to create empty table in their schema with metadata only not data. This I want to do at user access and roles level.
Please tell me how I can do this?
I have tried giving them read access on underlying tables but users can see data as well.
Create table cust_acct_details
as
select *
from ep_rel.acct a
inner join ep_dnf.Cust_account ca
on a.acct_id = ca.acct_id
Tables should create without data.

Add below condition to your code
-- condition to add where 1<>1
Create table cust_acct_details
as
select *
from ep_rel.acct a
inner join ep_dnf.Cust_account ca
on a.acct_id = ca.acct_id
where 1<>1
Please make sure there are unique column names in your select statement. Oracle will not allow same column name in one table. Please use alias instead of *.

If you remove all tablespace privileges from a user they can still create tables but they won't be able to populate them.
For example, if you run this PL/SQL block to revoke all tablespace quotas from one user:
begin
for users in
(
select 'alter user '||username||' quota 0 on '||tablespace_name v_sql
from dba_ts_quotas
where username = 'TEST_USER'
order by 1
) loop
execute immediate users.v_sql;
end loop;
end;
/
Now the user can create tables but will get an error if they try to add rows:
SQL> create table test1(a number);
Table created.
SQL> insert into test1 values(1);
insert into test1 values(1)
*
ERROR at line 1:
ORA-01536: space quota exceeded for tablespace 'USERS'
For metadata, users can always see the metadata in their own schema. To allow them to view the metadata in other schema, run a grant like:
grant select_catalog_role to the_user;
Then that user can view the metadata either in the ALL_ data dictionary views, or using DBMS_METADATA.GET_DDL.

Related

BigQuery create Temp table

I am trying to create a temporary table with a specific name so i can use it in other queries. The problem is that when i create a temp table like this:
BEGIN
BEGIN TRANSACTION;
--delete test_temp where 1=1;
create temp table test_temp as SELECT * FROM `analytics.reports.analysis` ;
COMMIT TRANSACTION;
END;
the table name is indeed test_temp but if i will try to select * from test_temp
i get nothing. the table id always generates a new unique id.
something like analytics-prod:_script3991beb3e9868774854ac09d407f1c397428a4f6.test_temp
Is there a way to make this temp table with a pre-defined name?
What I am trying to achieve basically is create a table from a select every 15min.
I thought to create a scheduled query running this transaction that will delete + populate the temp table and then I can always reference to test_temp without changing the table id.
According to the docs:
You can refer to a temporary table by name for the duration of the current multi-statement query
So if you want to refer the table in other queries, an option could be use a permanent table in a separated dataset:
...
CREATE OR REPLACE TABLE `analytics.my_temp_dataset.test_temp` AS SELECT * FROM `analytics.reports.analysis` ;
...
In that case, you don't need a temp table but a permanent table you just replace on the next run using the CREATE OR REPLACE TABLE statement. If you are using the temp table as part of a scripting stage, then I suggest using running this instead:
BEGIN
CREATE OR REPLACE TEMP TABLE _SESSION.test_temp AS
SELECT * FROM `analytics.reports.analysis`;
-- SELECT COUNT(*) CNT FROM _SESSION.test_temp;
END;
Since it is a temp table you don't need a DROP query at the end.
You can create a temporary table in a session in BigQuery.
You can create a session via the API and then create your temporary tables in the session. The tables will then be visible to all queries using that session.
There are limitations on sessions you should be aware of:
They last up to 24 hours max
No concurrent jobs running in a session
I use temporary tables with sessions to do complex transformations in an ETL pipeline. For example:
Create session
Create temporary tables
Do joins, and other transformations, write results to temporary tables
Do final transformations and output results to permanent tables
End session
I am writing a Python API for this and will put it on github at some point. I could probably post a gist if that is helpful.
In the meantime, see Google's documentation for sessions in BigQuery:
https://cloud.google.com/bigquery/docs/sessions-intro

ORA-00942 cannot find table

I ran these statements:
create table SAMPLE(
ID INT
);
INSERT INTO SAMPLE VALUES(1);
COMMIT;
GRANT INSERT, SELECT, UPDATE, DELETE ON SAMPLE TO NEWLEC;
COMMIT;
But Eclipse says cannot find the table.
How can I resolve it?
You are connecting as the newlec user, and unqualified references to tables will look for them in that schema, not under other users.
You can qualify the table name:
SELECT * FROM real_owner.SAMPLE
For example, if you were connected as HR when you created the table, you would do:
SELECT * FROM HR.SAMPLE
You could also create a public synonym, which is probably overkill and can cause other issues and confusion; or create a private synonym for the newlec user which points to the rea table, e.g.:
CREATE SYNONYM SAMPLE FOR real_owner.SAMPLE;
SELECT * FROM SAMPLE;
so the unqualified query now sees the synonym, and through that the real table owned by someone else. Or you could set your current_schema after logon:
ALTER SESSION SET CURRENT_SCHEMA=real_owner;
SELECT * FROM SAMPLE;
so all unqualified queries now see objects owned by that user, not newlec.
However, if this is a basic assignment on a beginner course then you are probably just expected to qualify the name.

I have restricted select access at table level in sql server. But users are able to access views which are created top of that table

I have restricted select access at table level for 1 single table 'A'in sql server(2016).
But users are able to access views which are created top of that table 'A'.
when users run select statement on table 'A'(select * from table 'A')users are getting 'select permission is denied on object table 'A' ' message.
when users run select statement on view (select * from view 'A') users are able to access all data.
Users are able to create new views by writing select statement on table 'A'.
How can i restrict users to access table 'A' from views as well.
This is expected behavior due to ownership chaining. Permissions on tables referenced by the view are not checked as long as the view and tables have the same owner (AUTHORIZATION).
To break the ownership chain, you could either move the table to a different schema (owned by a different user than the view schema) or change to owner of the table. Examples below.
--move table to different schema
CREATE USER RestricedTablesOwner WITHOUT LOGIN;
GO
CREATE SCHEMA RestricedTables AUTHORIZATION RestricedTablesOwner;
GO
ALTER SCHEMA RestricedTables TRANSFER dbo.A;
GO
--change table to different owner, retaining same schema
ALTER AUTHORIZATION ON OBJECT::dbo.A TO RestricedTablesOwner;

Using Sequence for inserting

I want to insert a new row in my table.
There I want to put the ID with the help of seq_name.nextval.
So how to know the sequence name for that particular table?
To use a sequence to generate IDs, you create it normally in the schema where the table is.
As user application user GEM_APP:
CREATE TABLE my_table (id NUMBER, col1 ...);
CREATE SEQUENCE my_seq;
The application user itself (and f.i. it's stored procedures) can use the sequence directly:
INSERT INTO my_table (id, col1) VALUES (my_seq.nextval, 'bla');
However, other users need the correct privileges. Usually, you grant select rights on the sequence to the same users or roles you grant insert rights on the table:
GRANT SELECT, INSERT ON my_table TO user_xy;
GRANT SELECT ON my_seq TO user_xy;
Then the other user can insert data into the table, but must qualify the schema:
INSERT INTO gem_app.my_table(id, col1) VALUES (gem_app.my_seq.nextval, 'bla');
You can create aliases to hide the schemas, some people like them, some not, but I would definitely not recommend to use PUBLIC synonyms as they are hard to control and create all kind of namespace clashes.

What performance considerations should I care when designing a table that will not receive updates

We have in our DB a Table which contains a dozens of rows.
The only DML's which applied on the Table are :
1.Inserts - Rows are inserted due to Trigger execution on another table .
2.Deletes - A schedualed procedure is loading requested records to temp table, working with these records and afterwards deleting them from the specific table (there is also a SELECT from the table in order to populate the temp table each time the procedure is running).
We've build the Table with PK and when we run the deletion,
the table is deleted row by row with the ID of the PK column.
just to clarify, we dont have any UPDATES opreations on the table .
Is there any specific guidelines or recommendations when creating such a table ( without updates ) ?
Thx for your answers .
There's nothing special about a table that you don't intend to update.
You could, if you wanted for security reasons, deny update permissions to everyone, since you really only want to allow inserts, deletes, and selects, but there's nothing special about the design, and nothing forcing you to do so.
you can create this table in another schema and grant select, insert, delete to your schema without granting update
so any trying to execute update statemets from your current schema will not executed.
here is an example:
connect system/manager
grant connect, resource to user1 identified by user1;
grant connect, resource to user2 identified by user2;
disconnect
connect user1/user1
create table user1.table1(col1 number, col1_desc varchar2(16));
grant select, insert, delete on user1.table1 to user2;
disconnect
conn user2/user2
select * from user1.table1
insert into user1.table1 values (1, 'insert-user2');
commit;
insert into user1.table1 values (2, 'insert-user2');
commit;
delete from user1.table1 t where t.col1 = 2;
commit;
update user1.table1 t set t.col1_desc = 'ins-user2' where t.col1 = 1;
commit;
-- last update statement will throw ORA-01031: insufficient privileges
note: you can use table1 table name directly from user2 by using synonym for user1.table1
regards,