2016-02-19 6 views
0

Мое требование - обновить столбец partition_date уже разделенной таблицы - MYTABLE. У меня есть MYPROC pl/sql процедура для этого. Ниже приведен соответствующий контент MYPROC.Oracle: как обновить столбец секционированной таблицы

p_partition_name VARCHAR2(40); 

SELECT distinct(uo.subobject_name) 
INTO p_partition_name 
FROM MYTABLE t, 
    user_objects uo 
WHERE dbms_rowid.rowid_object(t.rowid) = uo.object_id 
AND partition_date BETWEEN '01-OCT-2015' AND '31-OCT-2015'; 



BEGIN 

         DBMS_OUTPUT.PUT_LINE('Partition Name' || p_partition_name); 
          FOR i IN 1 .. partition_table.count 
          LOOP 
           UPDATE MYTABLE partition (p_partition_name) SET PARTITION_DATE = '01-AUG-2015' WHERE {..some condition..} 
          END LOOP; 
         END; 

При выполнении MYPROC, я получаю ниже ошибки.

Error report: 
ORA-02149: Specified partition does not exist 
ORA-06512: at "NESSDBA.MYPROC", line 116 
ORA-06512: at line 2 
02149. 00000 - "Specified partition does not exist" 
*Cause: Partition not found for the object. 
*Action: Retry with correct partition name. 
Partition NameSYS_P3495 

Когда я выполняю ниже обычного update заявления без использования процедуры и вручную передавая имя раздела, нет никаких ошибок.

UPDATE MYTABLE partition (SYS_P3495) SET PARTITION_DATE = '01-AUG-2015' WHERE {..some condition..} 

Как передать название раздела в мою инструкцию по обновлению в pl/sql?

+1

Есть ли причина, по которой вам необходимо указать название раздела? Это почти никогда не нужно. Если вы хотите использовать имя раздела и определить имя раздела во время выполнения, то для его создания потребуется использовать динамический SQL. Это возможно, но это добавляет немного сложности, и кажется маловероятным, что это действительно необходимо. –

+0

Я запускаю 'update' с именем раздела, чтобы повысить производительность команды' update'. Я тоже кое-что прочитал. Я даже заметил время, затраченное на выполнение простой инструкции 'update' vs' update' с именем раздела. Существует большая разница во времени. Кстати, у меня есть миллионы записей в моем столе. – user2488578

+0

Использует ли ваше заявление ключ раздела в предложении where? Не могли бы? Кажется маловероятным, что вы можете определить имя раздела, в котором есть данные, которые вас интересуют, но что ключ раздела не будет одним из предикатов. Если ключ раздела является одним из предикатов, план запроса должен показать, что Oracle просто должен получить доступ к одному разделу без необходимости его указания. Если вы не сделали что-то вроде ручного разбиения на разделы, а не на разбиение на разделы ... –

ответ

1

Попробуйте использовать динамический sql вместо статического; Код

declare 
v_date date:= to_date('01-AUG-2015','dd-mon-yyyy'); 
bEGIN 
    FOR i IN (SELECT distinct (uo.subobject_name) partition_name FROM parttab t, user_objects uo 
    WHERE dbms_rowid.rowid_object(t.rowid) = uo.object_id) LOOP 

    DBMS_OUTPUT.PUT_LINE('update parttab partition (' || i.partition_name || ') set jdate = '||v_date); 
    execute immediate 'update parttab partition (' || i.partition_name || ') set jdate = :vv_date' using v_date; 

    END LOOP; 
END; 
+0

Я объявил переменную 'setter VARCHAR2 (20): = '01 -AUG-2015''. Я изменил свой код в соответствии с вашим ответом на этот вопрос: 'немедленно выполнить 'обновление parttab раздела (' || i.partition_name || ') установить jdate = (' || setter || ')';'. Это дает «ORA-00904:« AUG »: недопустимый идентификатор' – user2488578

+0

Я предположил, что вы хотите, чтобы записи обновления в таблице для определенного раздела отображали SYS_P3495 в вашем случае; предполагая, что вы выбираете раздел динамически и обновляете записи для определенного раздела только в этом случае ваш sql-запрос станет обновлять mytable «раздел раздел» set = «set clause», а затем где условие. –

+0

Я не совсем понял ваш комментарий. Мое требование прост - в вашем ответе вместо 'sysdate-1', я хочу передать дату в формате' dd-MON-yyyy'. Как это сделать? – user2488578