2

我正在将数据库从 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。但我不想将与表 A 中的任何不匹配的记录放入表 B .

第二次编辑:我被要求展示这个问题的代码。正如我对提问者所说,我一直在用一个简单的例子来提问;我的表格实际上更复杂,我认为简化版本会更容易回答。但这里是实际的表格,如果有人想看看我真正在做什么。我链接的实际字段是 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  
4

2 回答 2

2

错误本身只是说您的 FK 不包含构成表 B 的 PK 的所有四列。仔细检查您的 FK 规范,看看它是否包含所有四列。

话虽如此,@Kevin 的评论(在问题中)是正确的,FK 不能那样工作,你必须先插入 PK 表。

编辑:现在我看到 FK 在表 B 而不是 A 上(根据您的评论和编辑)这是问题所在,您在表 B 中有一个 FK 引用 A,但是 A 上的 PK 只是一个 ID ...不起作用,表 B 上的 FK 和它所引用的表上的 PK(在本例中为 A)需要相同。您可以将 ID 列作为 PK 从 A 中删除,并使其成为与 B 相同的复合键,如果您希望它起作用。

于 2012-06-22T17:20:15.893 回答
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) 

当您尝试在 aVARCHAR(45)引用 aVARCHAR(12)但它没有添加 FK 时,MySQL 应该会抱怨。


第二个错误是您的 FK 引用的键既不是PRIMARY也不是UNIQUE。MySQL 的另一个帮助是通过允许 FK 到非唯一的列复合来解决问题。

因此,您应该将 (case-1) 声明为UNIQUEtable中的键,chemistry或者 (case-2) 您的 FK 应该是相反的,从 tableB到(在此化合物上A已经有 a )。PRIMARY KEY

两者中哪一个是正确的,取决于您的数据关系:

每个chemistry都有 0 或 1chemistry_qc吗?那是 case-1 (你有一个1:1关系,或者更准确地说是 a 0..1 :: 1)。

每个chemistry_qc都有 0 或更多chemistry吗?那是case-2(你有一个共同的1:n关系,1 :: 0..n在上面的符号中)。


最后,应该清楚导致迁移错误的原因是您使用的向导(正确地)期望一个FOREIGN KEY约束来引用一个PRIMARY或一个UNIQUE化合物。

于 2012-06-22T22:49:04.623 回答