Oracle:在包和过程中设置会话参数
Oracle: Setting Session Parameters in Packages and Procedures
我是一名 SQL 服务器 DBA,目前正在快速了解 Oracle。我正在尝试为 SQL 服务器创建与 sp_WhoIsActive 非常相似的东西,但对于 Oracle 则无需重新发明轮子。基本上我所做的就是从 v$session 中选择一些值并将它们插入到 table(可怜的 ASH/AWR)中。
在 Oracle 12.1 中,查询字典视图时似乎存在一个错误,由于错误的解析逻辑,它可能会永远花费(错误 22225899:复杂查询的解析缓慢)。解决方法是设置会话参数:
alter session set "_optimizer_squ_bottomup"=false;
在 T-SQL 中,我可以非常轻松地在会话中执行存储过程并在 运行 时间设置此变量。然而在 Oracle 中,情况似乎并非如此。
示例代码:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(
v_temp NUMBER :=1
) IS
BEGIN
alter session set "_optimizer_squ_bottomup"=false;
INSERT INTO SY_DB_ACTIVITY
SELECT
<fields>
FROM
v$session;
commit;
当我运行这个时,我得到错误:
"PLS-00103: Encountered symbol 'ALTER' when expecting one of the following..."
现在,我知道如何做到这一点的唯一方法是通过像 SQL Plus 这样的实用程序来启动交互式用户会话。谁能给我一些关于 Oracle 如何处理这种情况的指导?我想将它捆绑到一个 SP 或一个包中,然后从 Oracle Scheduler 中调用它。
Hre 是一个简单示例,说明如何在过程中 执行 alter session
:
CREATE PROCEDURE SP_DB_ACTIVITY IS
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
END;
/
您可以通过以下方式将其与 select 和插入语句结合使用:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS
v_Id NUMBER;
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
SELECT 1
INTO v_Id
FROM dual;
INSERT INTO SY_DB_ACTIVITY (id) VALUES(v_Id);
END SP_DB_ACTIVITY;
/
Here is a small DEMO 在这里您可以看到当您调用它时过程将做什么以及如何调用它。此外,在此示例中,您正在调用带有 IN 参数的过程。所以您可以将该参数用于某些事情,在上面的示例中是没有任何参数的过程...
当然你也可以直接插入table:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS
v_Id NUMBER;
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
INSERT INTO SY_DB_ACTIVITY(id)
select 1
from dual;
END SP_DB_ACTIVITY;
/
我是一名 SQL 服务器 DBA,目前正在快速了解 Oracle。我正在尝试为 SQL 服务器创建与 sp_WhoIsActive 非常相似的东西,但对于 Oracle 则无需重新发明轮子。基本上我所做的就是从 v$session 中选择一些值并将它们插入到 table(可怜的 ASH/AWR)中。
在 Oracle 12.1 中,查询字典视图时似乎存在一个错误,由于错误的解析逻辑,它可能会永远花费(错误 22225899:复杂查询的解析缓慢)。解决方法是设置会话参数:
alter session set "_optimizer_squ_bottomup"=false;
在 T-SQL 中,我可以非常轻松地在会话中执行存储过程并在 运行 时间设置此变量。然而在 Oracle 中,情况似乎并非如此。
示例代码:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(
v_temp NUMBER :=1
) IS
BEGIN
alter session set "_optimizer_squ_bottomup"=false;
INSERT INTO SY_DB_ACTIVITY
SELECT
<fields>
FROM
v$session;
commit;
当我运行这个时,我得到错误:
"PLS-00103: Encountered symbol 'ALTER' when expecting one of the following..."
现在,我知道如何做到这一点的唯一方法是通过像 SQL Plus 这样的实用程序来启动交互式用户会话。谁能给我一些关于 Oracle 如何处理这种情况的指导?我想将它捆绑到一个 SP 或一个包中,然后从 Oracle Scheduler 中调用它。
Hre 是一个简单示例,说明如何在过程中 执行 alter session
:
CREATE PROCEDURE SP_DB_ACTIVITY IS
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
END;
/
您可以通过以下方式将其与 select 和插入语句结合使用:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS
v_Id NUMBER;
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
SELECT 1
INTO v_Id
FROM dual;
INSERT INTO SY_DB_ACTIVITY (id) VALUES(v_Id);
END SP_DB_ACTIVITY;
/
Here is a small DEMO 在这里您可以看到当您调用它时过程将做什么以及如何调用它。此外,在此示例中,您正在调用带有 IN 参数的过程。所以您可以将该参数用于某些事情,在上面的示例中是没有任何参数的过程...
当然你也可以直接插入table:
CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS
v_Id NUMBER;
BEGIN
EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';
INSERT INTO SY_DB_ACTIVITY(id)
select 1
from dual;
END SP_DB_ACTIVITY;
/