从Web应用程序设置Oracle会话变量是将Web应用程序中的值传递给触发器的可靠方法吗?

时间:2015-02-04 19:30:14

标签: oracle session coldfusion oracle10g coldfusion-9

我在Oracle 10g中有一个查找表,其中包含一个触发器,用于在插入,更新和删除时填充历史表。我希望能够通过触发器从历史记录表中的ColdFusion应用程序中捕获用户ID。

我发现这样做的一种可能方法是使用Oracle会话变量: 在coldfusion代码中,我在插入,更新和删除代码之前将用户ID传递给Oracle会话:

CALL dbms_session.set_identifier(12345);

在触发器中,我读取了client_identifier var,交换了" 0"如果为null。

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 session var中的值多个同时用户将不可靠。

从Web应用程序设置Oracle会话变量是将Web应用程序中的值传递给触发器的可靠方法吗?

1 个答案:

答案 0 :(得分:1)

假设您没有执行上面概述的内容(我认为这样做不可行),您可以在查找表中添加一列(让我们称之为MY_LOOKUP_TABLE)在其中存储进行更新(或插入)的用户的用户ID:

ALTER TABLE my_lookup_table
  ADD update_user_id NUMBER DEFAULT 0 NOT NULL;

(假设您的查找表不是很大,并且您不介意为每个现有行设置默认值。)

当你需要从查找表中删除一行时出现困难...你如何记录删除它的用户的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>