我想在循环迭代后将select查询中的值添加到某个变量/属性。像Java中的Arraylist这样的价值持有者。
循环终止后,我需要删除变量/属性中的值。
如何在pl / sql编程中实现这一点。
FOR FEH IN (SELECT ID FROM T_FEH_SG WHERE ZESG_ID IS NOT NULL) LOOP
FOR UWBFEH IN (SELECT * FROM T_GRPN_J_FERF WHERE FEH_ID = FEH.ID) LOOP
// Here some code to add values from select query based on some conditions
END LOOP;
// Here I need to delete the added values.
END LOOP;
如果我删除存储的值,那么也应该从实际表中删除这些值。
答案 0 :(得分:1)
我通常建议不要使用嵌套循环,而是使用连接。 在您的示例中,它看起来有点像您希望使用关联数组并使用批量收集填充它:
...
TYPE T_myTable IS TABLE OF T_UWB_GRUPPEN_J_FEHLERF%ROWTYPE INDEX BY PLS_INTEGER;
myTable T_myTable;
...
FOR FEH IN (SELECT ID FROM T_FEHLERFALL_SG WHERE ZESG_ID IS NOT NULL) LOOP
-- select into table
SELECT * BULK COLLECT INTO myTable FROM T_UWB_GRUPPEN_J_FEHLERF WHERE FEHLERF_ID = FEH.ID;
...
-- delete table
myTable.DELETE;
END LOOP;
...
答案 1 :(得分:1)
由于您实际上不需要来自T_FEHLERFALL_SG表的任何数据,您可以摆脱第一个循环进行单个SELECT(使用JOIN,EXISTS或IN,具体取决于您要获取的数据)。
还有一个重要的问题需要回答 - 在将数据插入数组之前是否需要执行任何逻辑?在清除之前,您打算如何处理存储在数组中的值?
无论如何,这里有一些你可能会觉得有用的选项(同样,我使用了声明的CURSOR,因为它提供了更好的代码可读性,据我所知,它更好地由优化器管理,可以快速重用获取结果来自SGA - 您还可以阅读Result cache和Oracle Concepts - SGA)。
DECLARE
TYPE t_uwbfeh_tab IS TABLE OF T_UWB_GRUPPEN_J_FEHLERF%ROWTYPE INDEX BY PLS_INTEGER; -- empirically learned (and from our DB Oracle consultant) arrays indexed by PL/SQL types (especially PLS_INTEGER) react noticeably faster even for a ~1k-element arrays
-- declare the PL/SQL TABLE variable and initialize it
l_uwbfeh_arr t_uwbfeh_tab := NEW t_uwbfeh_tab();
CURSOR c_fetch_data
SELECT
UWBFEH.*
FROM
T_FEHLERFALL_SG FEH
,T_UWB_GRUPPEN_J_FEHLERF UWBFEH
WHERE
FEH.ZESG_ID IS NOT NULL
AND FEH.ID = UWBFEH.FEHLERF_ID;
BEGIN
-- If you don't need to do anything with the data in the array before inserting it into the array
OPEN c_fetch_data;
FETCH c_fetch_data BULK COLLECT INTO l_uwbfeh_arr;
CLOSE c_fetch_data;
-- If you really need to do some logic not doable with the 'smart' select statement
FOR UWBFEH IN c_fetch_data
LOOP
-- extend an array - let it store one more value
l_uwbfeh_arr.EXTEND;
-- do some logic with your values (here I just print out the FEHLERF_ID)
DBMS_OUTPUT.PUT_LINE('FEHLERF_ID: ' || UWBFEH.FEHLERF_ID);
-- insert the value into the array
l_uwbfeh_arr(l_uwbfeh_arr.LAST) := UWBFEH;
END LOOP;
-- If you need to do something with the data fetched in the array
IF l_uwbfeh_arr.COUNT > 0 THEN
FOR idx IN l_uwbfeh_arr.FIRST .. l_uwbfeh_arr.LAST
LOOP
-- access the rows as follows (here I just print out the FEHLERF_ID)
DBMS_OUTPUT.PUT_LINE('FEHLERF_ID: ' || l_uwbfeh_arr(idx).FEHLERF_ID);
END LOOP;
END IF;
-- If you don't actually need any data to be stored in the array and need to manipulate only on the fetched rows
-- you could skip fetching the data into the array and execute the logic in the following loop
FOR UWBFEH IN c_fetch_data
LOOP
-- here do the logic (here I just print out the FEHLERF_ID)
DBMS_OUTPUT.PUT_LINE('FEHLERF_ID: ' || UWBFEH.FEHLERF_ID);
END LOOP;
-- to delete all the data stored in the array, simply use the following line of code
l_uwbfeh_arr.DELETE;
END;
/