在oracle中执行Immediate

时间:2016-04-21 12:53:55

标签: oracle function for-loop plsql execute-immediate

我有下面的查询,它会在遇到符号时出现错误(在使用循环的行中。我正在尝试开发一个函数,它将动态参数作为table_name,column_name,table_id并用于其他表。< / p>

FUNCTION get_encryp_pass( table_name IN varchar2,column_name IN varchar2,table_id IN varchar2) RETURN VARCHAR2
  IS
  BEGIN
   EXECUTE IMMEDIATE 'for c1 in (select * from' || table_name ||) loop   
      EXECUTE IMMEDIATE 'update ' || table_name || ' set ' || column_name = encrypt_val(c1.column_name) || ' where ' || table_id || ' = ' || c1.table_id and column_name is not null;
      end loop;   
  END get_encrypt_pass;

3 个答案:

答案 0 :(得分:1)

要注意什么是变量,什么是字符串文字,因此必须单引号...而字符串变量应该是双引号:

EXECUTE IMMEDIATE 'update ' || table_name || ' set ' || column_name || ' = ''' || encrypt_val(c1.column_name) || ''' where ' || table_id || ' = ' || c1.table_id || ' and column_name is not null';

最佳做法是首先在varchar2-variable中连接语句并检查它。如果变量的内容是语法正确且可执行的,那么EXECUTE IMMEDIATE也可以正常工作

declare
   stmt varchar2(4000);
begin
   stmt := 'update ' || table_name || ' set ' || column_name || ' = ''' || encrypt_val(c1.column_name) || ''' where ' || table_id || ' = ' || c1.table_id || ' and column_name is not null';
   EXECUTE IMMEDIATE stmt;
end;

答案 1 :(得分:1)

这应该有效:

CREATE PROCEDURE get_encryp_pass(table_name  IN varchar2,
                                 column_name IN varchar2,
                                 table_id    IN varchar2) IS
BEGIN
  EXECUTE IMMEDIATE 'begin for c1 in (select * from ' || table_name ||
                    ') loop update ' || table_name || ' set ' ||
                    column_name || ' = encrypt_val(c1.' || column_name ||
                    ') where ' || table_id || ' = c1.'||table_id||' and ' || column_name ||
                    ' is not null; end loop; end;'
    ;
END;

但为什么不简单地拨打update FTP_SFTP_SERVER set PASSWORD=encrypt_val(PASSWORD) where PASSWORD is not null

答案 2 :(得分:0)

我想我有一个替代你的问题。在这种情况下可以使用MERGE。请尝试它我没有工作室测试它但它应该工作让我知道它是否有帮助。

FUNCTION get_encryp_pass(
    table_name  IN VARCHAR2,
    column_name IN VARCHAR2,
    table_id    IN VARCHAR2)
  RETURN VARCHAR2
IS
BEGIN
  EXECUTE IMMEDIATE 'MERGE INTO '||table_name||' t1 USING 
(
SELECT * FROM '||table_name|| ')t2
ON
(
t1.table_id = t2.table_id
)
WHEN MATCHED THEN
UPDATE SET t1.'||column_name||' = encrypt_val(t2.'||column_name||')'
||' WHERE and t1.'||column_name||' IS NOT NULL';
END;