问题
Dynamic SQL update statement as below:
EXECUTE IMMEDIATE 'UPDATE '||l_prefix||'CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = '||i.CUSTOMER_REF_ID||' WHERE CUSTOMER_ID = '||i.CUSTOMER_ID;
l_prefix
is the parameter hold the prefix of table name, the value assigned is T_
i.CUSTOMER_REF_ID
and i.CUSTOMER_ID
are the fields fetched from cursor.
The dynamic statement encounter error ORA-00904: invalid identifier
when data fetched.
When rewrite it in static way, the query is working fine:
UPDATE T_CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = i.CUSTOMER_REF_ID WHERE
CUSTOMER_ID = i.CUSTOMER_ID;
I know it must be something wrong on the concatenation of dynamic SQL, just couldn't pinpoint any as the compilation is fine.
回答1:
WARNING: Dynamic SQL like this is susceptible to SQL Injection attacks. Wherever possible rewrite your dynamic SQL to use bind variables instead.
Instead of constructing your dynamic SQL like this:
L_SQL := 'UPDATE '||l_prefix||'CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = '||i.CUSTOMER_REF_ID||' WHERE CUSTOMER_ID = '||i.CUSTOMER_ID;
EXECUTE IMMEDIATE L_SQL;
Use this:
L_SQL := 'UPDATE '||l_prefix||'CRS_CUSTOMERS SET CUSTOMER_SOURCE_REF_ID = :REF_ID WHERE CUSTOMER_ID = :CUST_ID';
EXECUTE IMMEDIATE L_SQL USING i.CUSTOMER_REF_ID, i.CUSTOMER_ID;
This is still subject to SQL injection at the l_prefix
, but if you control that value programatically it may be OK. Also splitting the construction of the SQL and execution of the SQL into two steps allows you to more easily replace the EXECUTE IMMEDIATE
with DBMS_OUTPUT.PUT_LINE(SQL);
to check your query for syntax errors. You can also want to DBMS_OUTPUT.PUT_LINE
your parameters i.CUSTOMER_REF_ID
and i.CUSTOMER_ID
to check their values.
来源:https://stackoverflow.com/questions/49882662/dynamic-sql-syntax-using-execute-immediate