[英]Check whether a tables exist or not on another schema - ORACLE DB
我有一個由EMP_DBA創建的存儲過程,查詢的一部分將檢查現有表是否存在,如果存在,則刪除表。 如果我以EMP_DBA身份連接,則此查詢工作正常,現在我想使用其他帳戶(假設用戶USER1)運行此存儲過程,並且已授予USER1所有必要的權限。 如果表MARKET_DATA存在於模式EMP_DBA中,那么如何重寫下面的語句以使順序計數返回1?
BEGIN
SELECT COUNT(*) INTO c
FROM all_tables
WHERE
table_name = 'MARKET_DATA' AND OWNER = 'EMP_DBA';
IF C = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE MARKET_DATA';
--exception when others then null;
END IF;
您的選擇是正確的。 您應該重寫EXECUTE IMMEDIATE來執行
DROP TABLE EMP_DBA.MARKET_DATA
“我已授予USER1所有必要的權限”
這是一個令人擔憂的聲明。 所有必要的權利意味着什么? 唯一適當的權限是對EMP_DBA擁有的存儲過程執行。 該過程應封裝所有內容。 EMP_DBA不希望(或不希望)USER1獨立刪除其表。 此外,不可能在特定對象甚至特定模式上授予DDL語句。 並且DROP ANY是分發的強大特權。
編寫存儲過程的最佳方法是使用定義者的權限(默認設置)。 這樣可以確保代碼是使用存儲過程所有者(而不是執行用戶)的特權執行的。 您的代碼不起作用-大概是因為您沒有指定表所有者-提示您沒有正確的安全模型。
在我的版本中,我像您一樣使用ALL_TABLES來顯示CURRENT_USER和SESSION_USER之間的區別,但是實際上USER_TABLES也可以工作。
create or replace procedure recreate_tab
(p_tab_name in all_tables.table_name%type)
authid definer
is
n pls_integer;
begin
select count(*)
into n
from all_tables
where owner = (sys_context('userenv','current_user'))
and table_name = p_tab_name;
if n = 1
then
-- no need to specify schema because it's the procedure owner
execute immediate 'drop table '|| p_tab_name;
end if;
execute immediate 'create table '||p_tab_name
||' ( id number, descr varchar2(30))';
-- grant rights on the new table to the user executing the procedure
execute immediate 'grant select on '||p_tab_name||' to '
|| sys_context('userenv','session_user');
end recreate_tab;
/
grant execute on recreate_tab to user1
/
所以。 我什么都沒有...
SQL> conn user1/user1
Connected.
SQL> select count(*) from t42
2 /
select count(*) from t42
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select count(*) from emp_dba.t42
2 /
COUNT(*)
----------
56179
SQL> exec emp_dba.recreate_tab('T42')
PL/SQL procedure successfully completed.
SQL> select count(*) from emp_dba.t42
2 /
COUNT(*)
----------
0
SQL>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.