I have 2 tables. One of those is interval partitioned.
CREATE TABLE testtable
("MYVALUE" VARCHAR2(200) NOT NULL ENABLE,
"COLLECTION_TIME" DATE NOT NULL ENABLE
)
PARTITION BY RANGE (COLLECTION_TIME) INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
( PARTITION p_default VALUES LESS THAN (to_timestamp('1-1-2017', 'DD-MM-YYYY')) )
CREATE TABLE destinationtable
("MYVALUE" VARCHAR2(200) NOT NULL ENABLE,
"COLLECTION_TIME" DATE NOT NULL ENABLE
)
Lets say I insert 4 rows with different collection_time in the testtable.
insert into testtable values ('Value1',to_date('2-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'))
insert into testtable values ('Value1',to_date('3-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'))
insert into testtable values ('Value1',to_date('4-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'))
insert into testtable values ('Value1',to_date('5-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'))
This should create 4 new partitions in this table.
Now, I have aprocedure whose input is date, I want to insert only rows in the partition for that date into the destinationtable.
I have written a similar proc here ->
declare
p_records_for_date varchar2(200) := '2017-09-03 00:00';
l_parition_sql_addon varchar2(200);
begin
l_parition_sql_addon := ' partition for (to_date(substr('||p_records_for_date||',1,10),''yyyy-mm-dd''))';
execute immediate 'insert into destinationtable select myvalue,collection_time from testtable'||l_parition_sql_addon ;
end;
/
My question is, will this work ? or I will hit "ORA-14763: Unable to resolve FOR VALUES clause to a partition number
14763. 00000 - "Unable to resolve FOR VALUES clause to a partition number"
*Cause: Could not determine the partition corresponding to the FOR VALUES
clause.
*Action: Remove bind variables and dependencies on session parameters
from the values specified in the FOR VALUES clause."
Please comment on when that could happen and how it can be resolved ?
Well...we've got one problem to start with
SQL> CREATE TABLE testtable
2 ("MYVALUE" VARCHAR2(200) NOT NULL ENABLE,
3 "COLLECTION_TIME" DATE NOT NULL ENABLE
4 )
5 PARTITION BY RANGE (COLLECTION_TIME) INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
6 ( PARTITION p_default VALUES LESS THAN (to_timestamp('1-1-2017', 'DD-MM-YYYY')) )
7 /
Table created.
SQL>
SQL>
SQL>
SQL> CREATE TABLE destinationtable
2 ("MYVALUE" VARCHAR2(200) NOT NULL ENABLE,
3 "COLLECTION_TIME" DATE NOT NULL ENABLE
4 )
5 /
Table created.
SQL>
SQL>
SQL> insert into testtable values ('Value1',to_date('2-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL> insert into testtable values ('Value1',to_date('3-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL> insert into testtable values ('Value1',to_date('4-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL> insert into testtable values ('Value1',to_date('5-SEP-17 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL>
SQL> commit;
Commit complete.
SQL>
SQL> select partition_name
2 from user_tab_partitions
3 where table_name = 'TESTTABLE';
PARTITION_NAME
--------------------------------------------------------------------------------------------------------------------------------
P_DEFAULT
1 row selected.
SQL>
SQL> select to_char(COLLECTION_TIME,'dd/mm/yyyy') from TESTTABLE;
TO_CHAR(CO
----------
02/09/0017
03/09/0017
04/09/0017
05/09/0017
4 rows selected.
but lets proceed with the test case you probably *intended* to write
SQL> insert into testtable values ('Value1',to_date('2-SEP-2017 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL> insert into testtable values ('Value1',to_date('3-SEP-2017 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL> insert into testtable values ('Value1',to_date('4-SEP-2017 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL> insert into testtable values ('Value1',to_date('5-SEP-2017 06:36:28 AM', 'DD-MON-YYYY HH:MI:SS AM'));
1 row created.
SQL>
SQL> commit;
Commit complete.
SQL>
SQL> select partition_name
2 from user_tab_partitions
3 where table_name = 'TESTTABLE';
PARTITION_NAME
-----------------------------------------------------------------------------------------------------------------
P_DEFAULT
SYS_P3969
SYS_P3970
SYS_P3971
SYS_P3972
So *now* we have 4 partitions. Now your anonymous block *will* get an error...but not because of partitioning.
SQL>
SQL> declare
2 p_records_for_date varchar2(200) := '2017-09-03 00:00';
3 l_parition_sql_addon varchar2(200);
4 begin
5 l_parition_sql_addon := ' partition for (to_date(substr('||p_records_for_date||',1,10),''yyyy-mm-dd''))';
6 execute immediate 'insert into destinationtable select myvalue,collection_time from testtable'||l_parition_sql_addon ;
7 end;
8 /
declare
*
ERROR at line 1:
ORA-00907: missing right parenthesis
ORA-06512: at line 6
Because you are not generating the SQL correctly
SQL>
SQL> set serverout on
SQL> declare
2 p_records_for_date varchar2(200) := '2017-09-03 00:00';
3 l_parition_sql_addon varchar2(200);
4 begin
5 l_parition_sql_addon := ' partition for (to_date(substr('||p_records_for_date||',1,10),''yyyy-mm-dd''))';
6
7 -- execute immediate 'insert into destinationtable select myvalue,collection_time from testtable'||l_parition_sql_addon ;
8 dbms_output.put_line('insert into destinationtable select myvalue,collection_time from testtable'||l_parition_sql_addon );
9 end;
10 /
insert into destinationtable select myvalue,collection_time from testtable partition for (to_date(substr(2017-09-03
00:00,1,10),'yyyy-mm-dd'))
PL/SQL procedure successfully completed.
See the missing quotes. But lets put that aside and just try some inserts.... You'll find they work for partitions and non-existent partitions too
SQL>
SQL> insert into destinationtable
2 select myvalue,collection_time
3 from testtable partition for (to_date(substr('2017-09-03 00:00',1,10),'yyyy-mm-dd'));
1 row created.
SQL> insert into destinationtable
2 select myvalue,collection_time
3 from testtable partition for (to_date(substr('2018-09-03 00:00',1,10),'yyyy-mm-dd'));
0 rows created.