Check constraint/foreign key combination

I would like to add a constraint (check, FK, or otherwise) that forces a value to be either -1 OR be in a foreign table.  The statement below is invalid because you can't use subqueries, but I think it's clear what I'm trying to do.  Can anyone
suggest a different approach?
Thanks!
ALTER TABLE cfg.ClientFieldThreshold ADD CONSTRAINT CK_cfg_ClientFieldThreshold_DBListID
CHECK (DBListID = -1 OR DBListID IN (SELECT ID FROM dbo.vwClientDatabases)
/* the subquery here isn't allowed */

3 ways to do this. 
1) use NULL instead of -1 as the value that does not have to be in the foreign table.  Then you just need a normal foreign key (because a foreign key column that contains NULL is not checked against the foreign table.  Sample code to do this
Create Table FooParent(ParentID int primary key);
Create Table FooChild(ChildId int primary key, ParentID int Null, Constraint FooChildFK Foreign Key(ParentID) References FooParent);
go
-- Can add row with NULL
Insert FooChild(ChildId, ParentID) Values (1, Null);
go
-- But cannot add row with any other value that is not in FooParent
Insert FooChild(ChildId, ParentID) Values (2, 25);
go
-- Check result
Select * From FooChild;
go
Drop Table FooChild;
go
Drop Table FooParent;
2) Add a dummy row to the parent table with a primary key of -1.  Then, of course, all you need is a foreign key constraint.
3) Add a persisted computed column that is NULL whenever your column that you want to enforce the constraint against is equal to -1, otherwise just the value in that column.  Then create a foreign key on the computed column.  Sample code
Create Table FooParent(ParentID int primary key);
Create Table FooChild(ChildId int primary key, ParentID int Not Null, AlteredParentID As NULLIF(ParentID, -1) Persisted, Constraint FooChildFK Foreign Key(AlteredParentID) References FooParent);
go
-- Can add row with -1
Insert FooChild(ChildId, ParentID) Values (1, -1);
go
-- But cannot add row with any other value that is not in FooParent
Insert FooChild(ChildId, ParentID) Values (2, 25);
go
-- Check result
Select * From FooChild;
go
Drop Table FooChild;
go
Drop Table FooParent;
Tom

Similar Messages

  • Bug: no constraints/foreign keys when Scripter.Prefetch = true

    Kind of bug report, using assemblies version v11.0.0.0 and ScriptingOptions.DriAll = true.
    When you have tables with foreign keys or other constraints, these are not scripted when you pass urns of all tables to Scripter.Script which has Prefetch property set to true. I believe this is due to a bug in prefetching.
    To workaround, set Scripter.Prefetch = false. Strange enough, passing urns of subset of the tables works as well (even excluding one table only), which results in the "constraints are returned when passing single urn only" reported behavior.

    Hi, sure, sorry for late reply.
    This is the DB create script:
    DROP DATABASE [TestDB]
    USE [master]
    GO
    CREATE DATABASE [TestDB] CONTAINMENT = NONE ON PRIMARY
    ( NAME = N'TestDB', FILENAME = N'C:\Windows\Temp\Test.mdf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON
    ( NAME = N'TestLG', FILENAME = N'C:\Windows\Temp\Test.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
    GO
    ALTER DATABASE [TestDB] SET COMPATIBILITY_LEVEL = 110
    GO
    ALTER DATABASE [TestDB] SET ANSI_NULL_DEFAULT OFF
    ALTER DATABASE [TestDB] SET ANSI_NULLS OFF
    ALTER DATABASE [TestDB] SET ANSI_PADDING OFF
    ALTER DATABASE [TestDB] SET ANSI_WARNINGS OFF
    ALTER DATABASE [TestDB] SET ARITHABORT OFF
    ALTER DATABASE [TestDB] SET AUTO_CLOSE OFF
    ALTER DATABASE [TestDB] SET AUTO_CREATE_STATISTICS ON
    ALTER DATABASE [TestDB] SET AUTO_SHRINK OFF
    ALTER DATABASE [TestDB] SET AUTO_UPDATE_STATISTICS ON
    ALTER DATABASE [TestDB] SET CURSOR_CLOSE_ON_COMMIT OFF
    ALTER DATABASE [TestDB] SET CURSOR_DEFAULT GLOBAL
    ALTER DATABASE [TestDB] SET CONCAT_NULL_YIELDS_NULL OFF
    ALTER DATABASE [TestDB] SET NUMERIC_ROUNDABORT OFF
    ALTER DATABASE [TestDB] SET QUOTED_IDENTIFIER OFF
    ALTER DATABASE [TestDB] SET RECURSIVE_TRIGGERS OFF
    ALTER DATABASE [TestDB] SET DISABLE_BROKER
    ALTER DATABASE [TestDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
    ALTER DATABASE [TestDB] SET DATE_CORRELATION_OPTIMIZATION OFF
    ALTER DATABASE [TestDB] SET TRUSTWORTHY OFF
    ALTER DATABASE [TestDB] SET ALLOW_SNAPSHOT_ISOLATION OFF
    ALTER DATABASE [TestDB] SET PARAMETERIZATION SIMPLE
    ALTER DATABASE [TestDB] SET READ_COMMITTED_SNAPSHOT OFF
    ALTER DATABASE [TestDB] SET HONOR_BROKER_PRIORITY OFF
    ALTER DATABASE [TestDB] SET RECOVERY SIMPLE
    ALTER DATABASE [TestDB] SET MULTI_USER
    ALTER DATABASE [TestDB] SET PAGE_VERIFY CHECKSUM
    ALTER DATABASE [TestDB] SET DB_CHAINING OFF
    ALTER DATABASE [TestDB] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )
    ALTER DATABASE [TestDB] SET TARGET_RECOVERY_TIME = 0 SECONDS
    ALTER DATABASE [TestDB] SET READ_WRITE
    GO
    USE [TestDB]
    GO
    CREATE TABLE [dbo].[KeySource] (
    [ID] [smallint] IDENTITY(1,1) NOT NULL,
    CONSTRAINT [PK_Reservation] PRIMARY KEY CLUSTERED ([ID] ASC)
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    CREATE TABLE [dbo].[KeyUse] (
    [UseID] [smallint] NOT NULL,
    [Row] [tinyint] NOT NULL,
    [Column] [tinyint] NOT NULL,
    CONSTRAINT [PK_KeySource] PRIMARY KEY CLUSTERED ([UseID] ASC, [Row] ASC, [Column] ASC)
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
    CONSTRAINT [IX_ReservationSeats] UNIQUE NONCLUSTERED ([Row] ASC, [Column] ASC)
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    ALTER TABLE [dbo].[KeyUse] WITH CHECK ADD CONSTRAINT [FK_Source_Use] FOREIGN KEY([UseID]) REFERENCES [dbo].[KeySource] ([ID])
    ON UPDATE CASCADE
    ON DELETE CASCADE
    ALTER TABLE [dbo].[KeyUse] CHECK CONSTRAINT [FK_Source_Use]
    ALTER TABLE [dbo].[KeyUse] WITH CHECK ADD CONSTRAINT [FK_Use_Use] FOREIGN KEY([UseID], [Row], [Column]) REFERENCES [dbo].[KeyUse] ([UseID], [Row], [Column])
    ALTER TABLE [dbo].[KeyUse] CHECK CONSTRAINT [FK_Use_Use]
    This is the code:
    ServerConnection serverConnection = new ServerConnection("server", "user", "pwd");
    Server server = new Server(serverConnection);
    Database database = server.Databases["TestDB"];
    Urn[] urns = database.EnumObjects(DatabaseObjectTypes.Table).Rows.OfType<DataRow>().Select(r => new Urn((string)r["Urn"])).Take(2).ToArray();
    Scripter s = new Scripter(server);
    s.Options.DriAll = true;
    StringCollection result = s.Script(urns);
    This is the result:
    SET ANSI_NULLS ON
    SET QUOTED_IDENTIFIER ON
    CREATE TABLE [dbo].[KeySource](
    [ID] [smallint] IDENTITY(1,1) NOT NULL
    ) ON [PRIMARY]
    SET ANSI_NULLS ON
    SET QUOTED_IDENTIFIER ON
    CREATE TABLE [dbo].[KeyUse](
    [UseID] [smallint] NOT NULL,
    [Row] [tinyint] NOT NULL,
    [Column] [tinyint] NOT NULL
    ) ON [PRIMARY]
    Note that the constraints are missing.
    As already noted, adding s.PrefetchObjects = false; line fixes this.
    But let's do the magic way - supplying less Urns than there actually is tables. To test this, add a dummy table to the DB:
    USE [TestDB]
    CREATE TABLE [dbo].[DummyTable]([Test] [nchar](10) NULL) ON [PRIMARY]
    Run the code again. Note that the Take(2) method limits the Urns supplied to the Scripter to the same set as before.
    However, the result is now:
    SET ANSI_NULLS ON
    SET QUOTED_IDENTIFIER ON
    CREATE TABLE [dbo].[KeySource](
    [ID] [smallint] IDENTITY(1,1) NOT NULL,
    CONSTRAINT [PK_Reservation] PRIMARY KEY CLUSTERED
    [ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    SET ANSI_NULLS ON
    SET QUOTED_IDENTIFIER ON
    CREATE TABLE [dbo].[KeyUse](
    [UseID] [smallint] NOT NULL,
    [Row] [tinyint] NOT NULL,
    [Column] [tinyint] NOT NULL,
    CONSTRAINT [PK_KeySource] PRIMARY KEY CLUSTERED
    [UseID] ASC,
    [Row] ASC,
    [Column] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
    CONSTRAINT [IX_ReservationSeats] UNIQUE NONCLUSTERED
    [Row] ASC,
    [Column] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    ALTER TABLE [dbo].[KeyUse] WITH CHECK ADD CONSTRAINT [FK_Source_Use] FOREIGN KEY([UseID])
    REFERENCES [dbo].[KeySource] ([ID])
    ON UPDATE CASCADE
    ON DELETE CASCADE
    ALTER TABLE [dbo].[KeyUse] CHECK CONSTRAINT [FK_Source_Use]
    ALTER TABLE [dbo].[KeyUse] WITH CHECK ADD CONSTRAINT [FK_Use_Use] FOREIGN KEY([UseID], [Row], [Column])
    REFERENCES [dbo].[KeyUse] ([UseID], [Row], [Column])
    ALTER TABLE [dbo].[KeyUse] CHECK CONSTRAINT [FK_Use_Use]
    By testing on larger database I have noticed it does not really matter which table is excluded from the list.
    Hope this helps,
    Jan

  • ORA-02292: integrity constraint - foreign key delete

    I am getting the above error message when attempting to delete an entry with a foreign key constraint. I have the standard delete button and the standard DML process for inset, update, delete, and a page validation conditioned on the delete button for EXISTS with the following code:
    select 1 from dual
    where (select count(*) from mdeccommitments
    where producer = :P25_COREID
    and receiver = :P25_COREID) = 0
    and (select count(*) from mdecbriefcal
    where primarytarget = :P25_COREID
    and primaryowner = :P25_COREID) = 0
    This code works in SQL directly. However, when I try to run this, I do not get the inline error associated with the validation routine, I just get the popup for the delete and then the very user-unfriendly Oracle error, almost as if the validation wasn't there. I tried removing the popup associated with the delete button, but it did not make a difference.
    I want to provide a friendly intercept and return. I do not want to cascade the delete. What am I missing here?
    Thanks.
    Gillian

    Thanks Varad, by running the debug, I realized I misinterpreted what the validation did - I had used EXISTS instead of NOT EXISTS. Making this change resulted in the correct processing. Being a newbie, I wasn't sufficiently familiar with the debug option to think about it.

  • To check the foreign keys

    i need to know the table which gives a mapping of foreign keys...that is the key name its own table and then the table to which it is mapped as a foreign key

    Hi 477390,
    Here is the query.
    col "Primary Table" forma a30
    col "Primary Key constraint" forma a30
    col "Child Table" forma a30
    col "Reference Key constraint" forma a30
    select a.table_name "Primary Table"
         ,a.constraint_name "Primary Key constraint"
         ,b.table_name "Child Table"
         ,b.constraint_name "Reference Key constraint"
    from      dba_constraints a
         ,dba_constraints b
    where a.constraint_name=b.r_constraint_name
    and a.owner='<SCHEMA_NAME>';
    Cheers,
    Kamalesh JK

  • Quality Check view foreign key

    Headstart Ruleframe Designer6i
    Running utility quality check view definition
    Report states that complete property for _CG foreign key must be set to "NO" to keep from being generated in DB. However if foreign key is used in formmodule error CDG-3436 is raised : " Invalid Linkage ". I'm I correct in assuming that Complete property has to be set to "YES" and Validation property to "CLIENT" to avoid the errors?

    You are correct. I will log this as a bug in the quality check report.
    Thanks,
    Lauri

  • Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths

    I am trying to introduce a constraint on the sales_details table
    ALTER TABLE [dbo].[SALES_DETAILS] WITH CHECK ADD constraint fk_sd_vat FOREIGN KEY([VAT])
    REFERENCES [dbo].[VAT Rate] ([VAT]) on update cascade on delete cascade
    GO
    I am getting the error saying
    Msg 1785, Level 16, State 0, Line 1
    Introducing FOREIGN KEY constraint 'fk_sd_vat' on table 'SALES_DETAILS' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
    Msg 1750, Level 16, State 0, Line 1
    Could not create constraint. See previous errors.
    What could be the reason,Please suggest me the solution for  this,
    Thanks,

    Hi Erland,
    This is my DDl
    CREATE TABLE [dbo].sales_details(
    [BNUM] [varchar](20) NOT NULL,
    [CNAME] [varchar](30) NOT NULL,
    [CNUM] [int] NOT NULL FOREIGN KEY([CNUM])REFERENCES [dbo].[Customer] ([CNum]),
    [ITNAME] [varchar](100) NOT NULL,
    [ITEM#] [int] NOT NULL ,
    [QTY] [int] NOT NULL,
    [UNIT] [varchar](5) NOT NULL,
    [PRICE] [float] NOT NULL,
    [BASIC] [float] NOT NULL,
    [DISCOUNT] [float] NOT NULL,
    [FRQTY] [int] NOT NULL,
    [BADDR] [varchar](300) NULL,
    [CADDR] [varchar](300) NOT NULL,
    [BDATE] [datetime] NOT NULL,
    [VAT] [float] NOT NULL
    ALTER TABLE [dbo].[SALES_DETAILS] WITH CHECK ADD constraint cons1 FOREIGN KEY([ITNAME])
    REFERENCES [dbo].[New Item] ([Item Description]) on cascade update
    GO
    ALTER TABLE [dbo].[SALES_DETAILS] WITH CHECK ADD constraint FOREIGN KEY([VAT])
    REFERENCES [dbo].[VAT Rate] ([VAT]) on cascade update
    GO
    I am getting the error when i execute second Alter statement.
    Thanks,
    Check if VAT Rate table has any FK with cascaded options?
    Please Mark This As Answer if it solved your issue
    Please Vote This As Helpful if it helps to solve your issue
    Visakh
    My Wiki User Page
    My MSDN Page
    My Personal Blog
    My Facebook Page

  • FOREIGN KEY CONSTRAINT

    HI GUYS
    I DID THE FOLL
    CREATE TABLE MASTER(EMPNO NUMBER PRIMARY KEY,
    ENAME VARCHAR2(12));
    CREATE TABLE CHILD(EMPNO NUMBER);
    ALTER TABLE CHILD ADD CONSTRAINT FOREIGN KEY REFERNCES MASTER(EMPNO)
    NOW WHEN I DOTHE ABOVE AND THE DO DESC CHILD
    I GET THE FOLL
    EMPNO NUMBER
    ENAME VARCHAR2(12)
    KEY NUMBER
    WHAT IS THIS KEY COLUMN ? WHY IS IT COMING
    KINDLY CLARIFY

    Interesting.
    The correct syntax to add a FK constraint is:
    ALTER TABLE child ADD CONSTRAINT
       FOREIGN KEY (empno) REFERENCES master (empno);I can replicate your behaviour in 9.2.0.6, and in 8.1.7.4. It appears that in the absence of a column list in parens, Oracle takes the word after FOREIGN and adds a column with that name and the appropriate data type to the table and uses that in the FK.
    SQL> CREATE TABLE master (empno NUMBER PRIMARY KEY,
      2                       ename VARCHAR2(12));
    Table created.
    SQL> CREATE TABLE child (empno NUMBER);
    Table created.
    SQL> ALTER TABLE child ADD CONSTRAINT
      2     FOREIGN new_col REFERENCES master (empno);
    Table altered.
    SQL> desc child
    Name                                      Null?    Type
    EMPNO                                              NUMBER
    NEW_COL                                            NUMBERJust to show that the constraint is enforced:
    SQL> INSERT INTO child VALUES(1,1);
    INSERT INTO child VALUES(1,1)
    ERROR at line 1:
    ORA-02291: integrity constraint (OPS$ORACLE.SYS_C0070911) violated -
    parent key not foundBut, this only works when there is no KEY keyword:
    SQL> DROP TABLE child;
    Table dropped.
    SQL> CREATE TABLE child (empno NUMBER);
    Table created.
    SQL> ALTER TABLE child ADD CONSTRAINT
      2     FOREIGN KEY new_col REFERENCES master (empno);
       FOREIGN KEY new_col REFERENCES master (empno)
    ERROR at line 2:
    ORA-00902: invalid datatypeOn a fast scan of the documentation I don't see where this behaviour is documented, and I have certainly never seen this before. Anyone out there have any thoughts?
    John

  • How to get Multiple Key Combinations

    Hi,
    I am trying to get the event for multiple key combinations, ie some thing like "*Ctrl + I + M*" or "*Alt + A + S + D*".
    For two key combinations ( like Ctrl+I or Ctrl+M) i am able to get, but for more than two keys combinations, can someone give an idea how to get it.
    I tried with both KeyCodeCombination and KeyCharacterCombination.
    Below is a quick example to check for the key combination demo.
    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.input.KeyCharacterCombination;
    import javafx.scene.input.KeyCode;
    import javafx.scene.input.KeyCodeCombination;
    import javafx.scene.input.KeyCombination;
    import javafx.scene.input.KeyEvent;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    public class KeyCombinationDemo extends Application {
         Stage stage;
         Scene scene;
         StackPane root;
         public static void main(String[] args) {
              Application.launch(args);
         @Override
         public void start(Stage stage) throws Exception {
              this.stage = stage;
              root = new StackPane();
              root.getChildren().add(new Label("Enter any Key"));
              this.scene = new Scene(root, Color.LINEN);
              stage.setTitle(this.getClass().getSimpleName());
              stage.setWidth(600);
             stage.setHeight(600);
             stage.setScene(this.scene);
             stage.show();
              final KeyCombination keyComb1=new KeyCodeCombination(KeyCode.I,KeyCombination.CONTROL_DOWN);
              final KeyCharacterCombination keyComb2 = new KeyCharacterCombination("M",KeyCombination.CONTROL_DOWN);
              this.scene.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
                   @Override
                   public void handle(KeyEvent event) {
                        if(keyComb1.match(event)){
                             System.out.println("Ctrl+I pressed");
                        }else if(keyComb2.match(event)){
                             System.out.println("Ctrl+M pressed");
    }Thanks in Advance.
    Regards,
    Sai Pradeep Dandem.

    Hi John,
    Thanks for the prompt response.
    I tried the way you suggested and it worked well !! Thanks :)
    But, still i am expecting a direct way to handle this. :p
    Anyway here is code which i modified accordingly
    final String keyCombination1 = "_ALT_E_O";
    final String keyCombination2 = "_ALT_E_P";
    final String keyCombination3 = "_CONTROL_H";
    final StringBuilder key = new StringBuilder();
    this.scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
         @Override
         public void handle(KeyEvent event) {
              String codeStr = event.getCode().toString();
              if(!key.toString().endsWith("_"+codeStr)){
                   key.append("_"+codeStr);
    this.scene.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
         @Override
         public void handle(KeyEvent event) {
              if(key.length()>0){
                   if(key.toString().equals(keyCombination1)){
                        System.out.println("Key Combination 1 pressed");
                   }else if(key.toString().equals(keyCombination2)){
                        System.out.println("Key Combination 2 pressed");
                   }else if(key.toString().equals(keyCombination3)){
                        System.out.println("Key Combination 3 pressed");
                   key.setLength(0);
    });Thanks & Regards,
    Sai Pradeep Dandem

  • SQl*Modeler - foreign key amendment error

    SQl*Modeler 2.0.0 Build 584 (Windows)
    Oracle 10.2.0.4 Solaris
    If I change an existing foreign key to simply change the delete rule (from say CASCADE to RESTRICT) it changes in memory just fine. If I generate the DDL the change has happened and I get the expected DDL.
    However, I then save the model, exit SQL*Modeler, start SQL*Modeler and check the foreign key the change has been lost.
    I can workaround this by changing the name of the foreign key and the change is saved correctly. Feature ?
    Ian

    Hi Ian,
    I logged bug for that.
    You can use foreign key dialog to do that change without need to change the name - just double-click on FK line or presentation in the browser.
    Philip

  • Create a foreign key from a field that is part of a mulitple primary key

    Hi,
    i had a table named T_A, with a double primary key : (A,B)
    Then i created a table named T_B with a field : C.
    I want this field T_B.C to take only values that already exist in field T_A.A.
    So i tried to create a foreign key on my field T_B.C, pointing on the field T_A.A : an error message appeared "not possible to create a foreign key on a field that is not a primary key".
    How can i solve this....? If U have any idea, please mail me !!
    THANX very much.

    Add column A as foreign key into the table T_BHow?
    (was the question from the original poster. Adding a column to table T_B that happen to have same name as the corresponding column in table T_A would not allow you to add the foreign key).
    SQL> create table t_a (a number, b number, primary key(a, b)) ;
    Table created.
    SQL> create table t_b(a number, c number, constraint foreign key references t_a(a)) ;
    create table t_b(a number, c number, constraint foreign key references t_a(a))
    ERROR at line 1:
    ORA-02270: no matching unique or primary key for this column-list
    SQL>

  • Is this a BUG???  Database Export not including Foreign Key Constraints

    I'm using SQL Developer 1.5.4 with both the 59.47 and 59.59 patches installed. I want to do a database export from a 10g XE schema, and include all objects in the resulting DDL. So, I select ALL the checkboxes in the export wizard and when I get to Step 3 to specify objects, I don't see any of my constraints in the listbox... no foreign key constraints, no primary key constraints, no check constraints, nothing. Is this a bug, or is there a workaround, or what could I possibly be doing wrong? We want to be able to use the database export feature to easily transport and track modifications to our entire schema using source control compare.
    Any help or alternate suggestions would be apprieciated.
    Thanks,
    Matt

    Thanks skutz, we just figured that out this morning. Also, it should be noted that you need to be logged in as the owner of the schema otherwise selecting nothing in the filter will give you nothing, but selecting items in the filter will give you those items even if you're not connected as the schema owner. I wonder if that is the detail of the Bug 8679318.
    Edited by: mattsnyder on Jul 14, 2009 9:24 AM

  • Foreign key mapped to a unique constraint

    ok here is the issue
    create table parent(col1 char, col2 char);
    alter table parent add constraint pk_parent primary key(col1);
    alter table parent add constraint uk_parent unique(col1,col2);
    insert into parent values('A','7');
    *1 row created.*
    create table child(col1 char, col2 char);
    alter table child add constraint fk_child_parent foreign key(col1,col2) references parent(col1,col2);
    insert into child values('B','4');
    insert into child values('B','4')
    ERROR at line 1:
    ORA-02291: integrity constraint (WILDGOD.FK_CHILD_PARENT) violated - parent key
    not found
    thats what i expect....but
    insert into child values('B',NULL);
    *1 row created.*
    why does it let me do this, i realize its because col2 is NULL but shouldnt it still check for col1 to be in the parent?
    Please clarify, thanks in advance.

    I see the same & am not sure why either.
    SQL> @a
    SQL> create table parent(col1 char, col2 char);
    Table created.
    SQL> alter table parent add constraint pk_parent primary key(col1);
    Table altered.
    SQL> alter table parent add constraint uk_parent unique(col1,col2);
    Table altered.
    SQL>
    SQL> insert into parent values('A','7');
    1 row created.
    SQL> create table child(col1 char, col2 char);
    Table created.
    SQL> alter table child add constraint fk_child_parent foreign key(col1,col2) references parent(col1,col2);
    Table altered.
    SQL>
    SQL> insert into child values('B','4');
    insert into child values('B','4')
    ERROR at line 1:
    ORA-02291: integrity constraint (DBADMIN.FK_CHILD_PARENT) violated - parent key not found
    SQL>
    SQL> insert into child values('B',NULL);
    1 row created.
    SQL>
    SQL> select * from v$version;
    BANNER
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    PL/SQL Release 11.2.0.1.0 - Production
    CORE     11.2.0.1.0     Production
    TNS for Linux: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production

  • Using FOreign key constraints on tables in database.

    I am student and novice in the field of ORACLE and PL/SQL and Database Creation. I had created a database consisting tables and got problem while applying foreign key constraints.
    CUST_MSTR
    CREATE TABLE "DBA_BANKSYS"."CUST_MSTR"("CUST_NO" VARCHAR2(10),
    "FNAME" VARCHAR2(25), "MNAME" VARCHAR2(25), "LNAME" VARCHAR2(25),
    "DOB_INC" DATE NOT NULL,      "OCCUP" VARCHAR2(25), "PHOTOGRAPH" VARCHAR2(25),
    "SIGNATURE" VARCHAR2(25), "PANCOPY" VARCHAR2(1),      "FORM60" VARCHAR2(1));
    (CUST_NO is PRIMARY KEY, )
    -- EMP_MSTR
    CREATE TABLE "DBA_BANKSYS"."EMP_MSTR"("EMP_NO" VARCHAR2(10),
    "BRANCH_NO" VARCHAR2(10), "FNAME" VARCHAR2(25), "MNAME" VARCHAR2(25),
    "LNAME" VARCHAR2(25), "DEPT" VARCHAR2(30), "DESIG" VARCHAR2(30));
    (EMP_NO is primary key )
    --NOMINEE_MSTR
    CREATE TABLE "DBA_BANKSYS"."NOMINEE_MSTR"("NOMINEE_NO" VARCHAR2(10),
    "ACCT_FD_NO" VARCHAR2(10), "NAME" VARCHAR2(75), "DOB" DATE,
    RELATIONSHIP" VARCHAR2(25));
    (NOMINEE_NO is primary key )
    --ADDR_DTLS
    CREATE TABLE "DBA_BANKSYS"."ADDR_DTLS"("ADDR_NO" NUMBER(6),
    "CODE_NO" VARCHAR2(10),      "ADDR_TYPE" VARCHAR2(1), "ADDR1" VARCHAR2(50),
    "ADDR2" VARCHAR2(50), "CITY" VARCHAR2(25), "STATE" VARCHAR2(25),
    "PINCODE" VARCHAR2(6));
    ( ADDR_NO is primary key )
    Problem: I want to apply foreign key constraints on ADDR_DTLS table so that Before inserting value in ADDR_DTLS table it must check, VALUE in ADDR_DTLS.CODE_NO must be PRESENT either in attribute value CUST_MSTR.CODE_NO or EMP_MSTR.CODE_NO or NOMINEE_MSTR.CODE_NO table .
    I applied the foreign key constraints using this syntax
    CREATE TABLE "DBA_BANKSYS"."ADDR_DTLS"("ADDR_NO" NUMBER(6),
    "CODE_NO" VARCHAR2(10),      "ADDR_TYPE" VARCHAR2(1), "ADDR1" VARCHAR2(50),
    "ADDR2" VARCHAR2(50), "CITY" VARCHAR2(25), "STATE" VARCHAR2(25),
    "PINCODE" VARCHAR2(6),
    constraints fk_add foreign key CODE_NO references CUST_MSTR. CODE_NO,
    constraints fk_add1 foreign key CODE_NO references EMP_MSTR. CODE_NO,
    constraints fk_add2 foreign key CODE_NO references NOMINEE_MSTR.CODE_NO);
    (foreign key)
    ADDR_DTLS.CODE_NO ->CUST_MSTR.CUST_NO
    ADDR_DTLS.CODE_NO ->NOMINEE_MSTR.NOMINEE_NO
    ADDR_DTLS.CODE_NO ->BRANCH_MSTR.BRANCH_NO
    ADDR_DTLS.CODE_NO ->EMP_MSTR.EMP_NO
    When I applied foreign key constraints this way, its gives a error called foreign key constraints violation. (I understand that, its searches the attribute value of ADDR_DTLS.CODE_NO in all the three tables must be present then the value will be inserted. But I want, if the value is in any of the three table then its should insert the value or its gives an error.)
    Please help me out, though i put the question and i want too know how to apply the forign key in this way. and is there any other option if foreign key implementation is not pssible.

    If you are on 11g you can use ON DELETE SET NULL:
    CREATE TABLE addr_dtls
    ( addr_no          NUMBER(6)  CONSTRAINT addr_pk PRIMARY KEY
    , addr_cust_no     CONSTRAINT addr_cust_fk    REFERENCES cust_mstr    ON DELETE SET NULL
    , addr_emp_no      CONSTRAINT addr_emp_fk     REFERENCES emp_mstr     ON DELETE SET NULL
    , addr_nominee_no  CONSTRAINT addr_nominee_fk REFERENCES nominee_mstr ON DELETE SET NULL
    , addr_type        VARCHAR2(1)
    , addr1            VARCHAR2(50)
    , addr2            VARCHAR2(50)
    , city             VARCHAR2(25)
    , state            VARCHAR2(25)
    , pincode          VARCHAR2(6) );In earlier versions you'll need to code some application logic to do something similar when a parent row is deleted, as otherwise the only options are to delete the dependent rows or raise an error.
    btw table names can be up to 30 characters and don't need to end with MSTR or DTLS, so for example CUSTOMERS and ADDRESSES might be more readable than CUST_MSTR and ADDR_DTLS. Also if the Customer/Employee/Nominee PKs are generated from a sequence they should be numeric.
    Edited by: William Robertson on Aug 15, 2010 6:47 PM

  • Re: Foreign key-type constraints

    The methodology my company has defined and uses to attack this problem is
    based upon looking for large grain 'business components' within the
    business model.
    When translating the functionality of the 'business component' to a
    physical design we end up with a component object which usually consists of
    a major entity(table) and several subsidiary entities and the services
    which operate on and maintain those entities i.e. a component object.
    We would then remove the referential integrity constraints only between the
    components - to be managed by a component reference object - but internally
    to the component leave the database referential integrity rules in place.
    I beleive this maintains idea of encapsulation as the only way to
    communicate with the component is through a defined public service
    interface. It also lessens the impact of database changes as they are
    usually confined to one componeet and the public service interface to any
    other is left intact. It makes use of the database functionality without
    dramatically effecting maintenance and performance by writing it all
    yourself and/or defining every relationship with the refence manager.
    It also leads very much to the definition of large grain reusable
    components which can be used in many applications, important to a company
    such as mine which develops software for others.
    Unfortunately it is not always as simple as it sounds, the methodology helps.
    Good database management systems with declarative referential integrity
    will usuaually prevent you from defining circular references so you could
    test for this by attempting to create the database before you remove the
    inter component links. But circular references are much less likely with
    the component technique properly applied.
    Keith Matthews
    Caro System Inc.
    www.carosys.com
    At 02:07 PM 10/23/97 +0100, John Challis wrote:
    We've been pondering the issue of how database integrity should be
    represeted within a Forte/OO app. We're thinking, in particular, about
    foreign key-type constraints.
    First of all, we're not sure whether these constraints should be on the
    database, because some would say that this represents business knowledge
    which should only be in the app. Also, if constraints are on the
    database, the errors you receive if they are violated may not be very
    useful; i.e. we're using Oracle, and we'd have to map constraint names
    in error messages to some more meaningful message to present to a user.
    If foreign key-type constraints aren't on the database, what other
    options do we have?
    Let's say there's associations between objects X, Y and Z, whereby X and
    Y both know about and use Z - we don't want to delete Z while X and Y
    exist. I accept that Z should know how to delete itself, from
    persistance, but how does it check for the existence of X and Y? If Z
    asks objects of types X and Y to check whether they exist in the
    database, you can end up with a circular reference. If you do the check
    yourself, i.e. by having SQL checking existence of X and Y within the
    delete method for Z, then I reckon you've blown encapsulation, and
    you've also got a problem in relation to impact if the shape of your
    database changes.
    We're toying with the idea of having a central integrity manager, which
    will tell Z whether it can go ahead with the delete, thus centralising
    the integrity constraint knowledge within the app. and minimising impact
    of changes to the shape of the database.
    I'd be interested to know what others have done to address this issue,
    and any thoughts you may have.
    Thanks,
    John Challis
    PanCredit
    Leeds, UK
    ** bassssss **

    At 02:07 PM 10/23/97 +0100, you wrote:
    ...>First of all, we're not sure whether these constraints should be on the
    database, because some would say that this represents business knowledge
    which should only be in the app. This is a long-winded response, but I tried to relate it to a real-world
    example, so bear with me...
    Purists may argue with me here, but I must take issue with the notion that
    your database cannot have any business knowledge. As soon as you define a
    table, you have implicitly given the database business knowledge.
    For example, suppose you define a database table Person, with columns Name,
    ID, and BirthDate. You are specifically telling the database that there
    exists a business "something" called Person which can (or must!) have
    values called Name, ID, and Birthdate. You are probably also telling the
    database about certain business rules: The value called ID can be used to
    uniquely identify a Person; The value Name contains text, and has a maximum
    length; Birthdate must conform to the format rules for something of type
    Date; etc. Need I go on?
    So, to me the argument cannot be that your database should not have any
    business knowledge, but rather, what type of business knowledge should be
    given to the database?
    On the other side of the coin, I also take exception to the argument that
    business knowledge belongs only in the Application. In fact, if your
    discussion centers around whether business knowledge belongs in the
    Application vs. the Database, then maybe both sides are still thinking in
    two tiers, and you need to take a step back and think about your business
    classes some more.
    In our oversimplified example above, we set a limit on the length of the
    Name attribute. This is a business rule, and so "belongs" to the business
    class. However, our application class needs to have knowledge of that rule
    so that it can set a limit on the length of data that it allows to be
    entered. Likewise, the persistent storage class must have knowledge of
    that rule to effectively store and retrieve the data.
    We also have an attribute that is a Date, and a date by definition must
    follow certain rules about format and value. The application class and the
    storage class will both do their job more effectively if they know that the
    attribute is a Date.
    Does it break the rules of encapsulation if you allow the application class
    or the storage class to have knowledge of certain rules that are defined in
    the business class? If it does, then we might as well throw encapsulation
    out the door, because it is a totally useless concept in the real world.
    Now, let's think about the referential constraints. Suppose you want to
    create a business class Employee which inherits from the class Person, and
    adds attributes HireDate and Department. When you physically store the
    Employee information in your Relational database, you might actually store
    two tables, with the ID as a foreign key between them. In this case, the
    foreign key relationship would clearly belong to the storage class and the
    database. The business class should not know or care whether the Employee
    information is physically stored in one table, or two, or twelve.
    Now, let's add another business rule, that Employee Department must be a
    valid department. To support this rule, you will create a business Class,
    Department. For the sake of argument, let us say that the persistent data
    for this business class will be stored in a database table, also called
    Department.
    We have said that there is a relationship between Employee and Department.
    Which business class will contain the rule that defines the relationship?
    Clearly, it is not Department. Department has no reason to know about
    Employee, or any other class that might contain a reference to it. Since
    Employee is the one that contains a reference to Department, you could
    argue that the rule belongs there. That works fine, until you want to
    delete a Department object. Obviously, you would not go to the Employee
    class for that. So it seems that the relationship does not belong in
    either class.
    Someone has suggested that you have an integrity manager or some similar
    class for that purpose. The integrity manager would have knowledge of the
    rules that define the relationships between your business objects. This
    allows you to keep your OO design more "pure" from the standpoint of
    encapsulation. Conceptually, this makes good sense, since the relationship
    between two classes does not belong to either of the individual classes.
    Let's hold that thought for a minute.
    Now let's think about your physical database design. I am betting that
    there is a high degree of correlation between your database tables and your
    business objects. It won't be 100%, because, among other things,
    relational databases do not deal well with the concept of inheritance. But
    if there is a very wide divergence, then I would need to question the
    validity of your design. With that in mind, I am going to propose that you
    already have an Integrity Manager, and that is your relational DBMS.
    My position is this, that it is ok, even necessary, for the data storage
    class to have knowledge of the structure and relationships of the data. It
    needs this information to effectively do its job. From my point of view,
    saying that you cannot tell the database that there is a relationship
    between Employee and Department is just as pointless as saying that you
    cannot tell the database that a certain column contains a date, or that
    another column contains a unique key which should be used as an index.
    Would you argue that an index implies business knowledge, and therefore
    does not belong in the database? On the other hand, you could argue that
    referential constraints always belong to the physical storage classes,
    since they describe under what circumstances data can be stored or deleted.
    Now, for performance or other reasons, you might choose not to implement
    the Employee-Department relationship in your physical database, and that's
    ok, too. Maybe you have decided that since you do not delete departments
    very often, that you do not want to incur the database overhead to maintain
    the foreign key relationship. Or maybe you have determined that the
    Department data will be stored somewhere else other than the database.
    Perhaps you would create an Integrity Manager instead, that would only be
    invoked when you wanted to delete a Department object. The point is, if
    you create an Integrity Manager, be sure you do it for the right reason,
    and not because someone has mistakenly decreed that a database cannot have
    any business knowledge.
    This brings us to the other question, which is: What do you do with the
    error if the constraint is violated? Consider this as an option: Create a
    User-defined exception named DeleteFailed or something like that. Then it
    does not matter if the error comes from the database manager or a separate
    Integrity manager. In either case, you fill the exception object with
    whatever meaningful data is appropriate, and raise the exception. The
    application, which knows what it was trying to do, can listen for the
    exception and deal with it appropriately. (btw, this is a good way to deal
    with other predictable database exceptions as well, such as DuplicateKey,
    or NotFound - your application need not listen for a particular SQL Code or
    SQL State, which might tie it to a particular database or storage format.)
    I do not see a problem with using the DBMS to define relational
    constraints. That is, after all, what a Relational database does. You do
    not need an integrity manager for OO-purity, but you can use one if it
    makes sense for other reasons. You should be able to change the method of
    enforcing the relationships, or even change the entire DBMS without having
    any impact on the application classes or the business classes. If you can
    meet that test, then as far as I am concerned, you have not violated any
    rules of encapsulation.
    Any rebuttals?
    =========================================
    Jeanne Hesler <[email protected]>
    MSF&W, Springfield, Illinois
    (217) 698-3535 ext 207
    =========================================

  • Recreating foreign key not working? two proc one to drop constraint and another to recreate foreign constraint in database?

    CREATE PROC [dbo].[SP_DropForeignKeys] 
    AS
    BEGIN
    DECLARE @FKTABLE_OWNER SYSNAME, @FKTABLE_NAME sysname, @FK_Name sysname
    DECLARE Cursor_DisableForeignKey CURSOR FOR  
    SELECT   schema_name(schema_id), object_name(parent_object_id), name
    FROM   sys.foreign_keys
    OPEN Cursor_DisableForeignKey
    FETCH NEXT FROM   Cursor_DisableForeignKey  
    INTO  @FKTABLE_OWNER  , @FKTABLE_NAME, @FK_Name 
    DECLARE @SQL nvarchar(max)
    WHILE @@FETCH_STATUS = 0   
    BEGIN  
    SET @SQL  = 'ALTER TABLE [' + @FKTABLE_OWNER + '].[' + @FKTABLE_NAME   
               + ']  DROP CONSTRAINT [' + @FK_NAME + ']'  
    select @sql
    EXECUTE (@SQL)
    FETCH NEXT FROM   Cursor_DisableForeignKey INTO @FKTABLE_OWNER, @FKTABLE_NAME, @FK_Name
    END  
    CLOSE Cursor_DisableForeignKey
    DEALLOCATE Cursor_DisableForeignKey
    END
    create proc [dbo].[SP_CreateForeignKeys]
    as
    DECLARE @schema_name sysname;
    DECLARE @table_name sysname;
    DECLARE @constraint_name sysname;
    DECLARE @constraint_object_id int;
    DECLARE @referenced_object_name sysname;
    DECLARE @is_disabled bit;
    DECLARE @is_not_for_replication bit;
    DECLARE @is_not_trusted bit;
    DECLARE @delete_referential_action tinyint;
    DECLARE @update_referential_action tinyint;
    DECLARE @tsql nvarchar(4000);
    DECLARE @tsql2 nvarchar(4000);
    DECLARE @fkCol sysname;
    DECLARE @pkCol sysname;
    DECLARE @col1 bit;
    DECLARE @action char(6);
    SET @action = 'CREATE';
    DECLARE FKcursor CURSOR FOR
        select OBJECT_SCHEMA_NAME(parent_object_id)
             , OBJECT_NAME(parent_object_id), name, OBJECT_NAME(referenced_object_id)
             , object_id
             , is_disabled, is_not_for_replication, is_not_trusted
             , delete_referential_action, update_referential_action
        from sys.foreign_keys
        order by 1,2;
    OPEN FKcursor;
    FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name
        , @referenced_object_name, @constraint_object_id
        , @is_disabled, @is_not_for_replication, @is_not_trusted
        , @delete_referential_action, @update_referential_action;
    WHILE @@FETCH_STATUS = 0
    BEGIN
              BEGIN
            SET @tsql = 'ALTER TABLE '
                      + QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)
                      + CASE @is_not_trusted
                            WHEN 0 THEN ' WITH CHECK '
                            ELSE ' WITH NOCHECK '
                        END
                      + ' ADD CONSTRAINT ' + QUOTENAME(@constraint_name)
                      + ' FOREIGN KEY ('
            SET @tsql2 = '';
            DECLARE ColumnCursor CURSOR FOR
                select COL_NAME(fk.parent_object_id, fkc.parent_column_id)
                     , COL_NAME(fk.referenced_object_id, fkc.referenced_column_id)
                from sys.foreign_keys fk
                inner join sys.foreign_key_columns fkc
                on fk.object_id = fkc.constraint_object_id
                where fkc.constraint_object_id = @constraint_object_id
                order by fkc.constraint_column_id;
            OPEN ColumnCursor;
            SET @col1 = 1;
            FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;
            WHILE @@FETCH_STATUS = 0
            BEGIN
                IF (@col1 = 1)
                    SET @col1 = 0
                ELSE
                BEGIN
                    SET @tsql = @tsql + ',';
                    SET @tsql2 = @tsql2 + ',';
                END;
                SET @tsql = @tsql + QUOTENAME(@fkCol);
                SET @tsql2 = @tsql2 + QUOTENAME(@pkCol);
                FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;
            END;
            CLOSE ColumnCursor;
            DEALLOCATE ColumnCursor;
            SET @tsql = @tsql + ' ) REFERENCES ' + QUOTENAME(@schema_name) + '.' + QUOTENAME(@referenced_object_name)
                      + ' (' + @tsql2 + ')';           
            SET @tsql = @tsql
                      + ' ON UPDATE ' + CASE @update_referential_action
                                            WHEN 0 THEN 'NO ACTION '
                                            WHEN 1 THEN 'CASCADE '
                                            WHEN 2 THEN 'SET NULL '
                                            ELSE 'SET DEFAULT '
                                        END
                      + ' ON DELETE ' + CASE @delete_referential_action
                                            WHEN 0 THEN 'NO ACTION '
                                            WHEN 1 THEN 'CASCADE '
                                            WHEN 2 THEN 'SET NULL '
                                            ELSE 'SET DEFAULT '
                                        END
                      + CASE @is_not_for_replication
                            WHEN 1 THEN ' NOT FOR REPLICATION '
                            ELSE ''
                        END
                      + ';';
            END;
        PRINT @tsql;
        IF @action = 'CREATE'
            BEGIN
            SET @tsql = 'ALTER TABLE '
                      + QUOTENAME(@schema_name) + '.' + QUOTENAME(@table_name)
                      + CASE @is_disabled
                            WHEN 0 THEN ' CHECK '
                            ELSE ' NOCHECK '
                        END
                      + 'CONSTRAINT ' + QUOTENAME(@constraint_name)
                      + ';';
            PRINT @tsql;
            END;
        FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name
            , @referenced_object_name, @constraint_object_id
            , @is_disabled, @is_not_for_replication, @is_not_trusted
            , @delete_referential_action, @update_referential_action;
    END;
    CLOSE FKcursor;
    DEALLOCATE FKcursor;
    GO
    exec [dbo].[SP_DropForeignKeys] 
    exec [dbo].[SP_CreateForeignKeys]
    droped proc worked perfect but when i execute [dbo].[SP_CreateForeignKeys] and try to see again foreign key constraints but result is empty?
    can anybody suggest me what's wrong with these script?

    droped proc worked perfect but when i execute [dbo].[SP_CreateForeignKeys] and try to see again foreign key constraints but result is empty?
    Well, if you have dropped the keys, you have dropped them. They can't be recreated out of the blue. You need to use modify procedure to save the ALTER TABLE statements in a temp table, drop the keys, truncate the tables, and the run a cursor over the
    temp table. In a single transaction, so that you don't lose the keys if the server crashes half-way through.
    Erland Sommarskog, SQL Server MVP, [email protected]

Maybe you are looking for