Setting referential tables in SQL Server 2008 - sql

I have two tables (A and B) that need to be related. The A has a int column that will be the foreign key column related to B table's primary key of tinyint. When I setup the relationship using SMS, I got the following error. How do I set this relationship up without changing the data type? Is it possible to cast A.FKey to int?
The following data type properties of column 'dbo.A.FKey' do not match
those of 'dbo.B.PKey'.
- Data type
- Length
- Precision

The datatypes must be the same on a relationship. I advise altering the datatype to match.

You can try creating a computed column in master table which cast pk column so it matches detailed column definition. Then add a unique constraint on this computes column. Finally, add fk in details table that refers computed column. However, it's much easier to alter table and make columns involved in relationship one type

Related

How to make a general reference to the primary key column in oracle SQL?

I have multiple tables with a unique column name for each of their primary key such as: DeviceName, DeviceNumber, SwitchNumber, Etc.
There is another table which serves as an audit trail containing the changes from all tables, it lists the table name and the primary key value for each respective table as a reference i.e.
Table#2
TableName, InstanceNumber
I would like to use the information in table #2 to pull the respective records from each table in 'TableName' by referencing the 'InstanceNumber' attribute as the PK for each respective table without having to manually create a reference for each table's column name.
Is there a way I can do this? That is, create a query that references a 'general' column name to a table that points to the primary key column?
Select * from (TableName) where (PrimaryKeyColumn) = (InstanceNumber);
You can only do this using dynamic SQL -- in PL/SQL, that would be execute immediate.
Why not? Here is one reason. All the columns returned by a query need to be known when the query is compiled. That is, before any data is read. You are requesting a set of columns that depends on the table that is in the data. So, the columns are NOT known and the query cannot be compiled.

PostgreSQL Calculated Column with values of another table referenced by foreign key

I'm currently working on a simple dummy project to refresh my knowledge on SQL and to learn a few new things :)
I have a table Article with the columns:
aID, price
I have another table Storage:
sID, aID, count
The Storage table references the aID as a foreign key and the count column say how much of an article is stored.
Now I want to add a column value to my Storage table. This column should be calculated by Article.price * Storage.count.
I found after searching the web that you can have calculated columns like this
CREATE TABLE tbl
(
int1 INT,
int2 INT,
product BIGINT GENERATED ALWAYS AS (int1 * int2) STORED
);
But I haven't found an example how to this with columns from another table.
What do I have to do in order to use the price from the referenced aID in the calculation?
You cannot define a generated column based on values from other tables. Per the documentation:
The generation expression can refer to other columns in the table, but not other generated columns. Any functions and operators used must be immutable. References to other tables are not allowed.
You can achieve the expected behavior by creating two triggers on both tables but usually creating a view based on the tables is a simpler and more efficient solution.

SQL Validation of attributes - Different Data Types

I have a table that holds all the attribute information for a series of codes. An attribute code is set up to hold only a certain data type. These include numeric, free text and dropdown values from a stored list.
I have created a table that holds all the attribute codes and their allowed values. I am trying to come up with a query that will validate each of the attributes on each of the codes based on the values in the validation table.
I'm trying to stay away from cursors as there is a large amount of codes that need to be checked and I know cursors do not perform very fast with a large number of rows.
Example of Data Table:
Example of Validation Table:
You will notice from the LIST data types that they have a corresponding LIST_CODE and allowed LIST_VALUE.
While I'm reading your question again, you could do the following:
In your validation table you do not need the attributes NUMERIC_ATTR, FREE_TEXT_ATTR and FLOAT_ATTR
You simmply declare the columns in your data-Table as int, nvarchar(300) and float. A datatype is also a constraint and SQL-Server takes care that only values can be stored in a column that are allowed by the datatype.
You can do the same with your Attribute 0_OR_1. Just use the datatype bit in your data table. If you can't use bit for any reason and use tinyint you could add a CHECK CONSTRAINT to allow only the values 0 or 1:
ALTER TABLE DataTable
ADD CONSTRAINT CK_allow_only_0_or_1
CHECK ([0_OR_1_ATTR] = 0 OR [0_OR_1_ATTR] = 1);
Use a foreign key constraint for your dropdown
You could create a ForeignKey-Constraint to store only allowed values for your dropdown
ALTER TABLE DataTable
ADD CONSTRAINT FK_DropDownElements
FOREIGN KEY (DROPDOWN_ATTR)
REFERENCES ValidationTable (LIST_VALUE);

How to reference a composite primary key into a single field?

I got this composite primary key in Table 1:
Table 1: Applicant
CreationDate PK
FamilyId PK
MemberId PK
I need to create a foreign key in Table 2 to reference this composite key. But i do not want to create three fields in Table 2 but to concatenate them in a single field.
Table 2: Sales
SalesId int,
ApplicantId -- This should be "CreationDate-FamilyId-MemberId"
What are the possible ways to achieve this ?
Note: I know i can create another field in Table 1 with the three columns concatenation but then i will have redundant info
What you're asking for is tantamount to saying "I want to treat three pieces of information as one piece of information without explicitly making it one piece of information". Which is to say that it's not possible.
That said, there are ways to make happen what you want to happen
Create a surrogate key (i.e. identity column) and use that as the FK reference
Create a computed column that is the concatenation of the three columns and use that as the FK reference
All else being equal (ease of implementation, politics, etc), I'd prefer the first. What you have is really a natural key and doesn't make a good PK if it's going to be referenced externally. Which isn't to say that you can't enforce uniqueness with a unique key; you can and should.

SQL Server - Create FK Using a literal as one of the keys

I have a code list table with a group name and key id. Instead of using discreet tables for every look-up (key/description pair), they are all in a single code_list table. I would like to generate a FK using a literal and column name as the relational key.
Example:
Order table -> "State" & order.state_id -> code_list.group_name & code_list.key_id.
The statement below, obviously does not work, but is an example of what I am trying to accomplish.
ALTER TABLE [dbo].[Order] WITH CHECK
ADD CONSTRAINT [FK_State_Code_List]
FOREIGN KEY('State', [State_Id])
REFERENCES [dbo].[Code_List] ([Group_Name], [Key_Id])
I am using SQL Server 2014
You can't use a literal value.
You could add a persisted computed column with the desired value and reference that in the FK definition, used in some super type / sub type models as this questioner demonstrates.
But you appear to be implementing the "one true lookup table" anti pattern here.
You should just have a separate table for State and a regular foreign key.