我正在将数据库从MySQL 5迁移到SQL Server 2008.我正在使用SQL Server迁移助手,它给了我一个我不理解的错误。
我的表格看起来像这样:
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)
在MySQL中,我在两个表中指出的四个字段构成表B中的主键和表A中的外键;我不希望任何新记录插入表B,除非表A中的那些字段匹配。在MySQL中工作正常,但迁移助手给我以下错误:
M2SS0048: Foreign Key does not contains all the columns of Primary/Unique Key
除了语法错误,我无法弄清楚这个错误意味着什么。我是否允许表A中的那些字段使用空值?或者它们在表A中不必是唯一的?我尝试使用自动增量整数作为表B的主键(而不是复合键),但这似乎没有帮助。
任何想法或建议都将受到赞赏。
编辑:要清楚,我的外键在表B上。我首先将记录放入表A,然后将记录放入表B.但我不想将记录放入表B中,不匹配任何记录。在表A中。
第二次编辑:我被要求显示此问题的代码。正如我告诉提问者的那样,我一直在用一个简单的例子来提问;我的表实际上更复杂,我认为简化版本更容易回答。但是这里有实际的表格,如果有人想看看我真正在做什么。我链接的实际字段是QCBatchID,LaboratoryName,Constituent和Fraction(我在上面的示例中使用了泛型字段)。
表A是:
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
表B是:
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
答案 0 :(得分:2)
错误本身只是说你的FK不包含组成你的表B的PK的所有四列。仔细检查你的FK规范,看它是否全部有四个。
话虽如此,@ Kevin的评论(在问题中)是正确的,FK不会那样工作,你必须先在PK表中插入。
编辑:现在我看到FK在表B而不是A(根据您的评论和编辑)这是问题,表B中的FK引用A,但A上的PK只是一个ID。 ..这不起作用,表B上的FK和它引用的表上的PK(在这种情况下为A)需要相同。您可以从A中删除您的ID列作为PK,并使其键与B的键相同,如果您希望它起作用。答案 1 :(得分:1)
我只保留2个表中的相关列:
表A:
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,
--- more columns
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 ;
表B:
CREATE TABLE chemistry (
ChemistryID int(11) NOT NULL AUTO_INCREMENT,
--- more columns
LaboratoryName varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
--- more columns
Constituent varchar(45) 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,
--- more columns
PRIMARY KEY (ChemistryID),
KEY fk_chemistry_laboratory1 (LaboratoryName),
--- more KEYs
KEY LaboratoryName (LaboratoryName, Constituent, Fraction, QCBatchID),
KEY QCBatchID_4 (QCBatchID, LaboratoryName, Constituent, Fraction),
--- this key should have been needed for your FK reference
KEY LaboratoryName_4 (LaboratoryName , QCBatchID, Constituent, Fraction),
--- this key was needed for your FK reference
--- CONSTRAINTS
) ENGINE=InnoDB
AUTO_INCREMENT=206971
DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci ;
对于记录,这是FOREIGN KEY
从表格A (chemistry_qc)
到表格B (chemistry)
FOREIGN KEY
约束中有两个错误。第一个是由你完成的(并由MySQL协助)。您有两个引用和引用的复合键具有不同的顺序:
CONSTRAINT fk_chem_qc_chem
FOREIGN KEY (QCBatchID, LaboratoryName, Constituent, Fraction)
REFERENCES chemistry
(LaboratoryName, QCBatchID, Constituent, Fraction)
--- ||| |||
--- *** wrong order here *** ---
应该是:
CONSTRAINT fk_chem_qc_chem
FOREIGN KEY (QCBatchID, LaboratoryName, Constituent, Fraction)
REFERENCES chemistry
(QCBatchID, LaboratoryName, Constituent, Fraction)
当您尝试添加VARCHAR(45)
引用VARCHAR(12)
的FK时,MySQL应该抱怨,但事实并非如此。
第二个错误是您的FK引用的密钥既不是PRIMARY
也不是UNIQUE
。 MySQL的另一个帮助是通过允许FK到非唯一的列化合物来解决问题。
所以,你应该让(case-1)在表UNIQUE
中声明密钥为chemistry
或者(case-2)你的FK应该是另一种方式,从表{{1 {}为B
(此化合物上已有A
)。
这两个中的哪一个是正确的,取决于您的数据的关系:
每个PRIMARY KEY
都有0或1 chemistry
吗?那是案例-1(你有一个chemistry_qc
关系,或者更确切地说是一个1:1
。)
每个0..1 :: 1
都有0个或更多chemistry_qc
吗?那是第2种情况(你有一个共同的chemistry
关系,在上面的表示法中有一个1:n
。
最后,应该清楚的是,导致迁移错误的原因是您使用的向导(正确地)期望1 :: 0..n
约束引用FOREIGN KEY
或PRIMARY
复合。