views:

151

answers:

3

Table A has a computed field called Computed1. It's persisted and not null. Also, it always computes to an expression which is char(50). It's also unique and has a unique key constraint on it.

Table B has a field RefersToComputed1, which should refer to a valid Computed1 value.

Trying to create a foreign key constraint on B's RefersToComputed1 that references A' Computed1 leads to the following error:

Error SQL01268: .Net SqlClient Data Provider: Msg 1753, Level 16, State 0, Line 1 Column
'B.RefersToComputed1' is not the same length or scale as referencing column 'A.Computed1' in
foreign key 'FK_B_A'. Columns participating in a foreign key relationship must be defined with
the same length and scale.

Q: Why is this error created? Are there special measures needed for foreign keys for computed columns, and if so what are they?


Summary:

  • The specific problem rises from computed, char based, fields being varchar. Hence, Computed1 is varchar(50) and not char(50).
  • It's best to have a cast surrounding a computed field's expression to force it to a specific type. Credit goes to Cade Roux for this tip.
+1  A: 

Is RefersToComputed1 a primary key of type char(50)?

Lucero
@Lucero: It's not a primary key. The relationship is many to one, so in table B there can be several RefersToComputed1 of the same value.
Asaf R
So what exactly are you trying to do? a foreign key constraint is used to make sure that a column has only entries from a referenced primary key, but in your case there is no primary key. Please explain.
Lucero
@Lucero: you can *also* reference a unique index with a foreign key - doesn't have to be PK by all means.
marc_s
@marc_s, thanks for the hint. I actually never used them for anything but primary keys, and the docs which pop up when you search for foreign keys aren't helpful either: http://msdn.microsoft.com/en-us/library/ms175464.aspx
Lucero
+2  A: 

The computed field is composed of char(M), char(N) and so on, that add up to M+N+.. = 50, but the computed field itself is varchar(50). Changing RefersToComputed1 to varchar(50) instead of char(50) solves the problem.

Computed fields foreign keys require no special treatment (although persisted might be required on the computed column).

Asaf R
good catch - CHAR(50) would be padded to 50 chars length with spaces, while VARCHAR won't be - another plus for using VARCHAR over CHAR for these kind of things!
marc_s
Persisted would needed to index it, which would be required to create an FK on it...
gbn
You can also do a cast in your computated column expression to ensure your persisted column is of the type you think it is. That's a big problem in string operations.
Cade Roux
@Cade: That's a good advice. I've added a cast to my computed fields.
Asaf R
+1  A: 

Is RefersToComputed1 exactly the same datatype, length and collation exactly as Computed1?

Double check it... for example, do you need a final CAST or COLLATE on Computed1 to make sure it is what you expect? I say this because the error is saying that the 2 columns are different

Edit: char and varchar are not identical datatypes, so you'll need a CAST to change it

gbn