2016-04-21 4 views
0

У меня есть запрос ниже, который дает ошибку, поскольку встречается с символом (в строке, где используется цикл. Я пытаюсь разработать функцию, которая принимает динамический параметр как table_name, column_name, table_id и используется для других таблиц ., а такжеВыполнение Immediate in oracle

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; 
+0

У вас недостаточно одиночных кавычек. Например, после добавления имени таблицы вам нужно снова поставить кавычки). 'EXECUTE IMMEDIATE' нуждается в строке. – Nitish

+0

@Nitesh я попытался, но все равно получаю ту же ошибку. Jchomel, пожалуйста, объясните больше? – Andrew

+0

Как выглядит таблица образцов и каковы возможные значения в трех входных параметрах для этой таблицы? – ruudvan

ответ

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?

+0

Это означает, что 'table_id' является * not * именем вашего столбца? В этом случае вам нужно передать дополнительный параметр 'table_id_name'. –

+0

хорошо, я скорректировал процедуру. параметр 'table_id' теперь является именем столбца вашего первичного ключа. В моей первой версии это значение id :-) –

+0

Я исправил это: привязка переменной table_id больше не использовалась –

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 и проверить t его. Если содержание переменной является синтаксический правильно и выполнимы, то 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; 
+0

a FOR - Loop - это не просто SELECT/INSERT/UPDATE/DELETE-Statement, поэтому вы должны обернуть весь свой код в анонимный блок, например «** begin ** for .... loop do_something; end loop; ** end ** " – oratom

+0

Почему вы обновляете тот же 1 столбец для того же набора строк внутри цикла FOR? – ruudvan

+0

Мне интересно, нужна ли петля? –

0

Я думаю, что у меня есть одна альтернатива для вашего вопроса. В этом случае можно использовать MERGE. Пожалуйста, попробуйте, я не имею workpaceso dint, но это должно работать. Дайте мне знать, если это поможет.

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; 
+0

поэтому не должно быть столбца с именем table_id для имени_таблицы, которое вы передаете –

+0

Это работает для меня только что проверено. Y downvote plz justify –

Смежные вопросы