I den här handledningen ger jag ett exempel på ett Oracle PL/SQL-program för att demonstrera dynamisk SQL med EXECUTE IMMEDIATE-satsen.
Oracle PL/SQL UTFÖR OMEDELBART Dynamisk SQL-exempel
Följande PL/SQL-procedur kommer att uppdatera posten i tabellen Anställda för ett anställd-ID om ett värde skiljer sig från det faktiska värdet.
Update-satsen kommer att förberedas dynamiskt med hjälp av en sträng, och sedan kommer den att exekveras med EXECUTE IMMEDIATE-satsen. SQL-satsen kommer endast att göras för de parametrar som passerats och som har nya värden.
Till exempel, om du vill uppdatera förnamnet och lönen för den anställde, skicka sedan värdena för parametern i_id, first_name och i_salary, viloparametern kan vara null. Uppdateringssatsen kommer endast att genereras för dessa kolumner.
CREATE OR REPLACE PROCEDURE update_emp_rec (
i_id IN employees.employee_id%TYPE,
i_first IN employees.first_name%TYPE,
i_last IN employees.last_name%TYPE,
i_email IN employees.email%TYPE,
i_phone IN employees.phone_number%TYPE,
i_job IN employees.job_id%TYPE,
i_salary IN employees.salary%TYPE,
i_commission_pct IN employees.commission_pct%TYPE,
i_manager_id IN employees.manager_id%TYPE,
i_department_id IN employees.department_id%TYPE)
AS
emp_upd_rec employees%ROWTYPE;
sql_string VARCHAR2 (1000);
set_count NUMBER := 0;
BEGIN
SELECT *
INTO emp_upd_rec
FROM employees
WHERE employee_id = i_id;
sql_string := 'UPDATE EMPLOYEES SET ';
IF i_first != emp_upd_rec.first_name
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', FIRST_NAME =''' || i_first || '''';
ELSE
sql_string := sql_string || ' FIRST_NAME =''' || i_first || '''';
set_count := set_count + 1;
END IF;
END IF;
IF i_last != emp_upd_rec.last_name
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', LAST_NAME =''' || i_last || '''';
ELSE
sql_string := sql_string || ' LAST_NAME =''' || i_last || '''';
set_count := set_count + 1;
END IF;
END IF;
IF UPPER (i_email) != emp_upd_rec.email
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', EMAIL =''' || UPPER (i_email) || '''';
ELSE
sql_string := sql_string || ' EMAIL =''' || UPPER (i_email) || '''';
set_count := set_count + 1;
END IF;
END IF;
IF UPPER (i_phone) != emp_upd_rec.phone_number
THEN
IF set_count > 0
THEN
sql_string :=
sql_string || ', PHONE_NUMBER =''' || UPPER (i_phone) || '''';
ELSE
sql_string :=
sql_string || ' PHONE_NUMBER =''' || UPPER (i_phone) || '''';
set_count := set_count + 1;
END IF;
END IF;
IF i_job != emp_upd_rec.job_id
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', JOB_ID =''' || i_job || '''';
ELSE
sql_string := sql_string || ' JOB_ID =''' || i_job || '''';
set_count := set_count + 1;
END IF;
END IF;
IF i_salary != emp_upd_rec.salary
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', SALARY =' || i_salary;
ELSE
sql_string := sql_string || ' SALARY =' || i_salary;
set_count := set_count + 1;
END IF;
END IF;
IF i_commission_pct != emp_upd_rec.commission_pct
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', COMMISSION_PCT =' || i_commission_pct;
ELSE
sql_string := sql_string || ' COMMISSION_PCT =' || i_commission_pct;
set_count := set_count + 1;
END IF;
END IF;
IF i_manager_id != emp_upd_rec.manager_id
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', MANAGER_ID =' || i_manager_id;
ELSE
sql_string := sql_string || ' MANAGER_ID =' || i_manager_id;
set_count := set_count + 1;
END IF;
END IF;
IF i_department_id != emp_upd_rec.department_id
THEN
IF set_count > 0
THEN
sql_string := sql_string || ', DEPARTMENT_ID =' || i_department_id;
ELSE
sql_string := sql_string || ' DEPARTMENT_ID =' || i_department_id;
set_count := set_count + 1;
END IF;
END IF;
sql_string := sql_string || ' WHERE employee_id = ' || i_id;
IF set_count > 0
THEN
DBMS_OUTPUT.put_Line (sql_string);
EXECUTE IMMEDIATE sql_string;
ELSE
DBMS_OUTPUT.PUT_LINE (
'No update needed, ' || 'all fields match original values');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE ('No matching employee found');
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE( 'Data entry error has occurred, '
|| 'please check values and try again'
|| sql_string);
END;
/ Kör proceduren
Följande är PL/SQL-koden för att utföra proceduren ovan för att uppdatera förnamnet och lönen för anställd-ID 199.
SET SERVEROUTPUT ON;
DECLARE
I_ID NUMBER;
I_FIRST VARCHAR2 (20);
I_LAST VARCHAR2 (25);
I_EMAIL VARCHAR2 (25);
I_PHONE VARCHAR2 (20);
I_JOB VARCHAR2 (10);
I_SALARY NUMBER;
I_COMMISSION_PCT NUMBER;
I_MANAGER_ID NUMBER;
I_DEPARTMENT_ID NUMBER;
BEGIN
I_ID := 199;
I_FIRST := 'Joseph';
I_LAST := NULL;
I_EMAIL := NULL;
I_PHONE := NULL;
I_JOB := NULL;
I_SALARY := 3099;
I_COMMISSION_PCT := NULL;
I_MANAGER_ID := NULL;
I_DEPARTMENT_ID := NULL;
UPDATE_EMP_REC (I_ID,
I_FIRST,
I_LAST,
I_EMAIL,
I_PHONE,
I_JOB,
I_SALARY,
I_COMMISSION_PCT,
I_MANAGER_ID,
I_DEPARTMENT_ID);
COMMIT;
END;
/ Utdata
UPDATE EMPLOYEES SET FIRST_NAME ='Joseph', SALARY =3099 WHERE employee_id = 199 PL/SQL procedure successfully completed.
Se även:
- Hur trunkerar man tabell i Oracle-proceduren?
- Oracle Dynamic SQL-exempel för att infoga en post med DBMS_SQL
- Hur skriver man ut 1 till 10 utan att använda Loop i PL/SQL?