Sql 是否有人尝试使用intersect表而不是oracle apex值列表的存储方法

Sql 是否有人尝试使用intersect表而不是oracle apex值列表的存储方法,sql,oracle,oracle-apex,Sql,Oracle,Oracle Apex,如您所知,ApEx通过使用“:”分隔值,将值的多个选择列表存储在一列中,如下所示 qwe:rty:yui:opa:sdf:ghj 但这不是数据库应该如何工作的,应该有一个带有外键的中间表。 所以我的问题是,有没有人试图用正确的方法来做这件事,或者我只是坚持ApEx的方法?如果是这样,是否就没有出错的风险? 我对apex不是很有经验,所以我仍然不知道如何同时插入到两个表中,如果有人能告诉我如何自己找到解决方案。据我所知,要么使用apex提供的冒号分隔的值列表,要么发明自己的解决方案 我不知道他们

如您所知,ApEx通过使用“:”分隔值,将值的多个选择列表存储在一列中,如下所示

qwe:rty:yui:opa:sdf:ghj
但这不是数据库应该如何工作的,应该有一个带有外键的中间表。 所以我的问题是,有没有人试图用正确的方法来做这件事,或者我只是坚持ApEx的方法?如果是这样,是否就没有出错的风险?
我对apex不是很有经验,所以我仍然不知道如何同时插入到两个表中,如果有人能告诉我如何自己找到解决方案。

据我所知,要么使用apex提供的冒号分隔的值列表,要么发明自己的解决方案

我不知道他们为什么选择那样做,但是是的,这很烦人。您无法将这些值正确地存储到表中,无法强制引用完整性约束,在编写报告时遇到问题,因为我们通常存储ID和显示名称,因此必须将列转换为行;并不是说你做不到,只是说


由于我没有太多的多选项,我有点喜欢我所拥有的,但我不喜欢。

多选中的值在APEX中被视为冒号分隔的列表,但您在存储数据方面拥有所有想要的自由。没有对多选择的内置支持,可能是因为有很多方法可以在后端实现多选择,但自己实现逻辑并不太难

请允许我举例说明。有一个表团队主键团队ID,其中包含一个子表成员主键成员ID和一个相交表团队成员主键团队成员ID-自动生成。 在团队表单中,有一个页面项P1_TEAM_MEMBERS,类型为select list,Allow Multi Selection设置为on。 这有两个部分:

在页面加载时将数据从intersect表获取到页面项中 在提交时处理数据。 第一部分很简单。创建一个计算,在SQL查询返回冒号分隔值类型的P1_团队_成员的表单初始化过程之后运行。这种类型的计算是专门为处理多重选择而创建的。来源可能是

SELECT member_id FROM team_members WHERE team_id = :P1_TEAM_ID
如果您想拥有更多的控制权,还可以使用类型SQL Query return single value和us LISTAGG将列转换为冒号分隔的字符串

2对于处理数据,您可以使用自动行处理过程之后要执行的应用程序处理。这是因为如果要创建一个包含成员的新团队,则在我们的主表中需要主键值P1_TEAM。在我的代码中,我使用了另一个页面项P1\u TEAM\u MEMBERS\u旧THA具有团队成员的原始值。它还有一个以冒号分隔的字符串,它是在这个页面处理之前计算出来的。 plsql API apex_字符串提供了许多非常有用的函数。apex_string.split接受带有分隔符的字符串,并将其转换为pl/sql集合。 使用MULTISET可识别新旧值之间的差异

DECLARE
  l_old_team_members apex_t_varchar2;
  l_new_team_members apex_t_varchar2;
  l_members_added apex_t_varchar2;
  l_members_removed apex_t_varchar2;
BEGIN
  l_old_team_members := apex_string.split(:P1_MEMBERS_OLD,':');
  l_new_team_members := apex_string.split(:P1_MEMBERS,':');
  l_members_added := l_new_team MULTISET EXCEPT l_old_team;
  l_members_removed := l_old_team MULTISET EXCEPT l_new_team;
  -- add new team members
  FOR i IN 1 .. l_members_added.COUNT LOOP
    INSERT INTO team_members(team_id, member_id)
      VALUES (:P1_TEAM_ID,l_members_added(i));
  END LOOP;
  -- delete removed team members
  FOR i IN 1 .. l_members_removed.COUNT LOOP
    DELETE FROM team_members WHERE team_id = :P1_TEAM_ID AND member_id = l_members_removed(i);
  END LOOP;
END;

这段代码的缺点是没有现成的丢失更新检测,但如果需要的话,可以手动实现。

同样,我在某些情况下尝试添加一个动态操作,获取值并将其插入表中,但必须在另一个模式对话框页中完成,这不是一个非常优雅的解决方案,所以我很少使用它。让我们希望oracle在未来提供更好的解决方案:-感谢您的回答,这很有帮助,但您所说的没有丢失的更新检测是什么意思如果我可以问一下,如果您使用开箱即用的表单区域,那么您已经丢失了更新检测。用户A打开第1行的表单并去喝咖啡。用户B打开第1行的表单并更改数据。他救了我。当用户A现在将保存其数据时,用户B的更改将被覆盖。这是一个丢失的更新。如果更新检测丢失,则用户A将收到一条错误消息,指示在进行更改时更改的数据。