oracle 如果架构连接到sql开发人员,如何退出脚本

k75qkfdt  于 2023-06-22  发布在  Oracle
关注(0)|答案(1)|浏览(139)

我有这个.sh脚本来检查用户是否存在,如果是,那么它使用sqlplus删除用户。但主要问题是,当用户在SQL开发人员中连接时,它不会删除用户也不会停止脚本。我想做的是,如果用户没有删除,那么它应该停止脚本。

echo "SELECT COUNT(*) FROM dba_users WHERE username = '$schemas';" > check_user.sql
echo "exit" >> check_user.sql

result=\$(sqlplus -S / as sysdba @check_user.sql | grep -o -E '[0-9]+')

if [[ \$result -ge 1 ]]; then
    echo "Dropping user: $schemas"
    echo "drop user $schemas cascade;" > drop_schema.sql
    echo "exit" >> drop_schema.sql
    sqlplus -S / as sysdba @drop_schema.sql
    rm drop_schema.sql
else
    echo "User $schemas do not exist."
fi

rm check_user.sql
w8ntj3qf

w8ntj3qf1#

这是一个非常危险的剧本。“drop user cascade”表示删除所有对象。* 这将破坏数据 * 如果他们有表。我建议你不要尝试写这种破坏性的东西。此外,如果您有用户连接,为什么要删除该用户?当不再需要用户时,他们会被丢弃;显然还有东西需要这些
但我想回答你的问题首先,删除CASCADE选项。然后发出命令:WHENEVER SQLERROR EXIT FAILURE在脚本的开头。如果它试图删除仍处于连接状态的用户,它将抛出一个错误,SQL*Plus将立即退出。
如果您真的想彻底清除整个模式(所有的对象),那么就手动完成,而不是通过脚本。如果你坚持要编写脚本,那么你会想先杀死所有连接的会话:

BEGIN
  FOR rec_session IN (SELECT * FROM gv$session WHERE username = '$schemas')
  LOOP
    EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION '''||rec_session.sid||','||rec_session.serial#||',@'||rec_session.inst_id||''''; -- if non-RAC, leave out the ,inst_id piece.
  END LOOP;
END;

您可能还必须使用gv$access来终止 * 其他 * 用户的任何会话,这些用户碰巧正在使用您要删除的模式中的对象。你不能删除一个正在使用的对象,所以你必须先阻止所有人使用它。另一个不写这个的原因。
最后,您可以考虑将整个代码编写为仅由shell启动的匿名PL/SQL块,而不是在shell中执行所有编程逻辑。你的潜在失败点会少得多。

相关问题