我有一个名为 event 的表,并使用与事件相同的列和定义创建了另一个全局临时表 tmp_event 。是否可以使用此命令将事件中的记录插入tmp_event?
DECLARE
v_record event%rowtype;
BEGIN
Insert into tmp_event values v_record;
END;
事件表中有太多列,我想尝试这个,因为我不想列出所有列。
忘了提一下:我会在触发器中使用它,在EVENT表上插入后,这个v_record可以是:new 对象吗?
答案 0 :(得分:19)
要插入一行 -
DECLARE
v_record event%rowtype;
BEGIN
SELECT * INTO v_record from event where rownum=1; --or whatever where clause
Insert into tmp_event values v_record;
END;
或更精细的版本,以插入event
-
DECLARE
TYPE t_bulk_collect_test_tab IS TABLE OF event%ROWTYPE;
l_tab t_bulk_collect_test_tab;
CURSOR c_data IS
SELECT *
FROM event;
BEGIN
OPEN c_data;
LOOP
FETCH c_data
BULK COLLECT INTO l_tab LIMIT 10000;
EXIT WHEN l_tab.count = 0;
-- Process contents of collection here.
Insert into tmp_event values v_record;
END LOOP;
CLOSE c_data;
END;
/
在触发器中,是的,它可能,但它像鸡肉或鸡蛋。您必须使用rowtype
列值初始化:new
的每个字段,例如 -
v_record.col1 := :new.col1;
v_record.col2 := :new.col2;
v_record.col3 := :new.col3;
....
显然,上面的PLSQL示例不能在触发器中使用,因为它会引发变异触发器错误。如上所述,除了单独访问每个列之外,没有其他方法可以获取触发器中的整行,所以如果你这样做,为什么不直接在:new.col
本身使用INSERT into temp_event
,会为你节省很多工作。
此外,既然你说要提及所有列是很多工作,(在 Oracle 11gR2 中)这里有一个快速的方法,通过生成INSERT
语句并动态执行它(虽然未经过性能测试)。
CREATE OR REPLACE TRIGGER event_air --air stands for "after insert of row"
AFTER INSERT ON EVENT
FOR EACH ROW
L_query varchar2(2000); --size it appropriately
BEGIN
SELECT 'INSERT INTO tmp_event VALUES ('|| listagg (':new.'||column_name, ',')
WITHIN GROUP (ORDER BY column_name) ||')'
INTO l_query
FROM all_tab_columns
WHERE table_name='EVENT';
EXECUTE IMMEDIATE l_query;
EXCEPTION
WHEN OTHERS THEN
--Meaningful exception handling here
END;
答案 1 :(得分:2)
有一种方法可以使用%Rowtyp 将多行插入表中。
在下面的示例中结帐。
DECLARE
TYPE v_test IS TABLE OF TEST_TAB%rowtype;
v_test_tab v_test ;
EXECUTE immediate ' SELECT * FROM TEST_TAB ' bulk collect INTO v_test_tab ;
dbms_output.put_line('v_test_tab.count -->'||v_test_tab.count);
FOR i IN 1..v_test_tab.count
LOOP
INSERT INTO TEST_TAB_1 VALUES v_test_tab
(i
) ;
END LOOP;
END;
答案 2 :(得分:0)
总和就是完整的工作示例...
DECLARE
TYPE t_bulk_collect_test_tab IS TABLE OF event%ROWTYPE;
l_tab t_bulk_collect_test_tab;
CURSOR c_data IS SELECT * FROM event;
BEGIN
OPEN c_data;
LOOP
FETCH c_data
BULK COLLECT INTO l_tab LIMIT 10000;
EXIT WHEN l_tab.count = 0;
FORALL i IN 1..l_tab.count
Insert into tmp_event values l_tab(i);
commit;
END LOOP;
CLOSE c_data;
END;
/