Creating New Foreign Key (SQL Server) - sql-server

I am having a bit of trouble creating a foreign key in my DB. Here is a paraphrased model of what my tables look like:
NOTE
* (PK) NOTE_ID BIGINT
* TITLE VARCHAR(200)
* DATE DATETIME
* SERIES_ID BIGINT
SERIES
* (PK) SERIES_ID BIGINT
* TITLE VARCHAR(200)
* DESCR VARCHAR(1000)
I am trying to create a "has a" relationship between NOTE and SERIES by SERIES_ID. I thought that setting up a foreign key between the two tables by SERIES_ID would be the solution, but when I attempt to create it I get the following error:
ERROR: There are no primary or candidate keys in the referenced table 'dbo.SERIES' that match the referencing column list in the
foreign key 'FK_SERIES_NOTE'. Could not create constraint
I'm using the web database manager that comes with the GoDaddy SQL Server I set up, so I'm not sure what the underlying query it's trying to use or I would post it.
At the end of the day, this is all to create a relationship so that the NHibernate mappings for my Note object will contain a one-to-one relationship to a Series object. I may not even be trying to tackle this the correct way with the foreign key, though.
Am I going about this the correct way?
EDIT:
In an attempt to pair down the tables to a more simple example, I removed what I thought to be several non-critical columns. However, I ended up leaving a field that was actually a part of the composite primary key on the series table. So, because I was trying to assign the foreign key to only one part of the composite key, it was not allowing me to do so.
In the end, I have taken another look at the structure of my table and found that I don't actually need the other piece of the composite key - and after removing, the assignment of the foreign key works great now.

If you can, you may try running the following statement in a query analyzer and see the resulting error message (I guess #Damien_The_Unbeliever is right ) :
ALTER TABLE NOTE ADD CONSTRAINT FK_SERIES_NOTE
FOREIGN KEY (SERIES_ID) REFERENCES SERIES(SERIES_ID)
--ON DELETE CASCADE
-- uncomment the preceding line if you want a delete on a serie
-- to automatically delete all notes on this serie
Hope this will help

Related

Convert VARBINARY to Int or BigInt

My question is very simple and I understand that few Old days DB design is not good as we espect these days.
My legacy table does not have Primary key to perform Delta load. Hence, I'm trying to use Hashing concept to create Unique key. As "HASHBYTES" return VarBinary and I can not use VarBinary type as
primay key (not sure about this)
Ref URL on MSDN:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/94231bb4-ccab-4626-a9fb-325264bb883f/can-varbinary700-column-be-used-as-primary-key?forum=transactsql
hence, I'm converting this to INT or BigInt. The problem is it gives both negative as well as positive value(due to the range).
My Question is:
How can I convert VARBINARY(100) type to integer or BigInt (+ve value) and Set this as a Primary key in one of my table?
Edit Note:
I tried to use VARBINARY as Primary key for Delta load in SSIS Lookup task. I got the error:
"Violation of PRIMARY KEY constraint 'PK__DMIN__607056C02FB7E7DE'. Cannot insert duplicate key in object 'dbo.DMIN_'. The duplicate key value is (0x00001195764c40525bcaf6baa922091696cd8886).".
However, when I checked for duplicate key from the table. Table does not have duplicate key. Then why this error is showing up?
Please note that, the 1st time of SSIS execution worked fine. However, it shows error during 2nd execution [during "lookup match output"].
Please help. Thanks.
In projects I've worked on before we've always used GUIDs as our primary keys, utilising the unique identifier type in SQL Server.
The main problem with this however, is that using a uniqueidentifier type as your clustered index can degrade the performance of your database after some time, so recently we've taken the following approach (based on this article):
Create column: guid, uniqueidentifier, nonnull, default value newsequentialid(), PK
Create column: id, bigint, nonnull, identity(1,1)
Create a non clustered index on the guid column, unique
Create a clustered index on the id column, unique
That way when you insert into this new table, you don't have to worry about the keys or identities.
If you need some form of reference between the old database and the new and you CAN modify the structure of the old database, you can create a uniqueidentifier column in that (or char(36) if it doesn't support uniqueidentifier) and assign a guid to each of those and THEN create an additional uniqueidentifier column in the new database so you have that reference and insert that value into it. If that makes sense.

Postgres INSERT INTO... SELECT violates foreign key constraint

I'm having a really, really strange issue with postgres. I'm trying to generate GUIDs for business objects in my database, and I'm using a new schema for this. I've done this with several business objects already; the code I'm using here has been tested and has worked in other scenarios.
Here's the definition for the new table:
CREATE TABLE guid.public_obj
(
guid uuid NOT NULL DEFAULT uuid_generate_v4(),
id integer NOT NULL,
CONSTRAINT obj_guid_pkey PRIMARY KEY (guid),
CONSTRAINT obj_id_fkey FOREIGN KEY (id)
REFERENCES obj (obj_id)
ON UPDATE CASCADE ON DELETE CASCADE
)
However when I try to backfill this using the following code, I get a SQL state 23503 claiming that I'm violating the foreign key constraint.
INSERT INTO guid.public_obj (guid, id)
SELECT uuid_generate_v4(), o.obj_id
FROM obj o;
ERROR: insert or update on table "public_obj" violates foreign key constraint "obj_id_fkey"
SQL state: 23503
Detail: Key (id)=(-2) is not present in table "obj".
However, if I do a SELECT on the source table, the value is definitely present:
SELECT uuid_generate_v4(), o.obj_id
FROM obj o
WHERE obj_id = -2;
"0f218286-5b55-4836-8d70-54cfb117d836";-2
I'm baffled as to why postgres might think I'm violating the fkey constraint when I'm pulling the value directly out of the corresponding table. The only constraint on obj_id in the source table definition is that it's the primary key. It's defined as a serial; the select returns it as an integer. Please help!
Okay, apparently the reason this is failing is because unbeknownst to me the table (which, I stress, does not contain many elements) is partitioned. If I do a SELECT COUNT(*) FROM obj; it returns 348, but if I do a SELECT COUNT(*) FROM ONLY obj; it returns 44. Thus, there are two problems: first, some of the data in the table has not been partitioned correctly (there exists unpartitioned data in the parent table), and second, the data I'm interested in is split out across multiple child tables and the fkey constraint on the parent table fails because the data isn't actually in the parent table. (As a note, this is not my architecture; I'm having to work with something that's been around for quite some time.)
The partitioning is by implicit type (there are three partitions, each of which contains rows relating to a specific subtype of obj) and I think the eventual solution is going to be creating GUID tables for each of the subtypes. I'm going to have to handle the stuff that's actually in the obj table probably by selecting it into a temp table, dropping the rows from the obj table, then reinserting them so that they can be partitioned properly.

Apache Derby Tables, Writing a query that indicates primary and foreign keys in a table

I am new to Apache Derby so this question may seem remedial but I am trying to find a way to write a select statement from the ij prompt that will show all of the fields along with their data types, i.e. CHAR(), VARCHAR(), INT, etc. and indicate whether they are a foreign or primary key. The only thing I have come across so far is the describe table utility. That provides some useful information but it does not, as far as I can tell, give any info pertaining to primary and foreign keys. I'm thinking that I need to be looking in the SYS.SYSCONSTRAINTS table but when I ran a simple select statement on that table the results I got back were critic. The output that I am hoping to get would be something like this
==================================================
FIELD NAME FIELD TYPE CONSTRAINTS
==================================================
FIRST NAME VARCHAR(15) NOT NULL
LAST NAME VARCHAR(15) NOT NULL
MIDDLE INTIAL CHAR(1)
BIRTH DATE DATE NOT NULL
DEPT NUMBER CHAR(3) NOT NULL FOREIGN - DEPARTMENT
SSN CHAR(9) NOT NULL PRIMARY
I assume the answer, if there is one is in joining two or more of the sys. tables but I have not been able to find out which ones.
Does anybody know how to do this?
Thank you.

How do I configure Schema Compare to produce separate files for foreign keys?

To work with our database project in VS 2010, we make schema changes directly into our local project database using SSMS, then when we are ready to check in we do a Schema Compare, the local database vs the project, which identifies our changes. Then when we Write Changes, it alters or creates schema object scripts into our database project. If all looks well, we can then check in those changes to TFS.
Our standard on foreign keys and indices is to have those saved separately. That is, even though I define a column in a new table by saying something like this:
CREATE TABLE Billing.EntryPointProduct
(
EntryPointProductId INT IDENTITY(1,1) PRIMARY KEY,
EntryPointId INT FOREIGN KEY REFERENCES Billing.EntryPoint(EntryPointId),
ProductId INT FOREIGN KEY REFERENCES ProductCatalog.Product(ProductID)
)
What we really want, in the end, is a file for the EntryPointProduct table and a file for each of the Foreign Key objects. However, right now the schema compare is producing it all in one table script. I swear I have done this before with schema compare, but I can't seem to find the way to configure it to do this. Can anyone advise?
Can you change your DDL so it looks like this:
CREATE TABLE Billing.EntryPointProduct
(
EntryPointProductId INT IDENTITY(1,1),
EntryPointId INT,
ProductId INT,
CONSTRAINT [PK_EntryPointProduct] PRIMARY KEY CLUSTERED (EntryPointProductId)
)
ALTER TABLE Billing.EntryPointProduct
WITH CHECK ADD CONSTRAINT FK_EntryPointProduct_EntryPoint FOREIGN KEY(EntryPointId) REFERENCES Billing.EntryPoint(EntryPointId)
ALTER TABLE Billing.EntryPointProduct
WITH CHECK ADD CONSTRAINT FK_EntryPointProduct_ProductCatalog FOREIGN KEY(ProductId) REFERENCES ProductCatalog.Product(ProductID)
That way you'd have 3 different files, and your FK's would have real names (FK_*) instead of system-generated names which will be randomly generated each time they are created and therefore won't match if you did a schema compare between 2 separately scripted out databases. (Same reason why I modified the PK code)

Introducing FOREIGN KEY constraint 'c_name' on table 't_name' may cause cycles or multiple cascade paths

I have a database table called Lesson:
columns: [LessonID, LessonNumber, Description] ...plus some other columns
I have another table called Lesson_ScoreBasedSelection:
columns: [LessonID,NextLessonID_1,NextLessonID_2,NextLessonID_3]
When a lesson is completed, its LessonID is looked up in the Lesson_ScoreBasedSelection table to get the three possible next lessons, each of which are associated with a particular range of scores. If the score was 0-33, the LessonID stored in NextLessonID_1 would be used. If the score was 34-66, the LessonID stored in NextLessonID_2 would be used, and so on.
I want to constrain all the columns in the Lesson_ScoreBasedSelection table with foreign keys referencing the LessonID column in the lesson table, since every value in the Lesson_ScoreBasedSelection table must have an entry in the LessonID column of the Lesson table. I also want cascade updates turned on, so that if a LessonID changes in the Lesson table, all references to it in the Lesson_ScoreBasedSelection table get updated.
This particular cascade update seems like a very straightforward, one-way update, but when I try to apply a foreign key constraint to each field in the Lesson_ScoreBasedSelection table referencing the LessonID field in the Lesson table, I get the error:
Introducing FOREIGN KEY constraint 'c_name' on table 'Lesson_ScoreBasedSelection' may cause cycles or multiple cascade paths.
Can anyone explain why I'm getting this error or how I can achieve the constraints and cascading updating I described?
You can't have more than one cascading RI link to a single table in any given linked table. Microsoft explains this:
You receive this error message because
in SQL Server, a table cannot appear
more than one time in a list of all
the cascading referential actions that
are started by either a DELETE or an
UPDATE statement. For example, the
tree of cascading referential actions
must only have one path to a
particular table on the cascading
referential actions tree.
Given the SQL Server constraint on this, why don't you solve this problem by creating a table with SelectionID (PK), LessonID, Next_LessonID, QualifyingScore as the columns. Use a constraint to ensure LessonID and QualifyingScore are unique.
In the QualifyingScore column, I'd use a tinyint, and make it 0, 1, or 2. That, or you could do a QualifyingMinScore and QualifyingMaxScore column so you could say,
SELECT * FROM NextLesson
WHERE LessonID = #MyLesson
AND QualifyingMinScore <= #MyScore
AND #MyScore <= QualifyingMaxScore
Cheers,
Eric

Resources