How to prevent a user from using space in a tablespace? - sql

I tried the following commands,but i can still insert into the table on appts. Why?
MICHAEL#orcl#SQL> alter user michael quota 0M on appts;
User altered.
MICHAEL#orcl#SQL> select tablespace_name,max_bytes from user_ts_quotas;
TABLESPACE_NAME , MAX_BYTES
------------------------------,----------------
APPTS , 0
MICHAEL#orcl#SQL> select tablespace_name,table_name from user_tables;
TABLESPACE_NAME ,TABLE_NAME
------------------------------,------------------------------
APPTS ,TEST_D
....
MICHAEL#orcl#SQL> insert into test_d values(292,'Test',500,2100);
1 row created.

What about using ALTER TABLESPACE to make it read only? You could enter:
ALTER TABLESPACE APPTS READ ONLY

Related

How to pass a value to a subtitution variable using select script

I have a SQL script in which I declare some substitution variables at the top. The purpose of the script is to create a set of tables and views on a bunch of Oracle schemas when doing multi tenant deployment.
In one of the scripts that creates tables, a table space is assigned. Since the table space name varies from tenant to tenant, I want to extract the table space name from the schema and put it in as a substitution variable that I can then use through the script that creates tables and views.
An example:
define VISchema = FCFVI0
CREATE TABLE "&VISchema."."FSV_LIST_INFO"
("LIST_KEY" NUMBER GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE,
"LIST_REFERENCE" VARCHAR2(255 CHAR),
"LIST_SOURCE" VARCHAR2(255 CHAR),
"LAST_SCREENED" DATE,
"LAST_UPDATE" DATE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "&tablespace_nm." NO INMEMORY ;
I want to assign a value to the tablespace_nm substitution variable using the output from:
select tablespace_name from user_tablespaces;
But I have not figured out how.
If doing:
variable tablespace_nm_1 CHAR;
exec select tablespace_name into :tablespace_nm from user_tablespaces;
and I try to reference that variable as :tablespace_nm it says the tablespace does not exist.
Any help is appreciated
Well, if you have that script which contains bunch of tables you're going to create, maybe the simplest option is to open it in any decent text editor and perform search & replace, providing new values.
Otherwise, in my database, your way wouldn't work because user_tablespaces doesn't contain just one tablespace (so your select would fail with too_many_rows):
SQL> select tablespace_name from user_tablespaces;
TABLESPACE_NAME
------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USERS
Do you really see just one tablespace?
Anyway, for this demonstration, I'll use a where clause to select only one tablespace: users.
In SQL*Plus, you can use substitution variables (documentation is here). Here's how:
SQL> column tablespace_name new_value ts
tablespace_name won't get its value until you select it:
SQL> select tablespace_name from user_tablespaces
2 where tablespace_name = 'USERS';
TABLESPACE_NAME
------------------------------
USERS
OK; let's create table, providing tablespace name via substitution variable:
SQL> create table test (id number) tablespace &ts;
old 1: create table test (id number) tablespace &ts
new 1: create table test (id number) tablespace USERS
Table created.
SQL>
Looks like it works.

In Oracle, Can you create a new table with the same groups if you use CTAS Query?

I use the query CTAS to create a new table, however, when CTAS has finished, other users canĀ“t select the new table, but they had access to the old, Is it a way to pass all the users and groups to the new table? because the old table will be deleted.
"A way" is to grant (at least) select privileges to all those users.
If you used a role and granted select privilege to that role, and then granted role to those users, things would be quite simpler - just grant select privilege on the new table to the same role, and everyone will "see" it.
Otherwise, you can write query to create those grant statements for you.
For example, in Scott's schema there's the EMP table. I've previously granted privileges on it to other users in my database, and now I'm going to create a "new" CTAS table and grant privileges to the same set of users.
SQL> create table my_new_table as select * from emp;
Table created.
SQL> select 'grant select on my_new_table to ' || grantee ||';' run_me
2 from all_tab_privs_made
3 where owner = 'SCOTT'
4 and table_name = 'EMP';
RUN_ME
---------------------------------------------------------------
grant select on my_new_table to SYS;
grant select on my_new_table to SUPERUSER;
grant select on my_new_table to MY_ROLE;
grant select on my_new_table to MIKE;
Now simply copy/paste the above bunch of grant statements:
SQL> grant select on my_new_table to SYS;
Grant succeeded.
SQL> grant select on my_new_table to SUPERUSER;
Grant succeeded.
SQL> grant select on my_new_table to MY_ROLE;
Grant succeeded.
SQL> grant select on my_new_table to MIKE;
Grant succeeded.
SQL>
If there's zillion of users, PL/SQL option would be simpler as it would do everything for you (i.e. no copy/pasting):
SQL> begin
2 for cur_r in (select grantee
3 from all_tab_privs_made
4 where owner = 'SCOTT'
5 and table_name = 'EMP'
6 )
7 loop
8 execute immediate 'grant select on my_new_table to ' || cur_r.grantee;
9 end loop;
10 end;
11 /
PL/SQL procedure successfully completed.
SQL>
If you create a table using CTAS from an existing one, the new one is a new segment, therefore it lacks of privileges. You need to recover the permissions granted to the old table and granting to the new one. For that you can use several alternatives ( dbms_metadata, dynamic sql ).
For the purposes , I'd do it like this
SQL> CREATE TABLE T2 AS SELECT * FROM T1 ;
SQL> begin
dbms_metadata.set_transform_param (dbms_metadata.session_transform,
'SQLTERMINATOR', true);
dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'PRETTY',
true);
end;
/
select replace(dbms_metadata.get_dependent_ddl('OBJECT_GRANT', 'T1', 'OWNER_OF_T1' ),'T1','T2') AS ddl
from dual;
The first part is for creating in a nice format the list of necessary grants. The second part retrieves all the privileges granted to T1 and generates the list of grants statements for running to the T2 table. Then you only need to run the list of grants
As I said, there are several alternatives to do this.
Regards

how to access another user1s table in sql developer database?

BBMA.SALES_BKP TABLE IS THERE IN BBMP SCHEMA(user)
I WANT TO ACCESS "SALES_BKP TABLE" through DUMMY(its different user)
Here's how.
SQL> create user dummy identified by dummy
2 default tablespace user_data
3 temporary tablespace temp
4 quota unlimited on user_data;
User created.
SQL> grant create session, create table to dummy;
Grant succeeded.
SQL> create user bbma identified by bbma
2 default tablespace user_data
3 temporary tablespace temp
4 quota unlimited on user_data;
User created.
SQL> grant create session to bbma;
Grant succeeded.
Now, create table and let another user select from it.
SQL> connect dummy/dummy#orcl
Connected.
SQL> create table sales_bkp(id number, value number);
Table created.
SQL> insert into sales_bkp values (1, 100);
1 row created.
SQL> grant select on sales_bkp to bbma; --> this
Grant succeeded.
SQL> connect bbma/bbma#orcl
Connected.
SQL> select * from dummy.sales_bkp; --> note owner name
ID VALUE
---------- ----------
1 100
SQL>

Error creating nested table column storage table

Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
Seeking help from experts to resolve the following error:
CREATE TABLE "ABC"
(----
----
"STATUSES" "INTLIST" ,
----
"CHAIN_DETAILS" "CHAIN_CFG_LIST" ,
-----
)
NESTED TABLE "STATUSES" STORE AS "OP_STATUSES_NT"
RETURN AS VALUE
NESTED TABLE "CHAIN_DETAILS" STORE AS "op_chains"
RETURN AS VALUE;
Gives error message:
ORA-02320: Error creating nested table column storage table STATUSES
ORA-01950: no permissions for tablespace
My guess is the user has no quota on the default tablespace. You can find your default tablespace by querying user_users, or dba_users if checking a different user, and the quota from user_ts_quotas or dba_ts_quotas. A value of -1 means unlimited. Join these to see your quota for the default tablespace:
select u.username
, u.default_tablespace
, tq.max_bytes
from user_users u
left join user_ts_quotas tq
on tq.tablespace_name = u.default_tablespace;
This will be a problem for any table, but if deferred_segment_creation is set to true (the default) then the error will only appear when you attempt to add a row to the table, as this is the first request for storage.
Now that I check, it seems a nested table requires storage immediately, which could explain why you get the error for a nested table column.
Example using test user 'demo':
sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Fri May 11 10:41:51 2018
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> create user demo identified by demo;
User created.
SQL> grant create session, create table, create type to demo;
Grant succeeded.
Connect as demo:
SQL> conn demo/demo
Connected.
SQL> col username format a15
SQL> col default_tablespace format a20
SQL> select u.username
2 , u.default_tablespace
3 , tq.max_bytes
4 from user_users u
5 left join user_ts_quotas tq
6 on tq.tablespace_name = u.default_tablespace;
USERNAME DEFAULT_TABLESPACE MAX_BYTES
--------------- -------------------- ----------
DEMO USERS
My default tablespace is USERS and I have no quota on it, but I can create a table:
SQL> create table demotable(id integer);
Table created.
I only have a problem when I need some actual storage:
SQL> insert into demotable values (1);
insert into demotable values (1)
*
ERROR at line 1:
ORA-01950: no privileges on tablespace 'USERS'
Now try with a nested table:
SQL> create or replace type demo_tt as table of number(1);
2 /
Type created.
SQL> create table abc
2 ( id integer
3 , statuses demo_tt )
4 nested table statuses store as op_statuses_nt return as value;
create table abc
*
ERROR at line 1:
ORA-02320: failure in creating storage table for nested table column STATUSES
ORA-01950: no privileges on tablespace 'USERS'
My user demo needs a quota on tablespace USERS (normally you grant unlimited or nothing, but just for fun let's allocate 1MB...)
SQL> conn / as sysdba
Connected.
SQL> alter user demo quota 1M on users;
User altered.
SQL> conn demo/demo
Connected.
SQL> select u.username
2 , u.default_tablespace
3 , tq.max_bytes
4 from user_users u
5 left join user_ts_quotas tq
6 on tq.tablespace_name = u.default_tablespace;
USERNAME DEFAULT_TABLESPACE MAX_BYTES
--------------- -------------------- ----------
DEMO USERS 1048576
Retry the table creation:
SQL> create table abc
2 ( id integer
3 , statuses demo_tt )
4 nested table statuses store as op_statuses_nt return as value;
Table created.
SQL> insert into abc (id, statuses) values (1, demo_tt(1,2,3));
1 row created.

Oracle: Insufficient privileges on inserting data into tablespace tables

I'm a little new to all this... I want to create a new tablespace that will contain all my tables and indexes.
first the tablespace code..
create tablespace Sales_T
datafile 'C:\oracle\product\10.2.0\oradata\project\dataexample.dbf'
size 100m
autoextend on next 100m;
and then the user that will be assigned on this space:
create user app_admin identified by "p4ss" default tablespace
sales_T temporary tablespace temp;
grant connect, resource to app_admin;
grant dba to app_admin;
Logging in to app_admin user, I can create tables but can't query or insert data into them, which privileges do I need to grant to?
Use this
grant imp_full_database to p4ss;
This will lets you access your database and let you query over it.
The quota may be the problem:
sql>select username,tablespace_name,max_bytes from dba_ts_quotaS WHERE USERNAME='p4ss';
no rows selected
quotas are not allocate for p4ss user
sql> alter user p4ss quota unlimited on sales_T;
sql>select username,tablespace_name,max_bytes from dba_ts_quotaS WHERE USERNAME='p4ss';
USERNAME TABLESPACE_NAME MAX_BYTES
------------------------------ ------------------------------ ----------
P4SS SALES_T -1
-1 means unlimited