从 Web 应用程序设置 Oracle 会话变量是将值从 Web 应用程序传递到触发器的可靠方法吗?
Is setting an Oracle session variable from a web app a reliable way to pass a value from a web app to a trigger?
我在 Oracle 10g 中进行了查找 table,其中的触发器在插入、更新和删除时填充了历史记录 table。我希望能够通过触发器从历史记录 table 中的 ColdFusion 应用程序捕获用户 ID。
我发现一种可能的方法是使用 Oracle 会话变量:
在 coldfusion 代码中,我在插入、更新和删除代码之前将用户 ID 传递给 Oracle 会话:
CALL dbms_session.set_identifier(12345);
在触发器中,我读取了 client_identifier 变量,如果为空则换成“0”。
SELECT sys_context('USERENV','CLIENT_IDENTIFIER') INTO USER_ID FROM DUAL;
IF USER_ID IS NULL THEN
USER_ID := 0;
END IF;
在单用户测试中这工作正常,但因为我不知道 CF 应用程序服务器的数据库连接与 Oracle 会话的关系,我担心 oracle 会话 var 中的值在多个同时发生时不可靠用户。
从 Web 应用程序设置 Oracle 会话变量是否是将值从 Web 应用程序传递到触发器的可靠方法?
假设您没有执行上面概述的操作(我认为这是行不通的),而是在查找 table(我们称之为 MY_LOOKUP_TABLE
)中添加一列,其中您将进行更新(或插入)的用户的用户 ID 存储到 table:
ALTER TABLE my_lookup_table
ADD update_user_id NUMBER DEFAULT 0 NOT NULL;
(假设您的查找 table 不是很大,并且您不介意为每个现有行设置默认值。)
当您需要从查找中删除一行时,困难就来了 table ...您如何记录删除它的用户的 ID?在这种情况下,您还需要一个列来记录该行已被删除,可能 DELETE_FLAG
:
ALTER TABLE my_lookup_table
ADD delete_flag CHAR(1) DEFAULT 'N' NOT NULL;
然后,在您的更新触发器中,不要在 DELETE_FLAG = 'Y'
:
处记录更新
CREATE OR REPLACE TRIGGER record_update
AFTER UPDATE OF my_lookup_table
FOR EACH ROW
WHEN (new.delete_flag <> 'Y')
当您的应用执行删除操作时,您实际上需要先更新再删除:
<cftransaction>
<cfquery name="update_before_delete_lookup">
UPDATE my_lookup_table
SET update_user_id = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#user_id#" />
, delete_flag = 'Y'
WHERE <conditions>
</cfquery>
<cfquery name="delete_lookup">
DELETE FROM my_lookup_table
WHERE <conditions>
</cfquery>
</cftransaction>
我在 Oracle 10g 中进行了查找 table,其中的触发器在插入、更新和删除时填充了历史记录 table。我希望能够通过触发器从历史记录 table 中的 ColdFusion 应用程序捕获用户 ID。
我发现一种可能的方法是使用 Oracle 会话变量: 在 coldfusion 代码中,我在插入、更新和删除代码之前将用户 ID 传递给 Oracle 会话:
CALL dbms_session.set_identifier(12345);
在触发器中,我读取了 client_identifier 变量,如果为空则换成“0”。
SELECT sys_context('USERENV','CLIENT_IDENTIFIER') INTO USER_ID FROM DUAL;
IF USER_ID IS NULL THEN
USER_ID := 0;
END IF;
在单用户测试中这工作正常,但因为我不知道 CF 应用程序服务器的数据库连接与 Oracle 会话的关系,我担心 oracle 会话 var 中的值在多个同时发生时不可靠用户。
从 Web 应用程序设置 Oracle 会话变量是否是将值从 Web 应用程序传递到触发器的可靠方法?
假设您没有执行上面概述的操作(我认为这是行不通的),而是在查找 table(我们称之为 MY_LOOKUP_TABLE
)中添加一列,其中您将进行更新(或插入)的用户的用户 ID 存储到 table:
ALTER TABLE my_lookup_table
ADD update_user_id NUMBER DEFAULT 0 NOT NULL;
(假设您的查找 table 不是很大,并且您不介意为每个现有行设置默认值。)
当您需要从查找中删除一行时,困难就来了 table ...您如何记录删除它的用户的 ID?在这种情况下,您还需要一个列来记录该行已被删除,可能 DELETE_FLAG
:
ALTER TABLE my_lookup_table
ADD delete_flag CHAR(1) DEFAULT 'N' NOT NULL;
然后,在您的更新触发器中,不要在 DELETE_FLAG = 'Y'
:
CREATE OR REPLACE TRIGGER record_update
AFTER UPDATE OF my_lookup_table
FOR EACH ROW
WHEN (new.delete_flag <> 'Y')
当您的应用执行删除操作时,您实际上需要先更新再删除:
<cftransaction>
<cfquery name="update_before_delete_lookup">
UPDATE my_lookup_table
SET update_user_id = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#user_id#" />
, delete_flag = 'Y'
WHERE <conditions>
</cfquery>
<cfquery name="delete_lookup">
DELETE FROM my_lookup_table
WHERE <conditions>
</cfquery>
</cftransaction>