Copy Table from HR to Change It
CREATE TABLE employees
AS
SELECT * FROM hr.employees
Table created.
Silly Little Helper Function
CREATE OR REPLACE FUNCTION table_count (
table_name_in IN all_tables.table_name%TYPE,
where_in IN VARCHAR2 DEFAULT NULL)
RETURN PLS_INTEGER
AUTHID CURRENT_USER
IS
l_table_name all_tables.table_name%TYPE;
l_return PLS_INTEGER;
BEGIN
l_table_name := sys.DBMS_ASSERT.sql_object_name (table_name_in);
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM ' || table_name_in || ' WHERE ' || where_in
INTO l_return;
RETURN l_return;
END;
Function created.
Can't Bind Column Names
CREATE OR REPLACE PROCEDURE set_to_10000 (col_in IN VARCHAR2,
department_id_in IN PLS_INTEGER)
IS
l_update CONSTANT VARCHAR2 (1000) :=
'UPDATE employees SET :colname = 10000
WHERE department_id = :dept';
BEGIN
EXECUTE IMMEDIATE l_update USING col_in, department_id_in;
DBMS_OUTPUT.put_line ('Rows updated: ' || TO_CHAR (SQL%ROWCOUNT));
END;
Procedure created.
Can't Bind Column Names - In Action
BEGIN
set_to_10000 ('salary', 50);
/* ORA-01747: invalid user.table.column, table.column, or column specification */
END;
ORA-01747: invalid user.table.column, table.column, or column specification ORA-06512: at "SQL_ZMXEDLYQPZKPQGLNZCWHRGSTM.SET_TO_10000", line 8 ORA-06512: at line 2 ORA-06512: at "SYS.DBMS_SQL", line 1721More Details: https://docs.oracle.com/error-help/db/ora-01747
Bind Single Variable
CREATE OR REPLACE PROCEDURE set_to_10000 (col_in IN VARCHAR2,
department_id_in IN PLS_INTEGER)
IS
l_update VARCHAR2 (1000)
:= 'UPDATE employees SET '
|| col_in
|| ' = 10000
WHERE department_id = :dept';
BEGIN
EXECUTE IMMEDIATE l_update USING department_id_in;
DBMS_OUTPUT.put_line ('Rows updated: ' || TO_CHAR (SQL%ROWCOUNT));
END;
Procedure created.
BEGIN
DBMS_OUTPUT.put_line (
'Before '
|| table_count ('employees',
'department_id = 50 AND salary = 10000'));
set_to_10000 ('salary', 50);
DBMS_OUTPUT.put_line (
'After '
|| table_count ('employees',
'department_id = 50 AND salary = 10000'));
ROLLBACK;
END;
Before 0
Rows updated: 45
After 45
Multiple Placeholders, Different Names
CREATE OR REPLACE PROCEDURE updnumval (col_in IN VARCHAR2,
department_id_in IN PLS_INTEGER,
val_in IN NUMBER)
IS
l_update VARCHAR2 (1000)
:= 'UPDATE employees SET '
|| col_in
|| ' = :val
WHERE department_id = :dept';
BEGIN
EXECUTE IMMEDIATE l_update USING val_in, department_id_in;
DBMS_OUTPUT.put_line ('Rows updated: ' || TO_CHAR (SQL%ROWCOUNT));
END;
Procedure created.
BEGIN
DBMS_OUTPUT.put_line (
'Before '
|| table_count ('employees',
'department_id = 50 AND salary = 10000'));
updnumval ('salary', 50, 10000);
DBMS_OUTPUT.put_line (
'After '
|| table_count ('employees',
'department_id = 50 AND salary = 10000'));
ROLLBACK;
END;
Before 0
Rows updated: 45
After 45
Three Placeholders, Repeating Names
CREATE OR REPLACE PROCEDURE updnumval (col_in IN VARCHAR2,
department_id_in IN PLS_INTEGER,
val_in IN NUMBER)
IS
l_update VARCHAR2 (1000)
:= 'UPDATE employees SET '
|| col_in
|| ' = :val
WHERE department_id = :dept and :val IS NOT NULL';
BEGIN
EXECUTE IMMEDIATE l_update USING val_in, department_id_in, val_in;
DBMS_OUTPUT.put_line ('Rows updated: ' || TO_CHAR (SQL%ROWCOUNT));
END;
Procedure created.
BEGIN
DBMS_OUTPUT.put_line (
'Before '
|| table_count ('employees',
'department_id = 50 AND salary = 10000'));
updnumval ('salary', 50, 10000);
DBMS_OUTPUT.put_line (
'After '
|| table_count ('employees',
'department_id = 50 AND salary = 10000'));
ROLLBACK;
END;
Before 0
Rows updated: 45
After 45