【问题标题】:how to get values from report corresponding to check boxes which are checked in oracle apex如何从报告中获取与在 oracle apex 中选中的复选框相对应的值
【发布时间】:2015-04-29 10:07:11
【问题描述】:

在apex中通过sql命令获取报告后,我想存储变量sid,serial#对应于选中的复选框的数据。之后我必须在 apex 本身中执行 alter system kill session 'sid,serial#'

【问题讨论】:

    标签: oracle-apex


    【解决方案1】:

    您好,我将在this 教程中向您展示skillbuilders 使用的方法,该教程基于collections

    该方法包括四个步骤,其想法是根据集合而不是从一组表中生成报告。我将对所有步骤进行描述,但我强烈建议您查看上面链接中的视频,了解代码的具体细节。

    首先您需要使用您提供的信息创建集合(并为其命名) 想要显示在您的报告中,为此您将使用查询本身创建一个字符串,然后绑定您可能(或可能不需要)需要的变量。这是您收藏的模板,请记住,此模板需要根据您的场景进行调整。 在您的情况下,您最感兴趣的是项目 #47 和 #50,这是一个状态字段 (47) 和一个复选框字段 (50)。

    DECLARE
    
       l_collection_name APEX_COLLECTIONS.COLLECTION_NAME%TYPE;
       l_bind_names      APEX_APPLICATION_GLOBAL.VC_ARR2;
       l_bind_values     APEX_APPLICATION_GLOBAL.VC_ARR2;
       l_query           VARCHAR2(32767);
    
    BEGIN
    
       l_collection_name := 'REPLACE_NAME';
    
       IF apex_collection.collection_exists(l_collection_name)
       THEN
          apex_collection.delete_collection(
             p_collection_name => l_collection_name
          );
       END IF;
    
       --Query to initialize collection
       --Do not reorder columns later as that could break the values in the tabular form (reorder in report)
       l_query :=
             'SELECT col_1, ' --c001 => f01
          || '   col_2, ' --c002 => f02
          || '   col_3, ' --c003 => f03
          || '   col_4, ' --c004 => f04
          || '   col_5, ' --c005 => f05
          || '   NULL, ' --c006 => f06
          || '   NULL, ' --c007 => f07
          || '   NULL, ' --c008 => f08
          || '   NULL, ' --c009 => f09
          || '   NULL, ' --c010 => f10
          || '   NULL, ' --c011 => f11
          || '   NULL, ' --c012 => f12
          || '   NULL, ' --c013 => f13
          || '   NULL, ' --c014 => f14
          || '   NULL, ' --c015 => f15
          || '   NULL, ' --c016 => f16
          || '   NULL, ' --c017 => f17
          || '   NULL, ' --c018 => f18
          || '   NULL, ' --c019 => f19
          || '   NULL, ' --c020 => f20
          || '   NULL, ' --c021 => f21
          || '   NULL, ' --c022 => f22
          || '   NULL, ' --c023 => f23
          || '   NULL, ' --c024 => f24
          || '   NULL, ' --c025 => f25
          || '   NULL, ' --c026 => f26
          || '   NULL, ' --c027 => f27
          || '   NULL, ' --c028 => f28
          || '   NULL, ' --c029 => f29
          || '   NULL, ' --c030 => f30
          || '   NULL, ' --c031 => f31
          || '   NULL, ' --c032 => f32
          || '   NULL, ' --c033 => f33
          || '   NULL, ' --c034 => f34
          || '   NULL, ' --c035 => f35
          || '   NULL, ' --c036 => f36
          || '   NULL, ' --c037 => f37
          || '   NULL, ' --c038 => f38
          || '   NULL, ' --c039 => f39
          || '   NULL, ' --c040 => f40
          || '   NULL, ' --c041 => f41
          || '   NULL, ' --c042 => f42
          || '   NULL, ' --c043 => f43
          || '   NULL, ' --c044 => f44
          || '   NULL, ' --c045 => f45
          || '   NULL, ' --c046 => f46
          || '   ''O'', ' --c047 (for record status)
          || '   wwv_flow_item.md5(col_1, col_2, col_3, col_4, col_5) ' --c048 (for optimistic locking)
          --c049 for (not used in collection/reserevered for seq_id array)
          --c050 (not used in collection/reservered for delete checkbox array)
          || 'FROM some_table '
          || 'WHERE some_col = :PXX_ITEM_NAME';
    
       l_bind_names(1) := 'PXX_ITEM_NAME';  
       l_bind_values(1) := v('PXX_ITEM_NAME'); 
    
       apex_collection.create_collection_from_query_b(
          p_collection_name => l_collection_name,
          p_query           => l_query,
          p_names           => l_bind_names,
          p_values          => l_bind_values
       );
    
       IF :REQUEST = 'ADD'
       THEN
          apex_collection.add_member(
             p_collection_name => l_collection_name
          );
       END IF;
    
    END;
    

    第二步 成功创建集合后,您可以通过直接查询集合来生成报告,并使用APEX_ITEM 包将此字段设置为适当的项目,请注意第五项是链接到集合中第 50 个字段的复选框。再一次,下面的代码只是一个例子:

    SELECT apex_item.hidden(47,c047,NULL,'f47_'|| '#ROWNUM#')
       || apex_item.hidden(48,c048,NULL,'f48_'|| '#ROWNUM#')
       || apex_item.hidden(49,seq_id,NULL,'f49_'|| '#ROWNUM#')
       || apex_item.hidden(1,c001,NULL,'f01_'|| '#ROWNUM#')
       || apex_item.checkbox(
          50, 
          seq_id,
          NULL,
          CASE 
             WHEN c047 = 'D' THEN seq_id
          END,
          ':',
          'f50_' || '#ROWNUM#'
       ) AS delete_checkbox,
       apex_item.text(
          2,
          c002,
          20,
          50,
          NULL,
          'f02_' || '#ROWNUM#'
       ) AS col_2,
       apex_item.text(
          3,
          c003,
          20,
          50,
          NULL,
          'f03_' || '#ROWNUM#'
       ) AS col_3,
       apex_item.select_list_from_lov_xl(
          4,
          NVL(c004, '-1'),
          'NAMED_LOV',
          NULL,
          'YES',
          '-1',
          '- Select Value -',
          'f04_' || '#ROWNUM#'
       ) AS col_4,
       apex_item.select_list_from_lov(
          5,
          NVL(c005, '-1'),
          'NAMED_LOV',
          NULL,
          'YES',
          '-1',
          '- Select Value -',
          'f05_' || '#ROWNUM#'
       ) AS col_5
    FROM apex_collections
    WHERE collection_name = 'REPLACE_NAME'
    ORDER BY c003
    

    第三步所以,现在您有一个集合显示可以在页面中修改的项目,但是更改会立即发布到集合中吗?...不,你需要先更新集合,因为你有这个代码,这里它处理更新、行创建和行删除。

    DECLARE
    
       l_collection_name APEX_COLLECTIONS.COLLECTION_NAME%TYPE;
       l_original_md5    VARCHAR2(32);
       l_latest_md5      VARCHAR2(32);
    
    BEGIN
    
       l_collection_name := 'REPLACE_NAME';
    
       FOR x IN 1 .. apex_application.g_f49.count 
       LOOP         
          IF apex_application.g_f01(x) IS NOT NULL --ID exists, check to see if record was updated
          THEN
             SELECT c048
             INTO l_original_md5
             FROM apex_collections
             WHERE collection_name = l_collection_name
                AND seq_id = apex_application.g_f49(x);
    
             l_latest_md5 := wwv_flow_item.md5(
                apex_application.g_f01(x),
                apex_application.g_f02(x),
                apex_application.g_f03(x),
                apex_application.g_f04(x),
                apex_application.g_f05(x)
             );
    
             IF l_original_md5 != l_latest_md5 
             THEN
                apex_collection.update_member(
                   p_collection_name => l_collection_name,
                   p_seq             => apex_application.g_f49(x),
                   p_c001            => apex_application.g_f01(x),
                   p_c002            => apex_application.g_f02(x),
                   p_c003            => apex_application.g_f03(x),
                   p_c004            => apex_application.g_f04(x),
                   p_c005            => apex_application.g_f05(x),
                   p_c047            => 'U',
                   p_c048            => apex_application.g_f48(x)
                );
             END IF;
          ELSE --ID does not exist, must be new record
             apex_collection.update_member(
                p_collection_name => l_collection_name,
                p_seq             => apex_application.g_f49(x),
                p_c001            => apex_application.g_f01(x),
                p_c002            => apex_application.g_f02(x),
                p_c003            => apex_application.g_f03(x),
                p_c004            => apex_application.g_f04(x),
                p_c005            => apex_application.g_f05(x),
                p_c047            => 'N',
                p_c048            => apex_application.g_f48(x)
             );
          END IF;
       END LOOP;
    
       IF :REQUEST = 'DELETE' 
       THEN
          FOR x IN 1 .. apex_application.g_f50.count 
          LOOP
             apex_collection.update_member_attribute(
                p_collection_name => l_collection_name, 
                p_seq             => apex_application.g_f50(x), 
                p_attr_number     => '47', 
                p_attr_value      => 'D'
             );
          END LOOP;
       END IF;
    
    END;
    

    最后第四步在这里,我们根据对集合所做的更改来更新表。使用第 47 个和第 50 个字段,我们知道应该更新、删除或创建哪些字段:

    DECLARE
    
       l_table_md5       VARCHAR2(32);
       l_collection_name APEX_COLLECTIONS.COLLECTION_NAME%TYPE;
       l_del_count       PLS_INTEGER := 0;
       l_upd_count       PLS_INTEGER := 0;
       l_ins_count       PLS_INTEGER := 0;
       l_success_message VARCHAR2(32767);
    
       CURSOR op_lock_check_cur (
          p_id IN NUMBER
       )
       IS
          SELECT wwv_flow_item.md5(col_1, col_2, col_3, col_4, col_5)
          FROM some_table
          WHERE col_1 = op_lock_check_cur.p_id
          FOR UPDATE;
    
    BEGIN
    
       l_collection_name := 'REPLACE_NAME';
    
       FOR x IN (
          SELECT *
          FROM apex_collections
          WHERE collection_name = l_collection_name
             AND c047 IN ('N','U','D')
       ) 
       LOOP
          IF x.c047 = 'N'
          THEN
             INSERT INTO some_table(
                col_1,
                col_2,            
                col_3, 
                col_4, 
                col_5
             ) VALUES (
                some_table_seq.nextval, 
                x.c002, 
                x.c003, 
                x.c004, 
                x.c005
             );
    
             l_ins_count := l_ins_count + 1;
          ELSIF x.c047 = 'U'
          THEN
             --Optimistic lock check
             --MD5 should be identical to collection initialization proc
             OPEN op_lock_check_cur(x.c001);
             FETCH op_lock_check_cur INTO l_table_md5;
    
             -- Compare the checksum values and if they are different, raise an error.
             IF l_table_md5 != x.c048 
             THEN
                raise_application_error( 
                   -20001,
                   'Current version of data in database has changed '
                   || 'since user initiated update process.'
                );
             END IF;
    
             UPDATE some_table
             SET col_2 = x.c002,
                col_3 = x.c003,
                col_4 = x.c004,
                col_5 = x.c005
             WHERE CURRENT OF op_lock_check_cur;
    
             CLOSE op_lock_check_cur;
    
             l_upd_count := l_upd_count + 1;
          ELSIF x.c047 = 'D'
          THEN
             DELETE FROM some_table
             WHERE col_1 = x.c001;
    
             l_del_count := l_del_count + 1;
          END IF;
       END LOOP;
    
       apex_collection.delete_collection(p_collection_name => l_collection_name);
    
       l_success_message :=  
          l_ins_count || ' rows inserted, ' ||
          l_upd_count || ' rows updated, ' ||
          l_del_count || ' rows deleted';
    
       :PX_SUCCESS_MESSAGE := l_success_message;
    
    END;
    

    就这些了,但是再从头到脚看一遍教程,有很多信息我不能在这里发布。

    免责声明:我不是 Skillbuilders 的代表,我对视频不拥有任何权利,也不会以任何方式宣传 Skillbuilders 的网页。我只是一个发现本教程很有用的程序员。

    【讨论】:

    • 实际上,我的问题是从行中检索 sid,serial#(对应于选中的复选框)并使用...终止会话。alter system kill session 'sid,serial#' in pl/sql 进程...请给我简要说明的解决方案
    • 这就是解决方案,如果您阅读它,您会意识到在第四步中您可以做您想做的事情,包括终止检查的会话。
    猜你喜欢
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多