I want to select a data and wanna see in which partition.
partition column is : code (varchar column)
Select .... -- I want to find partition name
from
partition_table
where to_number(code) = 55;
why I need to this:
I have a data which code is '55' but in that table when I use partition column I do not select it. But there is data which value is '55'
So I want to that data in which partition.
And the data is not in PDEFAULT partition. I ve already check it.
edit
data is in another partition. I think there is a problem with exchange partition process
thanks in advance
There are a couple of ways.
1) The rowid will point to the partition object
SQL> create table t ( x int, y int )
2 partition by range (x )
3 ( partition p1 values less than ( 100 ),
4 partition p2 values less than ( 200 )
5 );
Table created.
SQL>
SQL> insert into t values (34,34);
1 row created.
SQL>
SQL> select rowid from t;
ROWID
------------------
AAA0cqAAHAAAAQ6AAA
1 row selected.
SQL>
SQL> select dbms_rowid.rowid_object(rowid) from t;
DBMS_ROWID.ROWID_OBJECT(ROWID)
------------------------------
214826
1 row selected.
SQL>
SQL> select subobject_name
2 from user_objects
3 where data_Object_id =
4 ( select dbms_rowid.rowid_object(rowid) from t );
SUBOBJECT_NAME
------------------------------------------------------------
P1
2) You can data mine the dictionary to probe the HIGH_VALUE column in USER_TAB_PARTITIONS. I did a video on how to do that here
https://www.youtube.com/watch?v=yKHQQXKdfOM
Related
I am trying to Create a list partition Based on the column "REFRESH_FLAG_Y" which has only Y and N as its Values, Below is the Alter Table used to Create the partition
ALTER TABLE "EDW"."LABOR_SCHEDULE_DAY_F" MODIFY
PARTITION BY LIST ("REFRESH_FLAG")
(PARTITION "REFRESH_FLAG_Y" VALUES ('Y') ,
PARTITION "REFRESH_FLAG_N" VALUES ('N')) ;
COMMIT;
But Whenever I execute the code I get an Error message
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition
You did tag the question with Oracle 11g tag; do you really use it?
This is a 12c example; it works if everything is OK:
SQL> create table labor_schedule_day_f as
2 select 1 id, 'Y' refresh_flag from dual union all
3 select 2 id, 'N' refresh_flag from dual;
Table created.
SQL> alter table labor_schedule_Day_f modify
2 partition by list (refresh_flag)
3 (partition refresh_flag_y values ('Y'),
4 partition refresh_flag_n values ('N')
5 );
Table altered.
Error you reported means this:
SQL> drop table labor_schedule_day_f;
Table dropped.
SQL> create table labor_schedule_day_f as
2 select 1 id, 'Y' refresh_flag from dual union all
3 select 2 id, 'N' refresh_flag from dual;
Table created.
Insert a row whose REFRESH_FLAG isn't Y nor N (so it violates the rule you specified):
SQL> insert into labor_schedule_day_f values (3, 'X');
1 row created.
Using the same ALTER TABLE statement as previously:
SQL> alter table labor_schedule_Day_f modify
2 partition by list (refresh_flag)
3 (partition refresh_flag_y values ('Y'),
4 partition refresh_flag_n values ('N')
5 );
alter table labor_schedule_Day_f modify
*
ERROR at line 1:
ORA-14400: inserted partition key does not map to any partition
SQL>
See? Error you got, which means that
which has only Y and N as its Values
isn't true.
P.S. You'd get the same result even if refresh_flag was NULL for some rows.
We are trying to migrate data from Oracle to Elasticsearch using Apache Nifi.
We are trying to establish a one to many relationships(represented as multiple tables in Oracle) in a single elastic index.
What we are trying to achieve can be summarized as below.
select * from table1. (The primary key of table1 is key1)
For each fetched record, We want to extract data from another table using the key from table 1. Something like
select * from table2 where foreign_key = key1.
We checked the ExecuteSQLRecord processor which has select query and post query but are unable to figure out how to reference key from table1 in the query to table2
Please let us know if there are any other processors specifically designed for this use case.
There are several ways to achieve this
Creating Views in Oracle
You can create views in Oracle to build the queries that make the relationship primarykey-foreingkey. Thereby you can select directly from the view instead.
A small example
SQL> create table testpk ( c1 number , c2 number );
Table created.
SQL> alter table testpk add primary key ( c1 ) ;
Table altered.
SQL> create table testfk ( c3 number , c4 number );
Table created.
SQL> alter table testfk add constraint fk_to_testpk FOREIGN KEY (c3) references testpk(c1) ;
Table altered.
SQL> insert into testpk values ( 1 , 1);
1 row created.
SQL> insert into testfk values ( 1 , 2 );
1 row created.
SQL> insert into testpk values ( 2 , 2 );
1 row created.
SQL> insert into testfk values ( 2 , 2 );
1 row created.
SQL> commit;
Commit complete.
SQL> create or replace force view my_test_view as select a.c1 , a.c2 , b.c3 , b.c4
2 from testpk a join testfk b on ( a.c1 = b.c3 ) ;
View created.
SQL> select * from my_test_view ;
C1 C2 C3 C4
---------- ---------- ---------- ----------
1 1 1 2
2 2 2 2
SQL>
Use queries directly
In your case, you need to run the query to make the relationship against the parent table, therefore you need a join:
select * from table2 inner join table1 where table2_foreingkey = table1_primarykey.
You want all records from table2 where the relationship parent key table 1 - child key table 2 matches, something you can do it with a normal inner join
If you ask me, I would create views to make the process more transparent in elastic search.
I'm in the middle of creating a tool similar to the SQL Developer table data viewer. My db is Oracle based.
I simply need to delete eg.: 'row number 3' from a SELECT result. That table doesn't have any PK nor unique records. I've tried various techniques with ROWNUM etc. but no luck.
Oracle has a ROWID pseudocolumn that you can use for this purpose in simple cases.
select rowid, ... from your_table where ... ;
delete from your_table where rowid = <what you got above>;
If your interface allows the user to make complex views/joins/aggregates, then knowing what the user intended to delete (so knowing what set of rowids to gather and what set of tables to delete from) is going to be tricky.
Warning: rowids are unique only within a given table, and, quoting the above documentation:
If you delete a row, then Oracle may reassign its rowid to a new row inserted later.
So be very, very careful if you do this.
Assuming that it is a standard heap-organized table (index-organized tables and clusters potentially introduce additional complexity), if you don't have any other way to identify a row, you can use the ROWID pseudocolumn. This gives you information about the physical location of a row on disk. This means that the ROWID for a particular row can change over time and the ROWID can and will be reused when you delete a row and then a subsequent INSERT operation inserts a new row that happens to be in the same physical location on disk. For most applications, it is reasonable to assume that the ROWID will remain constant between the time that you execute the query and the time that you issue the DELETE but you shouldn't try to store the ROWID for any period of time.
For example, if we create a simple two-column table and a few rows
SQL> create table foo( col1 number, col2 varchar2(10) );
Table created.
SQL> insert into foo values( 1, 'Justin' );
1 row created.
SQL> insert into foo values( 1, 'Justin' );
1 row created.
SQL> insert into foo values( 2, 'Bob' );
1 row created.
SQL> insert into foo values( 2, 'Charlie' );
1 row created.
SQL> commit;
Commit complete.
We can SELECT the ROWID and then DELETE the third row using the ROWID
SQL> select *
2 from foo;
COL1 COL2
---------- ----------
1 Justin
1 Justin
2 Bob
2 Charlie
SQL> select rowid, col1, col2
2 from foo;
ROWID COL1 COL2
------------------ ---------- ----------
AAAfKXAAEAABt7vAAA 1 Justin
AAAfKXAAEAABt7vAAB 1 Justin
AAAfKXAAEAABt7vAAC 2 Bob
AAAfKXAAEAABt7vAAD 2 Charlie
SQL> delete from foo where rowid = 'AAAfKXAAEAABt7vAAC';
1 row deleted.
SQL> select * from foo;
COL1 COL2
---------- ----------
1 Justin
1 Justin
2 Charlie
Try using ROWID instead of ROWNUM.
I am using an oracle 11 table with interval partitioning and list subpartitioning like this (simplified):
CREATE TABLE LOG
(
ID NUMBER(15, 0) NOT NULL PRIMARY KEY
, MSG_TIME DATE NOT NULL
, MSG_NR VARCHAR2(16 BYTE)
) PARTITION BY RANGE (MSG_TIME) INTERVAL (NUMTOYMINTERVAL (1,'MONTH'))
SUBPARTITION BY LIST (MSG_NR)
SUBPARTITION TEMPLATE (
SUBPARTITION login VALUES ('FOO')
, SUBPARTITION others VALUES (DEFAULT)
)
(PARTITION oldvalues VALUES LESS THAN (TO_DATE('01-01-2010','DD-MM-YYYY')));
How do I drop a specific subpartitition for a specific month without knowing the (system generated) name of the subpartition? There is a syntax "alter table ... drop subpartition for (subpartition_key_value , ...)" but I don't see a way to specify the month for which I am deleting the subpartition. The partition administration guide does not give any examples, either. 8-}
You can use the metadata tables to get the specific subpartition name:
SQL> insert into log values (1, sysdate, 'FOO');
1 row(s) inserted.
SQL> SELECT p.partition_name, s.subpartition_name, p.high_value, s.high_value
2 FROM user_tab_partitions p
3 JOIN
4 user_tab_subpartitions s
5 ON s.table_name = p.table_name
6 AND s.partition_name = p.partition_name
7 AND p.table_name = 'LOG';
PARTITION_NAME SUBPARTITION_NAME HIGH_VALUE HIGH_VALUE
--------------- ------------------ ------------ ----------
OLDVALUES OLDVALUES_OTHERS 2010-01-01 DEFAULT
OLDVALUES OLDVALUES_LOGIN 2010-01-01 'FOO'
SYS_P469754 SYS_SUBP469753 2012-10-01 DEFAULT
SYS_P469754 SYS_SUBP469752 2012-10-01 'FOO'
SQL> alter table log drop subpartition SYS_SUBP469752;
Table altered.
If you want to drop a partition dynamically, it can be tricky to find it with the ALL_TAB_SUBPARTITIONS view because the HIGH_VALUE column may not be simple to query. In that case you could use DBMS_ROWID to find the subpartition object_id of a given row:
SQL> insert into log values (4, sysdate, 'FOO');
1 row(s) inserted.
SQL> DECLARE
2 l_rowid_in ROWID;
3 l_rowid_type NUMBER;
4 l_object_number NUMBER;
5 l_relative_fno NUMBER;
6 l_block_number NUMBER;
7 l_row_number NUMBER;
8 BEGIN
9 SELECT rowid INTO l_rowid_in FROM log WHERE id = 4;
10 dbms_rowid.rowid_info(rowid_in =>l_rowid_in ,
11 rowid_type =>l_rowid_type ,
12 object_number =>l_object_number,
13 relative_fno =>l_relative_fno ,
14 block_number =>l_block_number ,
15 row_number =>l_row_number );
16 dbms_output.put_line('object_number ='||l_object_number);
17 END;
18 /
object_number =15838049
SQL> select object_name, subobject_name, object_type
2 from all_objects where object_id = '15838049';
OBJECT_NAME SUBOBJECT_NAME OBJECT_TYPE
--------------- --------------- ------------------
LOG SYS_SUBP469757 TABLE SUBPARTITION
As it turns out, the "subpartition for" syntax does indeed work, though that seems to be a secret Oracle does not want to tell you about. :-)
ALTER TABLE TB_LOG_MESSAGE DROP SUBPARTITION FOR
(TO_DATE('01.02.2010','DD.MM.YYYY'), 'FOO')
This deletes the subpartition that would contain MSG_TIME 2010/02/01 and MSG_NR FOO. (It is not necessary that there is an actual row with this exact MSG_TIME and MSG_NR. It throws an error if there is no such subpartition, though.)
Thanks for the post - it was very useful for me.
One observation though on the above script to identify the partition and delete it:
The object_id returned by dbms_rowid.rowid_info is not the object_id of the all_objects table. It is actually the data_object_id. It is observed that usually these ids match. However, after truncating the partitioned table several times, these ids diverged in my database. Hence it might be reasonable to instead use the data_object_id to find out the name of the partition:
select object_name, subobject_name, object_type
from all_objects where data_object_id = '15838049';
From the table description of ALL_OBJECTS:
OBJECT_ID Object number of the object
DATA_OBJECT_ID Object number of the segment which contains the object
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_rowid.htm
In the sample code provided in the above link, DBMS_ROWID.ROWID_OBJECT(row_id) is used instead to derive the same information that is given by dbms_rowid.rowid_info. However, the documentation around this sample mentions that it is a data object number from the ROWID.
Examples
This example returns the ROWID for a row in the EMP table, extracts
the data object number from the ROWID, using the ROWID_OBJECT function
in the DBMS_ROWID package, then displays the object number:
DECLARE object_no INTEGER; row_id ROWID; ... BEGIN
SELECT ROWID INTO row_id FROM emp
WHERE empno = 7499; object_no := DBMS_ROWID.ROWID_OBJECT(row_id); DBMS_OUTPUT.PUT_LINE('The obj. # is
'|| object_no); ...
I would like to know if the following steps are possible and how fast this is:
Create a partition named part1 in Table A
Drop partition part1 in Table B
Import the Table A partition part1 into Table B
Can you provide me with an example if it is possible indeed? Or any resources I can look at?
Note that the tables would have the exact same structure.
You can do something similar with the ALTER TABLE ... EXCHANGE PARTITION command. This would exchange a single partition with a table that has the same structure.
A little example:
/* Partitionned Table Creation */
SQL> CREATE TABLE table_a (
2 ID NUMBER PRIMARY KEY,
3 DATA VARCHAR2(200)
4 )
5 PARTITION BY RANGE (ID) (
6 PARTITION part100 VALUES LESS THAN (100),
7 PARTITION part200 VALUES LESS THAN (200)
8 );
Table created
/* Swap table creation */
SQL> CREATE TABLE swap_table (
2 ID NUMBER PRIMARY KEY,
3 DATA VARCHAR2(200)
4 );
Table created
SQL> INSERT INTO swap_table SELECT ROWNUM, 'a' FROM dual CONNECT BY LEVEL <= 99;
99 rows inserted
SQL> select count(*) from table_a partition (part100);
COUNT(*)
----------
0
This will exchange the partition part100 with the transition table swap_table:
SQL> ALTER TABLE table_a EXCHANGE PARTITION part100 WITH TABLE swap_table;
Table altered
SQL> select count(*) from table_a partition (part100);
COUNT(*)
----------
99