Foreign Key with a Constant
Let's say I have a table A, that has two columns: one is an ID for ThingA
, and one is an ID for ThingB
. The primary key is (ThingA, ThingB)
.
Next, I have a second table, but this time it's restricted to entries in table A
that have ThingB = 3
. The primary key is ThingA
, because ThingB
is a constant of 3.
Initially, I had thought I could simply:
FOREIGN KEY (ThingA, 3) REFERENCES A(ThingA, ThingB)
But I've learned that's not the case, and I have to create a column for the ThingB
:
ThingB INT NOT NULL DEFAULT(3) CHECK(ThingB = 3)
Then,
FOREIGN KEY (ThingA, ThingB) REFERENCES A (ThingA, ThingB)
Is there an alternative to this that doesn't require an extra column, or the DEFAULT + CHECK
? One alternative is a persisted, computed column, but I hate that idea too as it's basically a cheat and still adds a new column with physical storage. While on it's own, the INT
won't be big, there are several million rows that need it across several tables, and I'd rather not maintain the extra columns.
Here's sample DDL to illustrate the situation:
CREATE TABLE Test1
(
ThingA INT NOT NULL,
ThingB INT NOT NULL,
PRIMARY KEY (ThingA, ThingB)
);
CREATE TABLE Test2
(
ThingAVal INT NOT NULL,
ThingBVal INT NOT NULL DEFAULT(3) CHECK(ThingBVal = 3),
Val INT NOT NULL,
FOREIGN KEY (ThingAVal, ThingBVal) REFERENCES Test1 (ThingA, ThingB)
);
And I've created a db<>fiddle that demonstrates my (current) solution:
- https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=edba40478f104ac017c3444138a07762
If the answer is "No", I'll accept it, but I'm curious if there are any other alternatives.
sql-server database-design sql-server-2014 foreign-key constraint
bumped to the homepage by Community♦ 25 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
Let's say I have a table A, that has two columns: one is an ID for ThingA
, and one is an ID for ThingB
. The primary key is (ThingA, ThingB)
.
Next, I have a second table, but this time it's restricted to entries in table A
that have ThingB = 3
. The primary key is ThingA
, because ThingB
is a constant of 3.
Initially, I had thought I could simply:
FOREIGN KEY (ThingA, 3) REFERENCES A(ThingA, ThingB)
But I've learned that's not the case, and I have to create a column for the ThingB
:
ThingB INT NOT NULL DEFAULT(3) CHECK(ThingB = 3)
Then,
FOREIGN KEY (ThingA, ThingB) REFERENCES A (ThingA, ThingB)
Is there an alternative to this that doesn't require an extra column, or the DEFAULT + CHECK
? One alternative is a persisted, computed column, but I hate that idea too as it's basically a cheat and still adds a new column with physical storage. While on it's own, the INT
won't be big, there are several million rows that need it across several tables, and I'd rather not maintain the extra columns.
Here's sample DDL to illustrate the situation:
CREATE TABLE Test1
(
ThingA INT NOT NULL,
ThingB INT NOT NULL,
PRIMARY KEY (ThingA, ThingB)
);
CREATE TABLE Test2
(
ThingAVal INT NOT NULL,
ThingBVal INT NOT NULL DEFAULT(3) CHECK(ThingBVal = 3),
Val INT NOT NULL,
FOREIGN KEY (ThingAVal, ThingBVal) REFERENCES Test1 (ThingA, ThingB)
);
And I've created a db<>fiddle that demonstrates my (current) solution:
- https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=edba40478f104ac017c3444138a07762
If the answer is "No", I'll accept it, but I'm curious if there are any other alternatives.
sql-server database-design sql-server-2014 foreign-key constraint
bumped to the homepage by Community♦ 25 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
I fear there is no perfect solution in current implementations of SQL DBMSs. But you could useTINYINT
, if the number possible values ofThingB
is small.
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:09
@ypercubeᵀᴹ Yeah, it's aSMALLINT
on prod, I just wish there were a better way to associate it. I might get rid ofA
entirely, as I don't actually need it, and just do the referential-integrity viaThingA
, thus allowing me to removeThingB
.
– 202_accepted
Jun 7 '18 at 21:24
If I have time, I'll add an answer later with my thoughts on this. If not, during the weekend. I had a similar/related question, some years ago. Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:28
@ypercubeᵀᴹ I appreciate it. Scratching my head here, and my solutions are only getting more convoluted.
– 202_accepted
Jun 7 '18 at 21:30
Is there a reason why you're choosing not to use a surrogate identity-based key coupled with aUNIQUE
constraint on(ThingA, ThingB)
?
– John Eisbrener
Aug 13 '18 at 14:15
add a comment |
Let's say I have a table A, that has two columns: one is an ID for ThingA
, and one is an ID for ThingB
. The primary key is (ThingA, ThingB)
.
Next, I have a second table, but this time it's restricted to entries in table A
that have ThingB = 3
. The primary key is ThingA
, because ThingB
is a constant of 3.
Initially, I had thought I could simply:
FOREIGN KEY (ThingA, 3) REFERENCES A(ThingA, ThingB)
But I've learned that's not the case, and I have to create a column for the ThingB
:
ThingB INT NOT NULL DEFAULT(3) CHECK(ThingB = 3)
Then,
FOREIGN KEY (ThingA, ThingB) REFERENCES A (ThingA, ThingB)
Is there an alternative to this that doesn't require an extra column, or the DEFAULT + CHECK
? One alternative is a persisted, computed column, but I hate that idea too as it's basically a cheat and still adds a new column with physical storage. While on it's own, the INT
won't be big, there are several million rows that need it across several tables, and I'd rather not maintain the extra columns.
Here's sample DDL to illustrate the situation:
CREATE TABLE Test1
(
ThingA INT NOT NULL,
ThingB INT NOT NULL,
PRIMARY KEY (ThingA, ThingB)
);
CREATE TABLE Test2
(
ThingAVal INT NOT NULL,
ThingBVal INT NOT NULL DEFAULT(3) CHECK(ThingBVal = 3),
Val INT NOT NULL,
FOREIGN KEY (ThingAVal, ThingBVal) REFERENCES Test1 (ThingA, ThingB)
);
And I've created a db<>fiddle that demonstrates my (current) solution:
- https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=edba40478f104ac017c3444138a07762
If the answer is "No", I'll accept it, but I'm curious if there are any other alternatives.
sql-server database-design sql-server-2014 foreign-key constraint
Let's say I have a table A, that has two columns: one is an ID for ThingA
, and one is an ID for ThingB
. The primary key is (ThingA, ThingB)
.
Next, I have a second table, but this time it's restricted to entries in table A
that have ThingB = 3
. The primary key is ThingA
, because ThingB
is a constant of 3.
Initially, I had thought I could simply:
FOREIGN KEY (ThingA, 3) REFERENCES A(ThingA, ThingB)
But I've learned that's not the case, and I have to create a column for the ThingB
:
ThingB INT NOT NULL DEFAULT(3) CHECK(ThingB = 3)
Then,
FOREIGN KEY (ThingA, ThingB) REFERENCES A (ThingA, ThingB)
Is there an alternative to this that doesn't require an extra column, or the DEFAULT + CHECK
? One alternative is a persisted, computed column, but I hate that idea too as it's basically a cheat and still adds a new column with physical storage. While on it's own, the INT
won't be big, there are several million rows that need it across several tables, and I'd rather not maintain the extra columns.
Here's sample DDL to illustrate the situation:
CREATE TABLE Test1
(
ThingA INT NOT NULL,
ThingB INT NOT NULL,
PRIMARY KEY (ThingA, ThingB)
);
CREATE TABLE Test2
(
ThingAVal INT NOT NULL,
ThingBVal INT NOT NULL DEFAULT(3) CHECK(ThingBVal = 3),
Val INT NOT NULL,
FOREIGN KEY (ThingAVal, ThingBVal) REFERENCES Test1 (ThingA, ThingB)
);
And I've created a db<>fiddle that demonstrates my (current) solution:
- https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=edba40478f104ac017c3444138a07762
If the answer is "No", I'll accept it, but I'm curious if there are any other alternatives.
sql-server database-design sql-server-2014 foreign-key constraint
sql-server database-design sql-server-2014 foreign-key constraint
edited Jun 7 '18 at 21:49
MDCCL
6,68731744
6,68731744
asked Jun 7 '18 at 21:04
202_accepted202_accepted
7531922
7531922
bumped to the homepage by Community♦ 25 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 25 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
I fear there is no perfect solution in current implementations of SQL DBMSs. But you could useTINYINT
, if the number possible values ofThingB
is small.
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:09
@ypercubeᵀᴹ Yeah, it's aSMALLINT
on prod, I just wish there were a better way to associate it. I might get rid ofA
entirely, as I don't actually need it, and just do the referential-integrity viaThingA
, thus allowing me to removeThingB
.
– 202_accepted
Jun 7 '18 at 21:24
If I have time, I'll add an answer later with my thoughts on this. If not, during the weekend. I had a similar/related question, some years ago. Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:28
@ypercubeᵀᴹ I appreciate it. Scratching my head here, and my solutions are only getting more convoluted.
– 202_accepted
Jun 7 '18 at 21:30
Is there a reason why you're choosing not to use a surrogate identity-based key coupled with aUNIQUE
constraint on(ThingA, ThingB)
?
– John Eisbrener
Aug 13 '18 at 14:15
add a comment |
I fear there is no perfect solution in current implementations of SQL DBMSs. But you could useTINYINT
, if the number possible values ofThingB
is small.
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:09
@ypercubeᵀᴹ Yeah, it's aSMALLINT
on prod, I just wish there were a better way to associate it. I might get rid ofA
entirely, as I don't actually need it, and just do the referential-integrity viaThingA
, thus allowing me to removeThingB
.
– 202_accepted
Jun 7 '18 at 21:24
If I have time, I'll add an answer later with my thoughts on this. If not, during the weekend. I had a similar/related question, some years ago. Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:28
@ypercubeᵀᴹ I appreciate it. Scratching my head here, and my solutions are only getting more convoluted.
– 202_accepted
Jun 7 '18 at 21:30
Is there a reason why you're choosing not to use a surrogate identity-based key coupled with aUNIQUE
constraint on(ThingA, ThingB)
?
– John Eisbrener
Aug 13 '18 at 14:15
I fear there is no perfect solution in current implementations of SQL DBMSs. But you could use
TINYINT
, if the number possible values of ThingB
is small.– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:09
I fear there is no perfect solution in current implementations of SQL DBMSs. But you could use
TINYINT
, if the number possible values of ThingB
is small.– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:09
@ypercubeᵀᴹ Yeah, it's a
SMALLINT
on prod, I just wish there were a better way to associate it. I might get rid of A
entirely, as I don't actually need it, and just do the referential-integrity via ThingA
, thus allowing me to remove ThingB
.– 202_accepted
Jun 7 '18 at 21:24
@ypercubeᵀᴹ Yeah, it's a
SMALLINT
on prod, I just wish there were a better way to associate it. I might get rid of A
entirely, as I don't actually need it, and just do the referential-integrity via ThingA
, thus allowing me to remove ThingB
.– 202_accepted
Jun 7 '18 at 21:24
If I have time, I'll add an answer later with my thoughts on this. If not, during the weekend. I had a similar/related question, some years ago. Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:28
If I have time, I'll add an answer later with my thoughts on this. If not, during the weekend. I had a similar/related question, some years ago. Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:28
@ypercubeᵀᴹ I appreciate it. Scratching my head here, and my solutions are only getting more convoluted.
– 202_accepted
Jun 7 '18 at 21:30
@ypercubeᵀᴹ I appreciate it. Scratching my head here, and my solutions are only getting more convoluted.
– 202_accepted
Jun 7 '18 at 21:30
Is there a reason why you're choosing not to use a surrogate identity-based key coupled with a
UNIQUE
constraint on (ThingA, ThingB)
?– John Eisbrener
Aug 13 '18 at 14:15
Is there a reason why you're choosing not to use a surrogate identity-based key coupled with a
UNIQUE
constraint on (ThingA, ThingB)
?– John Eisbrener
Aug 13 '18 at 14:15
add a comment |
3 Answers
3
active
oldest
votes
I think the combination of a surrogate key on dbo.Test1
and a trigger executed after both INSERT
and UPDATE
statements, specifically an INSTEAD OF
trigger, is the answer here.
And might look something like this (fiddle):
Schema
create table dbo.Test1 (
Id int identity primary key,
ThingA int not null,
ThingB int not null
);
create table dbo.Test2 (
Id int identity primary key,
Test1Id int not null foreign key references Test1 (Id),
Val int not null
);
After INSERT
Trigger
create trigger test2ThingBCheck_Insert
on dbo.Test2
instead of INSERT
as
begin
insert into dbo.Test2 (Test1Id, Val)
select
t.Id
,i.Val
from
Test1 t
join
inserted i
on i.Test1Id = t.Id
where
t.ThingB = 3;
end;
After UPDATE
Trigger
create trigger test2ThingBCheck_Update
on dbo.Test2
instead of Update
as
begin
update
t2
set
Val = i.Val
from
dbo.Test2 t2
join
inserted i
on i.Id = t2.Id
join
dbo.Test1 t1
on t1.Id = i.Test1Id
where
t1.ThingB = 3;
end;
add a comment |
If you know the constant value of ThingB, then I suggest to leave the column "ThingB" away. Instead let the business logic add the constant value. What the value exactly is can be stored in another table or in some setting.
add a comment |
You said you didn't want to add an extra column to a number of tables that need to link back to Test1 in this way (ie on ThingA, 3).
How about adding one persisted computed column to TestA that shows the value ThingA if ThingB is 3, and null otherwise?
Then your foreign key references the new column only, based on ThingA in the referencing table.
alter table Test1 add SpecialThingA as
(case ThingB when 3 then ThingA else null end) persisted;
and
FOREIGN KEY (ThingA) REFERENCES Test1 (SpecialThingA)
In other words - one new column on Test1, rather than a new column on Test2 (to hold '3') and Test3, and ....
Didnt work for me on SQL server because persisted column in 'nchar' and the column that Im trying to create the relationship is 'int'
– juanora
14 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f209038%2fforeign-key-with-a-constant%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think the combination of a surrogate key on dbo.Test1
and a trigger executed after both INSERT
and UPDATE
statements, specifically an INSTEAD OF
trigger, is the answer here.
And might look something like this (fiddle):
Schema
create table dbo.Test1 (
Id int identity primary key,
ThingA int not null,
ThingB int not null
);
create table dbo.Test2 (
Id int identity primary key,
Test1Id int not null foreign key references Test1 (Id),
Val int not null
);
After INSERT
Trigger
create trigger test2ThingBCheck_Insert
on dbo.Test2
instead of INSERT
as
begin
insert into dbo.Test2 (Test1Id, Val)
select
t.Id
,i.Val
from
Test1 t
join
inserted i
on i.Test1Id = t.Id
where
t.ThingB = 3;
end;
After UPDATE
Trigger
create trigger test2ThingBCheck_Update
on dbo.Test2
instead of Update
as
begin
update
t2
set
Val = i.Val
from
dbo.Test2 t2
join
inserted i
on i.Id = t2.Id
join
dbo.Test1 t1
on t1.Id = i.Test1Id
where
t1.ThingB = 3;
end;
add a comment |
I think the combination of a surrogate key on dbo.Test1
and a trigger executed after both INSERT
and UPDATE
statements, specifically an INSTEAD OF
trigger, is the answer here.
And might look something like this (fiddle):
Schema
create table dbo.Test1 (
Id int identity primary key,
ThingA int not null,
ThingB int not null
);
create table dbo.Test2 (
Id int identity primary key,
Test1Id int not null foreign key references Test1 (Id),
Val int not null
);
After INSERT
Trigger
create trigger test2ThingBCheck_Insert
on dbo.Test2
instead of INSERT
as
begin
insert into dbo.Test2 (Test1Id, Val)
select
t.Id
,i.Val
from
Test1 t
join
inserted i
on i.Test1Id = t.Id
where
t.ThingB = 3;
end;
After UPDATE
Trigger
create trigger test2ThingBCheck_Update
on dbo.Test2
instead of Update
as
begin
update
t2
set
Val = i.Val
from
dbo.Test2 t2
join
inserted i
on i.Id = t2.Id
join
dbo.Test1 t1
on t1.Id = i.Test1Id
where
t1.ThingB = 3;
end;
add a comment |
I think the combination of a surrogate key on dbo.Test1
and a trigger executed after both INSERT
and UPDATE
statements, specifically an INSTEAD OF
trigger, is the answer here.
And might look something like this (fiddle):
Schema
create table dbo.Test1 (
Id int identity primary key,
ThingA int not null,
ThingB int not null
);
create table dbo.Test2 (
Id int identity primary key,
Test1Id int not null foreign key references Test1 (Id),
Val int not null
);
After INSERT
Trigger
create trigger test2ThingBCheck_Insert
on dbo.Test2
instead of INSERT
as
begin
insert into dbo.Test2 (Test1Id, Val)
select
t.Id
,i.Val
from
Test1 t
join
inserted i
on i.Test1Id = t.Id
where
t.ThingB = 3;
end;
After UPDATE
Trigger
create trigger test2ThingBCheck_Update
on dbo.Test2
instead of Update
as
begin
update
t2
set
Val = i.Val
from
dbo.Test2 t2
join
inserted i
on i.Id = t2.Id
join
dbo.Test1 t1
on t1.Id = i.Test1Id
where
t1.ThingB = 3;
end;
I think the combination of a surrogate key on dbo.Test1
and a trigger executed after both INSERT
and UPDATE
statements, specifically an INSTEAD OF
trigger, is the answer here.
And might look something like this (fiddle):
Schema
create table dbo.Test1 (
Id int identity primary key,
ThingA int not null,
ThingB int not null
);
create table dbo.Test2 (
Id int identity primary key,
Test1Id int not null foreign key references Test1 (Id),
Val int not null
);
After INSERT
Trigger
create trigger test2ThingBCheck_Insert
on dbo.Test2
instead of INSERT
as
begin
insert into dbo.Test2 (Test1Id, Val)
select
t.Id
,i.Val
from
Test1 t
join
inserted i
on i.Test1Id = t.Id
where
t.ThingB = 3;
end;
After UPDATE
Trigger
create trigger test2ThingBCheck_Update
on dbo.Test2
instead of Update
as
begin
update
t2
set
Val = i.Val
from
dbo.Test2 t2
join
inserted i
on i.Id = t2.Id
join
dbo.Test1 t1
on t1.Id = i.Test1Id
where
t1.ThingB = 3;
end;
edited Jun 9 '18 at 11:34
answered Jun 9 '18 at 10:48
pimbrouwerspimbrouwers
32828
32828
add a comment |
add a comment |
If you know the constant value of ThingB, then I suggest to leave the column "ThingB" away. Instead let the business logic add the constant value. What the value exactly is can be stored in another table or in some setting.
add a comment |
If you know the constant value of ThingB, then I suggest to leave the column "ThingB" away. Instead let the business logic add the constant value. What the value exactly is can be stored in another table or in some setting.
add a comment |
If you know the constant value of ThingB, then I suggest to leave the column "ThingB" away. Instead let the business logic add the constant value. What the value exactly is can be stored in another table or in some setting.
If you know the constant value of ThingB, then I suggest to leave the column "ThingB" away. Instead let the business logic add the constant value. What the value exactly is can be stored in another table or in some setting.
answered Aug 13 '18 at 13:59
Peter ZilzPeter Zilz
111
111
add a comment |
add a comment |
You said you didn't want to add an extra column to a number of tables that need to link back to Test1 in this way (ie on ThingA, 3).
How about adding one persisted computed column to TestA that shows the value ThingA if ThingB is 3, and null otherwise?
Then your foreign key references the new column only, based on ThingA in the referencing table.
alter table Test1 add SpecialThingA as
(case ThingB when 3 then ThingA else null end) persisted;
and
FOREIGN KEY (ThingA) REFERENCES Test1 (SpecialThingA)
In other words - one new column on Test1, rather than a new column on Test2 (to hold '3') and Test3, and ....
Didnt work for me on SQL server because persisted column in 'nchar' and the column that Im trying to create the relationship is 'int'
– juanora
14 hours ago
add a comment |
You said you didn't want to add an extra column to a number of tables that need to link back to Test1 in this way (ie on ThingA, 3).
How about adding one persisted computed column to TestA that shows the value ThingA if ThingB is 3, and null otherwise?
Then your foreign key references the new column only, based on ThingA in the referencing table.
alter table Test1 add SpecialThingA as
(case ThingB when 3 then ThingA else null end) persisted;
and
FOREIGN KEY (ThingA) REFERENCES Test1 (SpecialThingA)
In other words - one new column on Test1, rather than a new column on Test2 (to hold '3') and Test3, and ....
Didnt work for me on SQL server because persisted column in 'nchar' and the column that Im trying to create the relationship is 'int'
– juanora
14 hours ago
add a comment |
You said you didn't want to add an extra column to a number of tables that need to link back to Test1 in this way (ie on ThingA, 3).
How about adding one persisted computed column to TestA that shows the value ThingA if ThingB is 3, and null otherwise?
Then your foreign key references the new column only, based on ThingA in the referencing table.
alter table Test1 add SpecialThingA as
(case ThingB when 3 then ThingA else null end) persisted;
and
FOREIGN KEY (ThingA) REFERENCES Test1 (SpecialThingA)
In other words - one new column on Test1, rather than a new column on Test2 (to hold '3') and Test3, and ....
You said you didn't want to add an extra column to a number of tables that need to link back to Test1 in this way (ie on ThingA, 3).
How about adding one persisted computed column to TestA that shows the value ThingA if ThingB is 3, and null otherwise?
Then your foreign key references the new column only, based on ThingA in the referencing table.
alter table Test1 add SpecialThingA as
(case ThingB when 3 then ThingA else null end) persisted;
and
FOREIGN KEY (ThingA) REFERENCES Test1 (SpecialThingA)
In other words - one new column on Test1, rather than a new column on Test2 (to hold '3') and Test3, and ....
edited Oct 25 '18 at 1:59
answered Oct 25 '18 at 1:53
youcantryreachingmeyoucantryreachingme
2446
2446
Didnt work for me on SQL server because persisted column in 'nchar' and the column that Im trying to create the relationship is 'int'
– juanora
14 hours ago
add a comment |
Didnt work for me on SQL server because persisted column in 'nchar' and the column that Im trying to create the relationship is 'int'
– juanora
14 hours ago
Didnt work for me on SQL server because persisted column in 'nchar' and the column that Im trying to create the relationship is 'int'
– juanora
14 hours ago
Didnt work for me on SQL server because persisted column in 'nchar' and the column that Im trying to create the relationship is 'int'
– juanora
14 hours ago
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f209038%2fforeign-key-with-a-constant%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I fear there is no perfect solution in current implementations of SQL DBMSs. But you could use
TINYINT
, if the number possible values ofThingB
is small.– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:09
@ypercubeᵀᴹ Yeah, it's a
SMALLINT
on prod, I just wish there were a better way to associate it. I might get rid ofA
entirely, as I don't actually need it, and just do the referential-integrity viaThingA
, thus allowing me to removeThingB
.– 202_accepted
Jun 7 '18 at 21:24
If I have time, I'll add an answer later with my thoughts on this. If not, during the weekend. I had a similar/related question, some years ago. Are there DBMS that allow a Foreign Key that References a View (and not only base tables)?
– yper-crazyhat-cubeᵀᴹ
Jun 7 '18 at 21:28
@ypercubeᵀᴹ I appreciate it. Scratching my head here, and my solutions are only getting more convoluted.
– 202_accepted
Jun 7 '18 at 21:30
Is there a reason why you're choosing not to use a surrogate identity-based key coupled with a
UNIQUE
constraint on(ThingA, ThingB)
?– John Eisbrener
Aug 13 '18 at 14:15