Search code examples
sql-serverforeign-keysuniqueprimary-key

SQL Unique Value With Primary & Foreign Keys


I'm pretty sure this question has been asked before but using SQL I'm trying to only allow a table to have a unique value using both a primary and foreign keys. This may sound confusing so these are my SQL statements.

Folder table:

CREATE TABLE [dbo].[Folder] 
(
    [FolderID] VARCHAR(50) NOT NULL,
    [FolderURL] NCHAR(255) NOT NULL,
    [FolderTag] VARCHAR(50) NOT NULL,

    PRIMARY KEY CLUSTERED ([FolderURL] ASC),
    UNIQUE NONCLUSTERED ([FolderID] ASC)
);

Extension table:

CREATE TABLE [dbo].[Extension] 
(
    [ExtensionID] VARCHAR(10) NOT NULL,
    [FolderID] VARCHAR(50) NOT NULL,
    [LocationURL] VARCHAR(MAX) NOT NULL,

    PRIMARY KEY CLUSTERED ([ExtensionID] ASC),

    CONSTRAINT [fk_FolderID] 
        FOREIGN KEY ([FolderID])
        REFERENCES [dbo].[Folder]([FolderID]) ON DELETE CASCADE,
    CONSTRAINT uc_Extension UNIQUE ([ExtensionID], [FolderID]) 
);

In the Extension table I would like to have it have a unique value using the [FolderID] & [ExtensionID]. I first tried to achieve this by creating a primary key using both values, then I tried the current statement above.

Edit

I didn't give enough detail for what I am asking, below is a layout of both tables that i want to create and what the results are using the methods above.

Folder Table:

----------------------------------------------------------
| Folder ID |        FolderURL        |  FolderTag       |
|-----------|-------------------------|------------------|
|   Home    | C:/users/test/          | Home Folder      |
| Downloads | E:/Donwloads            | Downloads Folder |
|   Music   | C:/users/test/music     | Music Folder     |
| Documents | C:/users/test/documents | Downloads Folder |
----------------------------------------------------------

Extension Table:

---------------------------------------------------------
| Extension ID | FolderID  |        LocationURL         |
|--------------|-----------|----------------------------|
|    .jpg      | Downloads | C:/users/test/pictures     | = Pass 
|    .png      | Downloads | C:/users/test/pictures     | = Pass
|    .docx     | Documents | C:/users/test/BusinessDocs | = Pass
|    .mp3      |   Home    | C:/users/test/music        | = Pass
|    .jpg      |   Home    | C:/users/test/pictures     | = Fail
|    .mp3      | Downloads | C:/users/test/music        | = Fail
---------------------------------------------------------

From the table layouts provided above you can see that the last two fail due to the .mp3 ID is already entered into the table. what I am asking about is the to create a table which has a unique primary key, or something else which will allow for a unique ExtensionID and FolderID so it will allow the last two values in the Extension Table.

If anyone could help me I would greatly appreciate it.


Solution

  • CREATE TABLE [dbo].[Extension] 
    (
        [ExtensionID] VARCHAR(10) NOT NULL,
        [FolderID] VARCHAR(50) NOT NULL,
        [LocationURL] VARCHAR(MAX) NOT NULL,
    
        PRIMARY KEY ([ExtensionID], [FolderID]),
    
        CONSTRAINT [fk_FolderID] 
            FOREIGN KEY ([FolderID])
            REFERENCES [dbo].[Folder]([FolderID]) ON DELETE CASCADE
    );
    

    Here's full code and output. SQLFiddle.com is down for me; this is in PostgreSQL syntax.

    CREATE TABLE Folder
    (
        FolderID VARCHAR(50) NOT NULL,
        FolderURL NCHAR(255) NOT NULL,
        FolderTag VARCHAR(50) NOT NULL,
    
        PRIMARY KEY (FolderURL),
        UNIQUE (FolderID)
    );
    
    CREATE TABLE Extension 
    (
        ExtensionID VARCHAR(10) NOT NULL,
        FolderID VARCHAR(50) NOT NULL,
        LocationURL VARCHAR(255) NOT NULL,
    
        PRIMARY KEY (ExtensionID, FolderID),
    
        CONSTRAINT fk_FolderID 
            FOREIGN KEY (FolderID)
            REFERENCES Folder(FolderID) ON DELETE CASCADE
    );
    
    insert into folder values
    ('Home', 'C:/users/test/', 'Home Folder'),
    ('Downloads', 'E:/Donwloads', 'Downloads Folder'),
    ('Music', 'C:/users/test/music', 'Music Folder'),
    ('Documents', 'C:/users/test/documents', 'Downloads Folder');
    
    insert into Extension values
    ('.jpg', 'Downloads', 'C:/users/test/pictures'),
    ('.png', 'Downloads', 'C:/users/test/pictures'),
    ('.docx', 'Documents', 'C:/users/test/BusinessDocs'),
    ('.mp3', 'Home', 'C:/users/test/music'),
    ('.jpg', 'Home', 'C:/users/test/pictures'),
    ('.mp3', 'Downloads', 'C:/users/test/music');
    
    select * from folder;
    
    folderid    folderurl                 foldertag
    --
    Home        C:/users/test/            Home Folder
    Downloads   E:/Donwloads              Downloads Folder
    Music       C:/users/test/music       Music Folder
    Documents   C:/users/test/documents   Downloads Folder
    
    select * from extension;
    
    extensionid  folderid    locationurl
    --
    .jpg         Downloads   C:/users/test/pictures
    .png         Downloads   C:/users/test/pictures
    .docx         Documents  C:/users/test/BusinessDocs
    .mp3         Home        C:/users/test/music
    .jpg         Home        C:/users/test/pictures
    .mp3         Downloads   C:/users/test/music