I want to create a stored procedure like this:
PROCEDURE P_CUSTOMER_UPDATE
(
pADSLTable IN Table,
pAccountname IN NVARCHAR2,
pStatus IN NUMBER,
pNote IN NVARCHAR2,
pEmail IN NVARCHAR2,
pMobi IN NVARCHAR2,
pServiceTypeID IN NUMBER,
pDate IN DATE
)
IS
BEGIN
UPDATE pADSLTable
SET STATUS = pStatus, NOTE = pNote, EMAIL = pEmail, MOBI = pMobi, SERVICETYPE_ID = pServiceTypeID, ACTIVATION_DATE = pDate
WHERE ACCOUNT_NAME = pAccountname;
END;
Of course, Oracle does not let me do that. Is there a way to work around this problem? Thank you very much.
You have several different tables with exactly the same column names and data types? Smells like a dodgy design.
Anyway, we cannot use variables as database objects in straightforward SQL like that. We have to use dynamic SQL.
One reason to avoid the use of dynamic SQL is that it is open to abuse. Malicious people can use the parameters to attempt to bypass our security. This is called SQL injection. I think people over estimate the significance of SQL injection. It's not automatically a threat. For instance if the procedure is a private procedure in a package (i.e. not declared in the specification) it is unlikely that anybody will hijack it.
But it is sensible to take precautions. DBMS_ASSERT is a package introduced in Oracle 10g to trap attempted SQL injection attacks. It this case it would be worth using it to validate the passed table name
This would prevent anybody passing
'pay_table set salary = salary * 10 where id = 1234 --'
as the table name parameter.Another reason to avoid dynamic SQL is that it is harder to get right and harder to debug. The syntax of the actual statement is only checked at run time. It is good to have a complete suite of unit tests which validate all the passed inputs, to ensure that the procedure doesn't hurl a syntax exception.
Finally, such dynamic SQL doesn't show up in views such as ALL_DEPENDENCIES. This makes it harder to undertake impact analysis and locate all the programs which use a given table or column.
Yes, there is Native Dynamic SQL:
Performance and error checking is not as good (no compile-time syntax and schema validation). Beware of SQL injection.
So, if you have only a couple of tables to choose from, consider using an if/then/else construct with all options instead.
You can use all sort of DDL statements using dynamic SQL. You can pass names of different database objects as parameters or manipulate in variables.