如何在Oracle数据库的pl/sql过程中存储值
我想在循环迭代后将select查询中的值添加到某个变量/属性中。Java中类似Arraylist的值持有者 循环终止后,我需要删除变量/属性中的值 如何在pl/sql编程中实现这一点如何在Oracle数据库的pl/sql过程中存储值,oracle,plsql,Oracle,Plsql,我想在循环迭代后将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 /
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;
在这里,如果我删除存储的值,那么这些值也应该从实际表中删除。我通常建议不要使用嵌套循环,而是使用联接。 在您的示例中,它看起来有点像您希望使用关联数组并用大容量集合填充它:
由于您实际上不需要t_FEHLERFALL_SG表中的任何数据,因此您只需去掉进行单个选择的第一个循环(使用JOIN、EXISTS或IN,具体取决于您获取的数据) 还有一个重要的问题需要回答-在将数据插入阵列之前,是否需要执行任何逻辑?在清除数组之前,您计划如何处理数组中存储的值 无论如何,这里有一些您可能会觉得有用的选项(另外,我使用了声明的游标,因为它提供了更好的代码可读性,并且据我所知,它由优化器更好地管理,并且可以被重用,可以快速从中获取结果—您还可以阅读关于和的内容)
您将如何处理这些存储值?另外,如果您绝对必须执行循环游标(又称逐行处理,又称慢对慢)处理,为什么要执行循环嵌套游标?您意识到您刚刚重新发明了嵌套循环联接吗?最好将两个SQL语句合并为一个,让优化器计算出最佳连接路径!
...
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;
...
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;
/