通常应用程序应该验证用户的输入,以确保输入的内容是所希望的。
例,如果用户为delete语句传入部门编号,可以从departments表中做查询来验证输入的部门编号;
如果用户输入删除的表名,则可以查询all_tables来验证表名的存在。
在有效性检查代码中,DBMS_ASSERT包中的子程序是有用的。
可以使用DBMS_ASSERT.ENQUOTE函数来将字符串字面量使用引号括起来。这可以阻止恶意用户在开始和结束引号间注入文本。
-- 11g12_07_13.prc CREATE OR REPLACE PROCEDURE raise_emp_salary (column_value NUMBER, emp_column VARCHAR2, amount NUMBER) IS v_column VARCHAR2(30); sql_stmt VARCHAR2(200); BEGIN -- 检测输入的列名有效性 SELECT column_name INTO v_column FROM USER_TAB_COLS WHERE TABLE_NAME = 'EMPLOYEES' AND COLUMN_NAME = emp_column;
sql_stmt := 'UPDATE employees SET salary = salary + :b1 WHERE ' || DBMS_ASSERT.ENQUOTE_NAME(v_column, FALSE) || ' = :b2';
EXECUTE IMMEDIATE sql_stmt USING amount, column_value;
-- 如果列名有效 IF SQL%ROWCOUNT > 0 THEN DBMS_OUTPUT.PUT_LINE('更新列: ' || emp_column || ' = ' || column_value || '的员工薪水'); END IF;
-- 如果列名无效 EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE ('无效列: ' || emp_column); END raise_emp_salary;
--11g12_07_13.tst --测试前先查看相关的数据 SELECT employee_id, department_id, salary FROM employees WHERE employee_id = 112 OR department_id = 110;
DECLARE plsql_block VARCHAR2(500); BEGIN -- 从动态SQL块调用 plsql_block := 'BEGIN raise_emp_salary(:cvalue, :cname, :amt); END;'; EXECUTE IMMEDIATE plsql_block USING 110, 'DEPARTMENT_ID', 10;
-- 从动态SQL语句调用 --EXECUTE IMMEDIATE 'BEGIN raise_emp_salary(:cvalue, :cname, :amt); END;' --USING 112, 'EMPLOYEE_ID', 10; END;
1次执行:
2次执行
|
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17013648/viewspace-1082050/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/17013648/viewspace-1082050/