重构没有光标的代码 PL/SQL
Refactor code without cursor PL/SQL
如何在不使用 CURSOR
的情况下重构这些代码行?
我是 PL/SQL 的初学者。
任何帮助,将不胜感激。谢谢
DECLARE
CURSOR c_emps IS
SELECT employee_id
FROM bonus;
v_region HR.REGIONS.region_name%TYPE;
v_salary hr.employees.salary%TYPE;
BEGIN
FOR r_emps IN c_emps LOOP
SELECT reg.region_name, emp.salary
INTO v_region, v_salary
FROM hr.employees emp,
hr.departments dep,
hr.Locations loc,
hr.countries cot,
hr.regions reg
WHERE emp.department_id = dep.department_id AND
dep.location_id = loc.location_id AND
loc.country_id = cot.country_id AND
cot.region_id = reg.region_id AND
employee_id = r_emps.employee_id;
IF v_region = 'Europe' THEN
UPDATE bonus
SET bonus = bonus + (v_salary * .01)
WHERE employee_id = r_emps.employee_id;
ELSE
UPDATE bonus
SET bonus = v_salary * .01
WHERE employee_id = r_emps.employee_id;
END IF;
END LOOP;
COMMIT;
END;
/
CURSOR c_emps IS
SELECT employee_id
FROM bonus;
您不需要显式声明 CURSOR。您可以在 CURSOR FOR LOOP 本身中执行此操作:
FOR r_emps IN (SELECT employee_id FROM bonus)
LOOP
如果 PL/SQL 不是强制性的,那么您可以使用 SQL SQL UPDATE 语句中的 24=]CASE 表达式。
有点像,
UPDATE bonus
SET bonus =
CASE
WHEN region = 'Europe'
THEN bonus + (v_salary * .01)
ELSE v_salary * .01
...
and so on
是的,您需要将整个 PL/SQL 代码重写为 SQL 更新语句。但是,它会更好更快。 for循环是逐行处理,因此是慢-慢。如果可以在 SQL.
中执行相同操作,请避免使用 PL/SQL
在使用 SQL 服务器时,需要付出大量努力来避免游标,因为游标的处理非常糟糕。在 SQL 服务器中使用光标就像在糖蜜中苦苦挣扎。 Oracle 更好地处理游标,因此您可以在 Oracle 中看到更多的逐行工作。太多了,真的。即使在 Oracle 中,如果某些事情可以用单个 SQL 语句完成,它也比使用 PL/SQL 游标和循环要好得多。
不幸的是,Oracle 不允许在 UPDATE
语句中加入。但不用担心,MERGE
声明是最近的创新。
MERGE INTO BONUS B
USING(
SELECT EMP.EMPLOYEE_ID, EMP.SALARY, REG.REGION_NAME
FROM HR.EMPLOYEES EMP
JOIN HR.DEPARTMENTS DEP
ON DEP.DEPARTMENT_ID = EMP.DEPARTMENT_ID
JOIN HR.LOCATIONS LOC
ON LOC.LOCATION_ID = DEP.LOCATION_ID
JOIN HR.COUNTRIES COT
ON COT.COUNTRY_ID = LOC.COUNTRY_ID
JOIN HR.REGIONS REG
ON REG.REGION_ID = COT.REGION_ID ) U
ON( U.EMPLOYEE_ID = b.EMPLOYEE_ID )
WHEN MATCHED THEN
UPDATE SET B.BONUS =( u.SALARY * 0.01 ) +
CASE U.REGION_NAME WHEN 'Europe' THEN B.BONUS ELSE 0 END;
不需要 when not matched
子句真是太好了,有效地将 merge
变成了非常灵活的 update
。
如何在不使用 CURSOR
的情况下重构这些代码行?
我是 PL/SQL 的初学者。
任何帮助,将不胜感激。谢谢
DECLARE
CURSOR c_emps IS
SELECT employee_id
FROM bonus;
v_region HR.REGIONS.region_name%TYPE;
v_salary hr.employees.salary%TYPE;
BEGIN
FOR r_emps IN c_emps LOOP
SELECT reg.region_name, emp.salary
INTO v_region, v_salary
FROM hr.employees emp,
hr.departments dep,
hr.Locations loc,
hr.countries cot,
hr.regions reg
WHERE emp.department_id = dep.department_id AND
dep.location_id = loc.location_id AND
loc.country_id = cot.country_id AND
cot.region_id = reg.region_id AND
employee_id = r_emps.employee_id;
IF v_region = 'Europe' THEN
UPDATE bonus
SET bonus = bonus + (v_salary * .01)
WHERE employee_id = r_emps.employee_id;
ELSE
UPDATE bonus
SET bonus = v_salary * .01
WHERE employee_id = r_emps.employee_id;
END IF;
END LOOP;
COMMIT;
END;
/
CURSOR c_emps IS SELECT employee_id FROM bonus;
您不需要显式声明 CURSOR。您可以在 CURSOR FOR LOOP 本身中执行此操作:
FOR r_emps IN (SELECT employee_id FROM bonus)
LOOP
如果 PL/SQL 不是强制性的,那么您可以使用 SQL SQL UPDATE 语句中的 24=]CASE 表达式。
有点像,
UPDATE bonus
SET bonus =
CASE
WHEN region = 'Europe'
THEN bonus + (v_salary * .01)
ELSE v_salary * .01
...
and so on
是的,您需要将整个 PL/SQL 代码重写为 SQL 更新语句。但是,它会更好更快。 for循环是逐行处理,因此是慢-慢。如果可以在 SQL.
中执行相同操作,请避免使用 PL/SQL在使用 SQL 服务器时,需要付出大量努力来避免游标,因为游标的处理非常糟糕。在 SQL 服务器中使用光标就像在糖蜜中苦苦挣扎。 Oracle 更好地处理游标,因此您可以在 Oracle 中看到更多的逐行工作。太多了,真的。即使在 Oracle 中,如果某些事情可以用单个 SQL 语句完成,它也比使用 PL/SQL 游标和循环要好得多。
不幸的是,Oracle 不允许在 UPDATE
语句中加入。但不用担心,MERGE
声明是最近的创新。
MERGE INTO BONUS B
USING(
SELECT EMP.EMPLOYEE_ID, EMP.SALARY, REG.REGION_NAME
FROM HR.EMPLOYEES EMP
JOIN HR.DEPARTMENTS DEP
ON DEP.DEPARTMENT_ID = EMP.DEPARTMENT_ID
JOIN HR.LOCATIONS LOC
ON LOC.LOCATION_ID = DEP.LOCATION_ID
JOIN HR.COUNTRIES COT
ON COT.COUNTRY_ID = LOC.COUNTRY_ID
JOIN HR.REGIONS REG
ON REG.REGION_ID = COT.REGION_ID ) U
ON( U.EMPLOYEE_ID = b.EMPLOYEE_ID )
WHEN MATCHED THEN
UPDATE SET B.BONUS =( u.SALARY * 0.01 ) +
CASE U.REGION_NAME WHEN 'Europe' THEN B.BONUS ELSE 0 END;
不需要 when not matched
子句真是太好了,有效地将 merge
变成了非常灵活的 update
。