cdu*_*dub 1 mysql oracle plsql
我正在使用几个表来处理数据库.他们是一个
districts table
PK district_id
student_data table
PK study_id
FK district_id
ga_data table
PK study_id
district_id
Run Code Online (Sandbox Code Playgroud)
ga_data表是我正在添加的数据.school_data表和ga_data都有130万条记录.两个表之间的study_id是1比1,但是ga_data.district_id是NULL并且需要更新.我在使用以下PL/SQL时遇到问题:
update ga_data
set district_id = (select district_id from student_data
where student_data.study_id = ga_data.study_id)
where ga_data.district_id is null and rownum < 100;
Run Code Online (Sandbox Code Playgroud)
我需要逐步增加,这就是为什么我需要rownum.但我正确使用它吗?在多次运行查询之后,它只更新了大约8,000条记录中的130万条记录(应该是大约110万条更新,因为在student_data中某些district_id为null).谢谢!
ROWNUM只是在前n行之后切断查询.您在STUDENT_DATA中有一些行,DISTRICT_ID为NULL.因此,经过多次运行后,您的查询可能会陷入困境,返回相同的100条QA_DATA记录,所有这些记录都与那些讨厌的STUDENT_DATA行匹配.
因此,您需要一些机制来确保您逐步通过QA_DATA表.标志列将是一个解决方案.对查询进行分区以使其命中另一组STUDENT_ID是另一种.
目前尚不清楚为什么必须以100个批量执行此操作,但最简单的方法可能是使用BULK PROCESSING(至少在Oracle中:这种PL/SQL语法在MySQL中不起作用).
这是一些测试数据:
SQL> select district_id, count(*)
2 from student_data
3 group by district_id
4 /
DISTRICT_ID COUNT(*)
----------- ----------
7369 192
7499 190
7521 192
7566 190
7654 192
7698 191
7782 191
7788 191
7839 191
7844 192
7876 191
7900 192
7902 191
7934 192
8060 190
8061 193
8083 190
8084 193
8085 190
8100 193
8101 190
183
22 rows selected.
SQL> select district_id, count(*)
2 from qa_data
3 group by district_id
4 /
DISTRICT_ID COUNT(*)
----------- ----------
4200
SQL>
Run Code Online (Sandbox Code Playgroud)
此匿名块使用批量处理LIMIT子句将结果集批处理为100行的块.
SQL> declare
2 type qa_nt is table of qa_data%rowtype;
3 qa_recs qa_nt;
4
5 cursor c_qa is
6 select qa.student_id
7 , s.district_id
8 from qa_data qa
9 join student_data s
10 on (s.student_id = qa.student_id);
11 begin
12 open c_qa;
13
14 loop
15 fetch c_qa bulk collect into qa_recs limit 100;
16 exit when qa_recs.count() = 0;
17
18 for i in qa_recs.first()..qa_recs.last()
19 loop
20 update qa_data qt
21 set qt.district_id = qa_recs(i).district_id
22 where qt.student_id = qa_recs(i).student_id;
23 end loop;
24
25 end loop;
26 end;
27 /
PL/SQL procedure successfully completed.
SQL>
Run Code Online (Sandbox Code Playgroud)
请注意,此构造允许我们在发出更新之前对所选行执行其他处理.如果我们需要以编程方式应用复杂的修复,这很方便.
如您所见,QA_DATA中的数据现在与STUDENT_DATA中的数据相匹配
SQL> select district_id, count(*)
2 from qa_data
3 group by district_id
4 /
DISTRICT_ID COUNT(*)
----------- ----------
7369 192
7499 190
7521 192
7566 190
7654 192
7698 191
7782 191
7788 191
7839 191
7844 192
7876 191
7900 192
7902 191
7934 192
8060 190
8061 193
8083 190
8084 193
8085 190
8100 193
8101 190
183
22 rows selected.
SQL>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1484 次 |
| 最近记录: |