I’m migrating a database from MySQL 5 to SQL Server 2008. I’m using the SQL Server Migration Assistant, and it’s giving me an error that I don’t understand.
I have tables that look like this:
Table A
ID (primary key)
ProductionBatch
Manufacturer
LotNo
Cost
(and a bunch of other fields)
Table B
ProductionBatch (primary key)
Manufacturer (primary key)
LotNo (primary key)
Cost (primary key)
(and a bunch of other fields)
In MySQL, the four fields I’ve indicated in both tables form the primary key in Table B and a foreign key in Table A; I don’t want any new records inserted into table B unless there’s a match on those fields in Table A. Works fine in MySQL, but the Migration Assistant is giving me the following error:
M2SS0048: Foreign Key does not contains all the columns of Primary/Unique Key
The grammar error aside, I can’t figure out what this error means. Is it that I’m allowing null values for those fields in Table A? Or that they do not have to be unique in Table A? I tried using an autoincrementing integer as a primary key for Table B (instead of the compound key), but that didn’t seem to help.
Any ideas or suggestions would be appreciated.
EDIT: To be clear, my foreign key is on Table B. I put records into Table A first, then put records into Table B. But I don’t want to put records into Table B that don’t match any in Table A.
SECOND EDIT: I’ve been asked to show the code for this problem. As I told the questioner, I’ve been using a simple example to ask the question; my tables are actually more complicated, and I thought a simplified version would be easier to answer. But here are the actual tables, if anyone would like to see what I’m really doing. The actual fields I’m linking on are QCBatchID, LaboratoryName, Constituent, and Fraction (I used generic ones in the above example).
Table A is:
CREATE TABLE `chemistry_qc` (
`QCBatchID` varchar(12) COLLATE utf8_unicode_ci NOT NULL,
`LaboratoryName` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
`Constituent` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
`Fraction` enum('Not Reported','NA','Total','Dissolved','TR') COLLATE utf8_unicode_ci
NOT NULL,
`LabSampleType` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL,
`PercentRecovery` decimal(5,2) DEFAULT NULL,
`RPD` double(5,2) DEFAULT NULL,
PRIMARY KEY (`QCBatchID`,`LaboratoryName`,`Constituent`,`Fraction`),
CONSTRAINT `fk_chem_qc_chem` FOREIGN KEY (`QCBatchID`, `LaboratoryName`, `Constituent`, `Fraction`) REFERENCES `chemistry` (`LaboratoryName`, `QCBatchID`, `Constituent`, `Fraction`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Table B is:
CREATE TABLE `chemistry` (
`ChemistryID` int(11) NOT NULL AUTO_INCREMENT,
`StationID` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
`EventStartDateTime` datetime NOT NULL,
`SampleStartDateTime` datetime DEFAULT NULL,
`SampleEndDateTime` datetime DEFAULT NULL,
`SampleType` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`FieldSampleID` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`Matrix` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL,
`FieldQC` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`GrabComposite` enum('C','G') COLLATE utf8_unicode_ci DEFAULT NULL,
`EventRepresentation` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`CollectionMethod` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL,
`LaboratoryName` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`LabSampleID` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`ConstituentType` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`Constituent` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`CASNumber` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`Fraction` enum('TR','Dissolved','Total','Not Reported','NA') COLLATE utf8_unicode_ci DEFAULT NULL,
`QCBatchID` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL,
`SamplePrepMethod` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`AnalysisType` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
`LabSampleType` varchar(4) COLLATE utf8_unicode_ci DEFAULT NULL,
`AnalyteType` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
`SamplePrepDate` date DEFAULT NULL,
`ReportedValue` double DEFAULT NULL,
`Units` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL,
`NumericQualifier` enum('>=','<=','>','<','=') COLLATE utf8_unicode_ci DEFAULT NULL,
`DataQualifier` text COLLATE utf8_unicode_ci,
`ReportingLimit` double DEFAULT NULL,
`MethodDetectionLimit` double DEFAULT NULL,
`PercentMoisture` decimal(3,2) DEFAULT NULL,
`MethodReference` varchar(12) COLLATE utf8_unicode_ci DEFAULT NULL,
`MethodNumber` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`AnalysisDateTime` datetime DEFAULT NULL,
`Dilution` int(3) DEFAULT NULL,
`SampleNotes` longtext COLLATE utf8_unicode_ci,
PRIMARY KEY (`ChemistryID`),
KEY `fk_chemistry_event1` (`StationID`,`EventStartDateTime`),
KEY `fk_chemistry_laboratory1` (`LaboratoryName`),
KEY `ChemistryID` (`ChemistryID`,`StationID`,`EventStartDateTime`),
KEY `fk_chemistry_c_EventRepresentation1` (`EventRepresentation`),
KEY `fk_chemistry_c_collectionmethod1` (`CollectionMethod`),
KEY `fk_chemistry_c_sampletype1` (`SampleType`),
KEY `fk_chemistry_c_matrix` (`Matrix`),
KEY `fk_chemistry_c_methods` (`Constituent`,`ConstituentType`,`Units`,`MethodReference`,`MethodNumber`),
KEY `fk_chemistry_sampleprepmethod1` (`SamplePrepMethod`),
KEY `fk_chemistry_analysistype` (`AnalysisType`),
KEY `fk_chemistry_analytetype` (`AnalyteType`),
KEY `fk_chemistry_labsampletype` (`LabSampleType`),
KEY `ChemistryID_2` (`ChemistryID`,`StationID`),
KEY `LaboratoryName` (`LaboratoryName`,`Constituent`,`Fraction`,`QCBatchID`),
KEY `QCBatchID_4` (`QCBatchID`,`LaboratoryName`,`Constituent`,`Fraction`),
KEY `LaboratoryName_4` (`LaboratoryName`,`QCBatchID`,`Constituent`,`Fraction`),
CONSTRAINT `chemistry_analysistype` FOREIGN KEY (`AnalysisType`) REFERENCES `c_analysistype` (`AnalysisType`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_10` FOREIGN KEY (`SamplePrepMethod`) REFERENCES `c_sampleprepmethod` (`SamplePrepMethod`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_11` FOREIGN KEY (`Constituent`, `ConstituentType`, `Units`, `MethodReference`, `MethodNumber`) REFERENCES `c_methods` (`Constituent`, `ConstituentType`, `Units`, `MethodReference`, `MethodNumber`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_2` FOREIGN KEY (`AnalyteType`) REFERENCES `c_analytetype` (`AnalyteType`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_3` FOREIGN KEY (`CollectionMethod`) REFERENCES `c_collectionmethod` (`CollectionMethod`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_4` FOREIGN KEY (`EventRepresentation`) REFERENCES `c_eventrepresentation` (`EventRepresentation`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_5` FOREIGN KEY (`Matrix`) REFERENCES `c_matrix` (`Matrix`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_6` FOREIGN KEY (`SampleType`) REFERENCES `c_sampletype` (`SampleType`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_7` FOREIGN KEY (`StationID`, `EventStartDateTime`) REFERENCES `event` (`StationID`, `EventStartDateTime`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_8` FOREIGN KEY (`LaboratoryName`) REFERENCES `laboratory` (`LaboratoryName`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `chemistry_ibfk_9` FOREIGN KEY (`LabSampleType`) REFERENCES `c_labsampletype` (`LabSampleType`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE=InnoDB AUTO_INCREMENT=206971 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
I’ll keep only the relevant columns from the 2 tables:
Table A:
Table B:
For the record, this a
FOREIGN KEYfrom tableA (chemistry_qc)to tableB (chemistry)There are two errors in your
FOREIGN KEYconstraint. The first was done by you (and assisted by MySQL). You have the two referencing and the referenced compound key with different ordering:It should be:
MySQL should have complained when you tried to add an FK where a
VARCHAR(45)was referencing aVARCHAR(12)but it didn’t.The second error is that your FK is referencing a key that is neither
PRIMARYnorUNIQUE. Another assistance by MySQL to screw things by allowing an FK to a non-unique column-compound.So, you should have either (case-1) declared that key as
UNIQUEin tablechemistryor (case-2) your FK should be the other way around, from tableBtoA(which already has aPRIMARY KEYon this compound).Which of the two is correct, depends on the relationships of your data:
Does every
chemistryhave 0 or 1chemistry_qc? That’s case-1 (and you have a1:1relationship or to be more exact a0..1 :: 1).Does every
chemistry_qchave 0 or morechemistry? That’s case-2 (and you have a common1:nrelationship, a1 :: 0..nin the above notation).Finally, it should be clear that what caused the migration error was that the wizard you used, was (correctly) expecting a
FOREIGN KEYconstraint to reference aPRIMARYor aUNIQUEcompound.