Self referencing table and SQL statement
In my database, I have a self-referencing table, the table itself is for projects, and it allows users to get a hierarchical view of the company.
Here is the SQL (modifier is the term we use for project code, BBCI is the top project)
SELECT
modifier, modifierDescription, level
FROM
modifier
WHERE
level <= 2
CONNECT BY PRIOR
modifier = parentModifier
START WITH modifier = 'BBCI'
ORDER BY level
That perticular query gets the first two levels in the structure. I use this information to produce a tree structure in a web app.
But users have requested it would be good if in the tree structure is showed an + or - depending on whether there were anymore children under each parent, or better still the number of children under it, for example
BBCI
+ BBCI_CHILD
+ BBCI_CHILD2
- BBCI_CHILD3
or
BBCI
+ BBCI_CHILD (3 projects underneath)
+ BBCI_CHILD2 (2 projects underneath)
- BBCI_CHILD3 (0 projects underneath)
I am really stumped on this issue, and I am sure there is a way to do this in the web app, so for example do a query for each child node to see how many child nodes are underneath, but I figure it would be a lot tidier and faster if I could do it from a single SQL statement. Unfortunately I have tried to do this and am very much stuck.
If you need more information please let me know
Thanks!
Jon
You may be able to do this using analytical functions but it depends on the Oracle version you are using. It can also be done with standard SQL - you just need to count the number of child rows for each modifier/project first and supply that list as an in-line view:
SELECT decode(modifier,'X',null,decode(child_rows,null,'-','+')),
m.modifier,
decode(modifier,'X',null,'('||nvl(cq.child_rows,0)||' projects underneath)')
FROM modifier m,
(select parentModifier,
count(parentModifier) child_rows
from modifier
where parentModifier is not null
group by parentModifier) cq
WHERE m.modifier=cq.parentModifier(+)
AND level <= 2
CONNECT BY PRIOR
m.modifier = m.parentModifier
START WITH modifier = 'X'
ORDER BY level, modifier;
which gives you something like...
D MODIFIER DECODE(MODIFIER,'X',NULL
X
- Y1 (0 projects underneath)
+ Y2 (2 projects underneath)
+ Y3 (3 projects underneath)
The decode stuff is just to show you the result, you can format the output in your calling code. Just extend the columns to include everything you want, modifierDescription etc..
Hope this helps.
Similar Messages
-
Self referencing table and contraint
Hi,
I have a self referencing table, used to store information on projects in an organization. There is a pimary key (modifier) and a foreign key to the modifier field (parentModifier)
Note: (modifier = project in the organization)
Basically, the parentModifier cannot be equal to the modifier in the same table, or equal to any of its children, otehrwise you get wierd recursive relationships. Its like saying you cannot be your own father, or one of your children cannot be your father. To get a list of the modifiers the parentModifier cannot be, the following statement can be used:
select
modifier
from
modifier
where
modifier = 'A'
and
level >= 1
connect by prior
modifier = parentModifier
start with
modifier = 'A'
order by
level;
So, now, I guess the way to do this is perform that query in a trigger before each row is being updated, so the pseudo code would be something like:
BEFORE UPDATE ON modifier
FOR EACH ROW
DECLARE
modifierToChange varchar2(255);
modifierList ???;
BEGIN
select
modifier
into
modifierList
from
modifier
where
modifier = 'A'
and
level >= 1
connect by prior
modifier = parentModifier
start with
modifier = 'A'
order by
level;
if modifierToChange in modifierList
return error
else
execute query
end if
END
As you can see my PL/SQL is limitied. At the moment I can handle this at the application layer (in php), but if the admin going to SQL Plus and starts to fiddle, they can easy break the system, by setting an invalid relationship.
I was wondeirng, if anyone could give me some help or advice, it would be fantastic,
Thanks!Having a unique key on mod_id would be enough to make sure the same element is not in the structure more than once. By allowing it to happed you will have all the descendants of the dup element following it when you walk the tree.
Let's say this is the intended behavior.
Consider the following test scenario:
create table modifier (
mod_id varchar2(10),
parent_mod_id varchar2(10)
insert into modifier (mod_id, parent_mod_id) values ('a', null);
insert into modifier (mod_id, parent_mod_id) values ('aa', 'a');
insert into modifier (mod_id, parent_mod_id) values ('ab', 'a');
insert into modifier (mod_id, parent_mod_id) values ('ac', 'a');
insert into modifier (mod_id, parent_mod_id) values ('aaa', 'aa');
insert into modifier (mod_id, parent_mod_id) values ('aab', 'aa');
insert into modifier (mod_id, parent_mod_id) values ('aac', 'aa');
insert into modifier (mod_id, parent_mod_id) values ('aba', 'ab');
insert into modifier (mod_id, parent_mod_id) values ('abb', 'ab');
insert into modifier (mod_id, parent_mod_id) values ('abc', 'ab');
insert into modifier (mod_id, parent_mod_id) values ('aca', 'ac');
insert into modifier (mod_id, parent_mod_id) values ('acb', 'ac');
insert into modifier (mod_id, parent_mod_id) values ('acc', 'ac');
insert into modifier (mod_id, parent_mod_id) values ('b', null);
insert into modifier (mod_id, parent_mod_id) values ('ba', 'b');
insert into modifier (mod_id, parent_mod_id) values ('bb', 'b');
insert into modifier (mod_id, parent_mod_id) values ('bc', 'b');
insert into modifier (mod_id, parent_mod_id) values ('baa', 'ba');
insert into modifier (mod_id, parent_mod_id) values ('bab', 'ba');
insert into modifier (mod_id, parent_mod_id) values ('bac', 'ba');
insert into modifier (mod_id, parent_mod_id) values ('bba', 'bb');
insert into modifier (mod_id, parent_mod_id) values ('bbb', 'bb');
insert into modifier (mod_id, parent_mod_id) values ('bbc', 'bb');
insert into modifier (mod_id, parent_mod_id) values ('bca', 'bc');
insert into modifier (mod_id, parent_mod_id) values ('bcb', 'bc');
insert into modifier (mod_id, parent_mod_id) values ('bcc', 'bc');
commit;
SQL> select lpad(' ', 2 * (level - 1)) || mod_id item
2 from modifier
3 start with parent_mod_id is null
4 connect by prior mod_id = parent_mod_id;
ITEM
a
aa
aaa
aab
aac
ab
aba
abb
abc
ac
aca
acb
acc
b
ba
baa
bab
bac
bb
bba
bbb
bbc
bc
bca
bcb
bcc
26 rows selected
Create a function to verify if a mod_id already is parent_mod_id's ascendant or descendant:
create or replace function exists_in_parents_branch
i_mod_id in varchar2
,i_parent_mod_id in varchar2
) return boolean is
pragma autonomous_transaction;
v_dummy varchar2(10);
begin
select mod_id
into v_dummy
from (select mod_id
from modifier
where mod_id = i_mod_id
connect by prior mod_id = parent_mod_id
start with mod_id = i_parent_mod_id
union
select mod_id
from modifier
where mod_id = i_mod_id
connect by prior parent_mod_id = mod_id
start with mod_id = i_parent_mod_id);
return true;
exception
when no_data_found then
return false;
end exists_in_parents_branch;
Create a trigger that calls the function above for every insert and update
create or replace trigger biu_modifier
before insert or update on modifier
for each row
begin
if exists_in_parents_branch(:new.mod_id, :new.parent_mod_id) then
raise_application_error(-20000, 'Cannot insert or update because of recursive relationship.');
end if;
end biu_modifier;
You are all set.
Here is a statement that should fail:
SQL> insert into modifier (mod_id, parent_mod_id) values ('bcc', 'b');
insert into modifier (mod_id, parent_mod_id) values ('bcc', 'b')
ERROR at line 1:
ORA-20000: Cannot insert or update because of recursive relationship.
ORA-06512: at "RC.BIU_MODIFIER", line 3
ORA-04088: error during execution of trigger 'RC.BIU_MODIFIER'
Here is a statement that should succeed:
SQL> insert into modifier (mod_id, parent_mod_id) values ('aaaa','aaa');
1 row created. -
Self Referencing Tables...
I have a self-referencing table (a Topic can be a response to another Topic) and read one of Frank Nimphius' blogs on this subject, posted on the ADF board for advise. As a result I created the read-only ViewObject to set up this tree relationship and set it to be exposed to the App Module.
Do I need to do more to it than that for JHeadstart to generate the right page defs? Any advise on setting this up cleanly? My user interface must present a page in which users can post new Topics, view topics in a heirarchy (response thread, like in this forum) and respond to Topics or responses. A response is a Topic that references another (parent) Topic. I have to believe this has been done before a million times but am not sure myself how to do it.
Thanks!Steve,
I've read the section and am getting this error:
(oracle.jbo.SQLStmtException) JBO-27122: SQL error during statement preparation. Statement: SELECT Topic.SUBJECT, Topic.ROW_ID, Status.STATUS_CHOICE, Status.ROW_ID AS ROW_ID11, Topic.CREATED_BY, Topic.CREATION_DATE, Response.SUBJECT AS SUBJECT1, Response.CREATION_DATE AS CREATION_DATE1, Response.ROW_ID AS ROW_ID12, Response.CREATED_BY AS CREATED_BY1 FROM TOPIC Topic, RESPONSE Response, STATUS Status WHERE (Topic.ROW_ID = Response.MASTER_ID (+)) AND (Topic.TOPIC_STATUS_ID = Status.ROW_ID) CONNECT BY PRIOR Topic.ROW_ID = Response.MASTER_ID (+) OR Response.ROW_ID = Response.MASTER_ID (+) ORDER BY SUBJECT,CREATION_DATE1
----- LEVEL 1: DETAIL 0 -----
(java.sql.SQLException) ORA-01436: CONNECT BY loop in user data
I have a table called Topic with a Pk called ROW_ID and another table called Response with a Pk called ROW_ID and an Fk called MASTER_ID. A Topic can have many Responses and a Response can also have many Responses. The parent ID could point to either a Topic or a Response. There's no limit on how many levels this can continue. There's a Status table also from which I want to show the text value of the Status for the Topic row (not the Status ROW_ID)
I have a View Object including entities: Topic, Response & Status
I tried the SQL query as:
(Topic.ROW_ID = Response.MASTER_ID (+)) AND (Topic.TOPIC_STATUS_ID = Status.ROW_ID) CONNECT BY PRIOR Topic.ROW_ID = Response.MASTER_ID (+) OR Response.ROW_ID = Response.MASTER_ID (+)
Hoping to have this result:
Topic A
-Response A (to Topic A)
--Response B (to A)
---Response C (to B)
-Response D (to Topic A)
Topic B
Topic C
What am I doing wrong?
Is there a guide that explains better using JHeadstart with JDeveloper (rather than Oracle Designer, which we don't use)? The developer's guide for JHeadstart is hard to translate for use with JDeveloper...
Thanks!! -
Best practice: self referencing table
Hallo,
I want to load a self referencing table to my enterprise area in the dwh. I am not sure how to do this. What if a record references to another record which is inserted later in the same etl process? There is now way to sort, because it is possible that record a references to record b and record b references to record a. Disabling the fk constraint is not a good idea, because this doesn't prevent that invalid references will be loaded? I am thinking of building two mappings, one without the self referencing column and the other only with it, but that would cause approx. twice as much running time. Any other solutions?
Regards,
TorstenMind sharing the solution? Would be interested to hear your solution (high level).
Jean-Pierre -
Mutating table and row state - this was unexpected
So, I learned in a class about 3 years ago to expect the following
SQL> create table p (pk number primary key);
Table created.
SQL> create table c (fk number references p(pk));
Table created.
SQL> create or replace trigger t_insrt
2 before insert on p
3 for each row
4 begin
5 insert into c values (:new.pk);
6 end;
7 /
Trigger created.
SQL> insert into p values (1);
insert into p values (1)
ERROR at line 1:
ORA-02291: integrity constraint (FORBESC.SYS_C00169150) violated - parent key
not found
ORA-06512: at "FORBESC.T_INSRT", line 2
ORA-04088: error during execution of trigger 'FORBESC.T_INSRT'and so it led me to think that replicating ON MODIFY PARENT - MODIFY CHILD functionality wouldn't work in a BEFORE ROW trigger, but it does
SQL> drop trigger t_insrt;
Trigger dropped.
SQL> create or replace trigger p_updt
2 before update on p
3 for each row
4 begin
5 update c
6 set fk = :new.pk
7 where fk = :old.pk;
8 end;
9 /
Trigger created.
SQL> insert into p values (1);
1 row created.
SQL> insert into c values (1);
1 row created.
SQL> select * from c;
FK
1
SQL> update p
2 set pk = 2
3 where pk = 1;
1 row updated.
SQL> select * from c;
FK
2Why would the first scenario fail while the second succeeds? The update seems prone to a parent record also not existing, at least not by the BEFORE ROW trigger.
---=Chuck< mutating table and row state >
BTW, you don't seem to have run into the mutating table error though 2 other threads today are also about it. You have a constraint violation, a different thing entirely.
I believe the second scenario works because you're neatly avoiding the error of the first. The error "ORA-02291: integrity constraint (FORBESC.SYS_C00169150) violated" means that on insert Oracle is looking up the value you're trying to insert, not finding it, and raising an error. With the before trigger you are taking the assigned value from the insert, updating the parent to it, so that on actual insert when the check happens the value is there due to the update.
I'm not convinced this is a good idea because any on-the-fly approach to data entry needs to be examined carefully. -
JPA: How to initialise an entity for a self-referencing table?
I am working on a project that requires a self-referencing table:
mysql> show create table attributes\G
*************************** 1. row ***************************
Table: attributes
Create Table: CREATE TABLE `attributes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) DEFAULT NULL,
`type` int(11) DEFAULT NULL,
`name` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
KEY `type` (`type`),
CONSTRAINT `attributes_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `attributes` (`id`),
CONSTRAINT `attributes_ibfk_2` FOREIGN KEY (`type`) REFERENCES `attributes` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=latin1
I used NetBeans to generate an entity class from the table:
@Entity
@Table(name = "attributes")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Attributes.findAll", query = "SELECT a FROM Attributes a"),
@NamedQuery(name = "Attributes.findById", query = "SELECT a FROM Attributes a WHERE a.id = :id"),
@NamedQuery(name = "Attributes.findByName", query = "SELECT a FROM Attributes a WHERE a.name = :name")})
public class Attributes implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Size(max = 128)
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "parent")
private Collection<Attributes> attributesCollection;
@JoinColumn(name = "parent", referencedColumnName = "id")
@ManyToOne
private Attributes parent;
@OneToMany(mappedBy = "type")
private Collection<Attributes> attributesCollection1;
@JoinColumn(name = "type", referencedColumnName = "id")
@ManyToOne
private Attributes type;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "attributes")
private Collection<ItemAttributes> itemAttributesCollection;
@OneToMany(mappedBy = "ivalue")
private Collection<ItemAttributes> itemAttributesCollection1;
But how can I write a constructor for this entity? The auto-generated code gets around the issue by doing nothing; the constructor is empty. I can't help thinking that if I set the parent and type references to anything with new Attributes(), then it will recurse out of control. What else can/shall I do? I know how to rewrite it to not use the entity relations, but I'd prefer to make it work.Cymae wrote:
I don't want to call the hash table creation method because from what i understand about interfaces the idea is that your main method doesnt know the table is actually a hash table...is that right?That's not exactly the idea. The idea to use the interface as the type instead of the implementation, is that your class probably doesn't need to know the full type. This makes it easy to change the implementation of the interface if needed. However, somebody at some point has to create the concrete object, a HashTable.
Basically, an interface describes a behavior, and a class that implements an interface decides how to actually perform this behavior. It is obviously impossible to perform the behavior if you are not told how to perform it.
Table table = new HashTable() is the correct way to do it. This means that if you ever need you Table implementation to change, the only thing you need to change in your whole class is this line. For example you might want Table table = new FileTable(). -
Query output help: Display self-referencing table
Hello,
I'm trying to display in a cfoutput a self-referencing table.
I'll start by showing some of the data in the table.
There are only 3 columns, pl_id (auto increment id pri-key),
pl_name and pl_parent_id (it's 0 if it's a parent, otherwise it's
the pl_id value for the parent).
pl_id pl_name pl_parent_id
1 Country 0
2 Food 0
3 US 1
4 Japan 1
5 Hamburger 2
6 Idaho 3
7 Florida 3
8 Cheese 2
What I'm trying to output is something like this:
Country - US - Idaho (3 levels here) or
Country - US - Florida (or if there are only 2 levels like
the next line)
Food - Cheese
I've tried using a cfoutput with a cfloop as well as grouping
but not having any luck. Could someone clear my clouded head on
this one?
thanks much,
Joe
ps. Adobe should really use a fixed width font for these
forums, it's impossible to line up table info!JoeNH2k wrote:
> It would be nice if it were that easy, I (of course)
tried that. The sort order
> of the query doesn't matter. The data is not sorted once
the function runs. The
> sort has to come after the select box is populated by
the function. I need to
> get the data at this point and sort it, probably somehow
creating a structure
> or array from this data and sorting that(?).
>
<cfset myArr = ArrayNew(1)>
<cfloop query="qryGetAll">
<cfset temp = ArrayAppend(myArr,
"#getNameWithParent(pl_id)#")>
</cfloop>
<cfset ArraySort(myArr, "textnocase", "asc")>
<cfset myList = ArrayToList(myArr, ",")>
then loop through myList to populate your <select>...
how about that?
Azadi Saryev
Sabai-dee.com
Vientiane, Laos
http://www.sabai-dee.com -
Self referencing table many to many relationship
I am in a bit of a logic pickle, and I was wondering if someone could help me out.
I have a table in a database I am designing called document, it holds information on surprisingly on documents in our DMS.
I want to create the notion that a document can have multiple related documents, and those documents can be the related documents for many documents.
So it is a self referencing table, I have done these before so no big deal, but this time is a many to many relation, it wasnt before.
Maybe something like:
document
docid (pk)
related_doc
docid (pk) (fk to document.docid)
related_docid (pk) fk to document.docid)
Does anyone have any experience with this or any advise I might find sueful?
Thanks!A junction table can be used to resolve a many-to-many relationship as is in your example. There are two PK/FK relationships between document and related_document table. This will prevent denormalization of data.
The other option could be to have just one table with two columns (parent_doc_id and child_doc_id) and have a PK constraint on both the columns - just like bill-of-materials.
But I think the approach you have in your posting will work well.
Shakti
http://www.impact-sol.com
Developers of Guggi Oracle - Tool for DBAs and Developers -
How to provide joins between oracle tables and sql server tables
Hi,
I have a requirement that i need to generate a report form two different data base. i.e Oracle and Sql Server.
how to provide joins between oracle tables and sql server tables ? Any help on this
Regards,
Malliuser10675696 wrote:
I have a requirement that i need to generate a report form two different data base. i.e Oracle and Sql Server. Bad idea most times. Heterogeneous joins do not exactly scale and performance can be severely degraded by network speed and b/w availability. And there is nothing you can do in the application and database layers to address performance issue at the network level in this case - your code's performance is simply at the mercy of network performance. With a single glaring fact - network performance is continually degrading. All the time. Always. Until it is upgraded. When the performance degradation starts all over again.
If the tables are not small (few 1000 rows each) and row volumes static, I would not consider doing a heterogeneous join. Instead I would rather go for a materialised view on the Oracle side, use a proper table and index structure, and do a local database join. -
How to build query to get tree architecture of self referencing table
Dear all,
I have the following table design :
This is a self referencing table representing a set of SubCategories which can have parent sub categories or not. I did not show here the Category table.
If the Subcategory has the ParentSubCategory ID = null, then this is a root subcategory otherwise it is a child of a parent sub category.
What I am looking for is the easy way to display the structure level by ProductCategoryID ?
Thanks for helpsyou can use a recursive logic based on CTE for that
something like this would be enough
;WITH ProdSubCat_Hiererchy
AS
SELECT psc.ProductSubCategoryID,c.CategoryName,psc.ParentSubCategoryID, psc.Name,CAST(psc.Name AS varchar(max)) AS [Path],1 AS [level]
FROM ProductSubCategory psc
INNER JOIN Category c
ON c.CategoryID = psc.ProductCategoryID
WHERE psc.ParentSubCategoryID IS NULL
UNION ALL
SELECT psc.ProductSubCategoryID,c.CategoryName,psc.ParentSubCategoryID, psc.Name,CAST(psch.[Path] + '/' + psc.Name AS varchar(max)) AS [Path],psch.[level] + 1
FROM ProductSubCategory psc
INNER JOIN Category c
ON c.CategoryID = psc.ProductCategoryID
INNER JOIN ProdSubCat_Hiererchy psch
ON psch.ProductSubCategoryID = psc.ParentSubCategoryID
SELECT *
FROM ProdSubCat_Hiererchy
ORDER BY LEFT([Path],CHARINDEX('/',[Path]+'/')-1),[Level]
OPTION (MAXRECURSION 0)
Please Mark This As Answer if it helps to solve the issue Visakh ---------------------------- http://visakhm.blogspot.com/ https://www.facebook.com/VmBlogs -
SQL text parsing to obtains referenced tables and columns
I wonder if anyone has a method of scanning an SQL statement to retrieve tables and columns referenced. EG:
select
f.cola, f.colb, f.colc, b.cold
from
foo f, bar b
where
f.cola=b.cola and f.colb=b.colb
order by f.colz, b.colawould provide
Tables
foo
bar
Columns
foo.cola [SELECT] [WHERE]
foo.colb [SELECT] [WHERE]
foo.colc [SELECT]
foo.colz [ORDER BY]
bar.cola [WHERE] [ORDER BY]
bar.colb [WHERE]
bar.cold [SELECT]The reason is that I'd like to query through several SQL scripts and validate tables and columns in a new version of the ERP system existThat query with date substitution should also work. Are you seeing some errors?
SQL> explain plan for select * from scott.emp where hiredate = to_date(':some_date', 'dd-mon-yyyy') ;
Explained.
SQL> @utlxpls
PLAN_TABLE_OUTPUT
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 1 | 40 | 2 |
|* 1 | TABLE ACCESS FULL | EMP | 1 | 40 | 2 |
Predicate Information (identified by operation id):
1 - filter("EMP"."HIREDATE"=TO_DATE(':some_date','dd-mon-yyyy'))
Note: cpu costing is off
14 rows selected.
SQL> -
ORA-02291 during MERGE on self-referenced table
Hello,
I encountered error ORA-02291 when I tried to use MERGE statement on the table with "self-referenced" foreign key. Using the foreign key deferrable did not help. The only one thing, which helped me, was using errorlog table. See the demonstration:
Working as common user:
SQL> CONNECT scott/tiger
First of all, I create table and (not deferrable) constraints:
CREATE TABLE fkv (
id NUMBER(1) CONSTRAINT nn_fkv_id NOT NULL,
parent_id NUMBER(1) CONSTRAINT nn_fkv_paid NOT NULL
ALTER TABLE fkv ADD CONSTRAINT pk_fkv_id PRIMARY KEY (id);
ALTER TABLE fkv ADD CONSTRAINT fk_fkv_paid FOREIGN KEY (parent_id) REFERENCES fkv(ID) NOT DEFERRABLE;
INSERT is working well:
INSERT INTO fkv (
id,
parent_id
SELECT
1,
1
FROM
DUAL;
COMMIT;
1 rows inserted.
commited.
MERGE statement using UPDATE branch is working well too:
MERGE INTO fkv USING (
SELECT
1 AS ID,
1 AS PARENT_ID
FROM
DUAL
) a
ON (
fkv.id = a.id
WHEN MATCHED THEN
UPDATE SET
fkv.parent_id = a.parent_id
WHERE
A.ID IS NOT NULL
DELETE WHERE a.id IS NULL
WHEN NOT MATCHED THEN
INSERT (
ID,
parent_id
VALUES (
A.ID,
A.PARENT_ID);
COMMIT;
1 rows merged.
commited.
And now is coming the strange behaviour:
MERGE INTO fkv USING (
SELECT
2 AS id,
2 AS PARENT_ID
FROM
DUAL
) a
ON (
fkv.id = a.id
WHEN MATCHED THEN
UPDATE SET
fkv.parent_id = a.parent_id
WHERE
A.ID IS NOT NULL
DELETE WHERE a.id IS NULL
WHEN NOT MATCHED THEN
INSERT (
ID,
parent_id
VALUES (
A.ID,
A.PARENT_ID);
SQL Error: ORA-02291: integrity constraint (SCOTT.FK_FKV_PAID) violated - parent key not found
ROLLBACK;
rollback complete.
Ok, even it is not a good solution, I try deferrable constraint:
ALTER TABLE fkv DROP CONSTRAINT fk_fkv_paid;
ALTER TABLE fkv ADD CONSTRAINT fk_fkv_paid FOREIGN KEY (parent_id) REFERENCES fkv(id) DEFERRABLE INITIALLY DEFERRED;
table FKV altered.
table FKV altered.
MERGE INTO fkv USING (
SELECT
2 AS id,
2 AS PARENT_ID
FROM
DUAL
) a
ON (
fkv.id = a.id
WHEN MATCHED THEN
UPDATE SET
fkv.parent_id = a.parent_id
WHERE
A.ID IS NOT NULL
DELETE WHERE a.id IS NULL
WHEN NOT MATCHED THEN
INSERT (
ID,
parent_id
VALUES (
A.ID,
A.PARENT_ID);
1 rows merged.
COMMIT;
SQL Error: ORA-02091: transaction rolled back
ORA-02291: integrity constraint (SCOTT.FK_FKV_PAID) violated - parent key not found
... deffered constraint did not help :-(
Let's try another way - errorlog table; for the first with the not deferrable constraint again:
ALTER TABLE fkv DROP CONSTRAINT fk_fkv_paid;
ALTER TABLE fkv ADD CONSTRAINT fk_fkv_paid FOREIGN KEY (parent_id) REFERENCES fkv(ID) NOT DEFERRABLE;
table FKV altered.
table FKV altered.
BEGIN
sys.dbms_errlog.create_error_log (
dml_table_name => 'FKV',
err_log_table_name => 'ERR$_FKV'
END;
anonymous block completed
Toys are prepared, let's start with error logging:
MERGE INTO fkv USING (
SELECT
2 AS id,
2 AS PARENT_ID
FROM
DUAL
) a
ON (
fkv.id = a.id
WHEN MATCHED THEN
UPDATE SET
fkv.parent_id = a.parent_id
WHERE
A.ID IS NOT NULL
DELETE WHERE a.id IS NULL
WHEN NOT MATCHED THEN
INSERT (
ID,
parent_id
VALUES (
A.ID,
A.PARENT_ID)
LOG ERRORS INTO err$_fkv;
1 rows merged.
Cannot belive, running SELECT for confirmation:
SELECT * FROM err$_fkv;
SELECT * FROM fkv;
no rows selected
ID PARENT_ID
1 1
2 2
Ok, COMMIT:
COMMIT;
commited.
SELECT for confirmation again:
SELECT * FROM err$_fkv;
SELECT * FROM fkv;
no rows selected
ID PARENT_ID
1 1
2 2
Using deffered constraint and error logging is working well too.
Metalink and Google did not help me. I am using databases 10.2.0.5 and 11.2.0.3.
Has somebody encountered this problem too or have I missed something?
Thank you
D.drop table fkv;
CREATE TABLE fkv (
id NUMBER(1) CONSTRAINT nn_fkv_id NOT NULL,
parent_id NUMBER(1) CONSTRAINT nn_fkv_paid NOT NULL
CREATE INDEX PK_FKV_ID ON FKV(ID);
ALTER TABLE fkv ADD CONSTRAINT pk_fkv_id PRIMARY KEY (id);
ALTER TABLE FKV ADD CONSTRAINT FK_FKV_PAID FOREIGN KEY (PARENT_ID) REFERENCES FKV(ID);Now run your MERGE statement and it works with non deferrable constraints.
Personally, I would contact support about this before depending on it in production.
P.S. I was not able to reproduce your findings that dropping and re-adding the constraints changes things. I suspect that when you dropped the constraint the index was NOT dropped, so you kept a non-unique index.
Try again using ALTER TABLE FKV DROP CONSTRAINT PK_FKV_ID drop index; -
Create a link in a table calls sql statement
Hello,
I'm very new to htmldb but need to complete a project within a tight timeline. I created a sql report in a region. On each row, I have an on/off link, which used to trigger a sql statement. It turns a flag on and off in a table. Key needs to be passed with the link to be used in sql. How do I passed the key in the link and how can I call the sql statement? Where can I put the sql statement? Can someone give me some tips?
Your help is greatly appreciated!
Junif you take a look at the "Understanding URL Syntax" section in chapter 6 of our User Guide, you'll see that you can set item values in html db via the URL by passing name/value pairs through the url. to see it in action, use our "Report with links to form on a table (2 Pages)" wizard to generate a form and a report on some table of yours. when you run that report page and click an edit link on it, you'll see how it passes its values to the form page using our URL syntax. in your case you'd want to create an item like MY_PROD_KEY_ITEM and set its value via your link. you'd then run your pl/sql block referring to the value of that item. when doing so, you'd probably want to use the bind variable syntax that's also explained in chapter 6, "Referencing Session State".
--raj -
Populating JTable table from sql statement.
Trying to teach myself a combanation of things. Since Oracle is my background java to oracle is only a natural. Now this code I'm trying to select some rows and then display those rows in a table. Simple concept as a teaching aid to me. I won't go into what I went through to get this far, just say there have been quite a few fall starts. Now this code works; however it returns ten rows (one for each tablespace) and displays row 1 ten times. Not quite what I had in mind.
I have got a simple select statment in my code:
select tablespace_name,initial_extent,next_extent,pct_increase, status
from dba_tablespaces order by tablespace_name
package TableTest;
// java imports
import java.util.Vector;
import java.awt.event.*;
import java.awt.Toolkit;
import java.awt.*;
import javax.swing.*;
// sql imports
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.DriverManager;
public class TableTest extends JFrame
Connection conn; // database connection object
Statement stmt; // statement object
ResultSet rslt; // result set object
//private vars
private String userName = "bubbalouie";
private String password = "helpmeimsinking";
private String sid = "rob";
private String port = "1521";
private String server = "w2sd001";
private String connectString = "jdbc:oracle:thin:@"+server+":"+port+":"+sid;
private int numCols = 5;
private String sqlStmt = null;
private String status = null;
public TableTest()
// Get content pane
Container contentPane = getContentPane();
// set layout manager
contentPane.setLayout(new BorderLayout());
// create some places to put dat
Vector data = new Vector();
Vector columns = new Vector();
Vector colHeads = new Vector();
colHeads.addElement("tablespace name"); // this is ugly fix later
colHeads.addElement("initial extent");
colHeads.addElement("next extent");
colHeads.addElement("pct increase");
colHeads.addElement("status");
// construct a simple sql statement
sqlStmt = "select tablespace_name, initial_extent, next_extent, pct_increase, status";
sqlStmt = sqlStmt+" from dba_tablespaces order by tablespace_name";
try
// connect to database
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection(connectString, userName, password);
// select data into object
stmt = conn.createStatement();
rslt = stmt.executeQuery(sqlStmt);
while (rslt.next())
for ( int i=0; i<numCols; i++ )
columns.addElement(rslt.getObject(i+1)); // get the i+1 object
} // end for
data.addElement(columns);
} // end while
// create the table
JTable table = new JTable(data,colHeads);
// add table to scroll pane
int v = ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED;
int h = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED;
JScrollPane jsp = new JScrollPane(table,v,h);
// Add scroll pane to content pane
contentPane.add(jsp, BorderLayout.CENTER);
} catch (SQLException ex)
String msg = "SQL error: "+ex.toString();
} catch (Exception ex)
String msg = "Error: "+ex.toString();
} // end constructor
public static void main(String[] args) {
TableTest frame = new TableTest();
frame.setSize(500, 400);
frame.setTitle("TableTest");
frame.setVisible(true);
} // TableTest end classif you are interested here is a generic table model for displaying ResultSets in a JTable. The resultset needs to support calling resultset meta data and the basic methods in there but then it should support anything you give it.
import java.sql.*;
import java.util.*;
import javax.swing.table.*;
public class ResultSetTableModel extends AbstractTableModel{
Vector rows;
int[] types;
String[] names;
public ResultSetTableModel(ResultSet rs)throws SQLException{
ResultSetMetaData rsmd = rs.getMetaData();
types = new int[rsmd.getColumnCount()];
names = new String[rsmd.getColumnCount()];
for(int n=0;i<types.length;n++){
types[n] = rsmd.getColumnType(n+1);
names[n] = rsmd.getColumnName(n+1);
rows = new Vector();
while(rs.next()){
Vector aRow = new Vector();
for(int j=0;j<types.length;j++){
switch(types[j]){
case Types.TINYINT:
aRow.addElement(new Byte(rs.getByte(j+1)));
break;
case Types.SMALLINT:
aRow.addElement(new Short(rs.getShort(j+1)));
break;
case Types.INTEGER:
aRow.addElement(new Integer(rs.getInt(j+1)));
break;
case Types.BIGINT:
aRow.addElement(new Long(rs.getLong(j+1)));
break;
case Types.REAL:
aRow.addElement(new Float(rs.getFloat(j+1)));
break;
case Types.FLOAT:
aRow.addElement(new Double(rs.getDouble(j+1)));
break;
case Types.DOUBLE:
aRow.addElement(new Double(rs.getDouble(j+1)));
break;
case Types.DECIMAL:
aRow.addElement(rs.getBigDecimal(j+1));
break;
case Types.NUMERIC:
aRow.addElement(new Long(rs.getLong(j+1)));
break;
case Types.BIT:
aRow.addElement(new Boolean(rs.getBoolean(j+1)));
break;
case Types.BINARY:
aRow.addElement(rs.getBytes(j+1));
break;
case Types.DATE:
aRow.addElement(rs.getDate(j+1));
break;
case Types.TIME:
aRow.addElement(rs.getTime(j+1));
break;
case Types.TIMESTAMP:
aRow.addElement(rs.getTimestamp(j+1));
break;
default:
aRow.addElement(rs.getString(j+1));
rows.addElement(aRow);
public Class getColumnClass(int column){
switch(types[column]){
case Types.BIT:
return Boolean.class;
case Types.DATE:
return java.sql.Date.class;
case Types.TIME:
return java.sql.Time.class;
case Types.TIMESTAMP:
return java.sql.Timestamp.class;
default:
return Object.class;
public int getRowCount(){
return rows.size();
public int getColumnCount(){
return types.length;
public Object getValueAt(int row, int column){
Vector aRow = (Vector) rows.elementAt(row);
return aRow.elementAt(column);
public String getColumnName(int column){
return names[column];
} -
Request: PL/SQL, External Table and SQL Loader
I see lately Questions asked in SQL and PL/SQL forum regarding SQL Loader and External Table are being moved to {forum:id=732}.
Being an PL/SQL developer for some time now i feel External Table (and if i may, SQL Loader and DBMS_DATAPUMP) are very much an integral part of a PL/SQL development and the question related to these topics are well suited in SQL and PL/SQL forum. Even in SQL and PL/SQL FAQ we have exclusive content that discuss on these topics {message:id=9360007}
So i would like to request the moderators to consider not moving such questions out of the SQL and PL/SQL forum.
Thanks,
Karthick.Karthick_Arp wrote:
I see lately Questions asked in SQL and PL/SQL forum regarding SQL Loader and External Table are being moved to {forum:id=732}.
Being an PL/SQL developer for some time now i feel External Table (and if i may, SQL Loader and DBMS_DATAPUMP) are very much an integral part of a PL/SQL development and the question related to these topics are well suited in SQL and PL/SQL forum. Even in SQL and PL/SQL FAQ we have exclusive content that discuss on these topics {message:id=9360007}
So i would like to request the moderators to consider not moving such questions out of the SQL and PL/SQL forum.
Thanks,
Karthick.Not sure which moderators are moving them... cos it ain't me. I'm quite happy to leave those there.
Maybe you are looking for
-
The version I am using is 3.6.11 The file is stored in the server in the format "Microsoft Office Excel 97-2003 Worksheet" But when I download it, it gets saved in the unrecognized format type "File" The servlet code written to download the file sets
-
can anyone help me ...i can burn a cd-rw on my e mac just fine ......open up on a pc and see the information , but it wont appear on my computer. any suggestions as to why or how i can fixed this ? cd-r seem to be fine, but not a re recordable disc
-
Can't create iPhoto Books and Calendars
I have OS10.10 on a 3.1 GHZ Core i7 iMac. It is a new machine and works very well. When I try to create a calendar or book for order in iPhoto nothing happens. It creates an album but beyond that I can not do anything. Anyone else have this proble
-
Adobe Illustrator could not complete the requested operation
I have just installed Adobe CS6 Design Standard and Illustrator won't open. It gets a message "could not complete the requested operation" and the program won't open. I can't figure out what's wrong. Tried to reinstall - no change. Tried to re-co
-
Hello, Can someone give me the sql to determine what tables and or tablespaces are say 15% fragmented? I'm on Oracle 9i. thanks...