我承认这里已多次询问过这个问题,并且我已经查看过很多答案。
我知道errno150指的是一个外键不正确的表,我已经看到了之前的回答here。我检查了那里的每一个条件,无法解决这个问题。不知道我是否遗漏了一些明显的东西。
这是使用MySQL的java实现,我是一个switch语句,它创建了两个表(目前),如下所示:
//Creates the table with the name given to the function and adds all fields & keys
switch(tableName){
case "Address":
stmt.executeUpdate("CREATE TABLE Address(houseNo INT(4) NOT NULL, "
+ "firstLine VARCHAR(30) NOT NULL, "
+ "secondLine VARCHAR(30), "
+ "city VARCHAR(25) NOT NULL, "
+ "county VARCHAR(25) NOT NULL, "
+ "postCode VARCHAR(7) NOT NULL, "
+ "PRIMARY KEY (houseNo, postCode))");
break;
case "Patient":
stmt.executeUpdate("CREATE TABLE Patient(patientID INT(8) NOT NULL PRIMARY KEY AUTO_INCREMENT, "
+ "title VARCHAR (10) NOT NULL, "
+ "forename VARCHAR(15) NOT NULL, "
+ "surname VARCHAR(25) NOT NULL, "
+ "dob DATE NOT NULL, "
+ "phoneNo CHAR(11) NOT NULL, "
+ "houseNo INT(4) NOT NULL, "
+ "postCode VARCHAR(7) NOT NULL, "
+ "amountOwed DECIMAL(5,2) NOT NULL, "
+ "FOREIGN KEY (houseNo) REFERENCES Address (houseNo), "
+ "FOREIGN KEY (postCode) REFERENCES Address (postCode))");
break;
}
地址创建正常(没有外键),患者给出errno150。相同的引擎,相同的字符集,相同的数据类型(甚至复制粘贴为100%确定),新创建的(空)表,都是非临时的。
感谢。
P.S。我无法使用SHOW ENGINE INNODB STATUS
,因为我没有足够高的权限级别。
完整的错误消息:
java.sql.SQLException: Can't create table 'team.Patient' (errno: 150)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545)
at com.mysql.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1540)
at com.mysql.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2595)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1468)
at uk.team.App.makeTable(App.java:146)
at uk.team.App.setupEnviro(App.java:80)
at uk.team.App.access$1(App.java:45)
at uk.team.App$1.run(App.java:33)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
答案 0 :(得分:2)
如果要创建与父表的相同行中的两个列匹配的外键约束,则需要为两列指定单个FOREIGN KEY(而不是每列有两个单独的FK约束。)
这适用于MySQL 5.6.13:
stmt.executeUpdate("CREATE TABLE Address(houseNo INT(4) NOT NULL, "
+ "firstLine VARCHAR(30) NOT NULL, "
+ "secondLine VARCHAR(30), "
+ "city VARCHAR(25) NOT NULL, "
+ "county VARCHAR(25) NOT NULL, "
+ "postCode VARCHAR(7) NOT NULL, "
+ "PRIMARY KEY (houseNo, postCode))");
stmt.executeUpdate("CREATE TABLE Patient(patientID INT(8) NOT NULL PRIMARY KEY AUTO_INCREMENT, "
+ "title VARCHAR (10) NOT NULL, "
+ "forename VARCHAR(15) NOT NULL, "
+ "surname VARCHAR(25) NOT NULL, "
+ "dob DATE NOT NULL, "
+ "phoneNo CHAR(11) NOT NULL, "
+ "houseNo INT(4) NOT NULL, "
+ "postCode VARCHAR(7) NOT NULL, "
+ "amountOwed DECIMAL(5,2) NOT NULL, "
+ "FOREIGN KEY (houseNo, postCode) REFERENCES Address (houseNo, postCode))");
答案 1 :(得分:1)
由于Address表没有问题,这与Patient表的引用更相关,我假设team是数据库名称:
从我在这里看到的,引用的列应该被编入索引。您已经同时创建了一个索引(houseNo
,postCode
),为什么不尝试单独为它们创建索引并查看它是否适合您?
虽然您已经提到过使用相同的引擎,字符集等,但为什么不在上面的查询中明确提及它们并运行它们。你可以在查询中添加ENGINE = InnoDB吗?
请告诉我如果它不适合您。
Can't create table (errno: 150) InnoDB adding foreign key constraints
答案 2 :(得分:0)
所以答案(更多是妥协)我来了:
function min_get_events ( $echo = true ) {
$events = new WP_query(array(
'post_type' => 'events',
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'meta_value',
'meta_key' => 'min_event-start',
'meta_query' => array(
'key' => 'min_event-start',
'value' => date('Y-m-d'),
'compare' => '>',
)
));
$i = 0;
$n = 1;
if ( $events->have_posts() ) :
while ( $events->have_posts() ):
global $post;
$events->the_post();
$open_date = get_post_meta($post->ID, 'min_event-start', true);
$close_date = get_post_meta($post->ID, 'min_event-end', true);
$start = strtotime($open_date);
$end = strtotime($close_date);
if ($start==$end || $start > $end) {
$date_string = date('F j, Y', $start);
}
else {
$date_string = date('F j, Y', $start) .' – '. date('F j, Y', $end);
}
//$description = get_post_meta($post->ID, 'event-description', true);
$location = get_post_meta($post->ID, 'min_event-location', true);
$url = get_post_meta($post->ID, 'min_event-url', true);
//$registration_url = get_post_meta($post->ID, 'event-registration-url', true);
$cta_text = get_post_meta($post->ID, 'min_event-cta-text', true);
$cta = !empty($cta_text) ? $cta_text : 'Register Now';
$i++;
if ( $i == 1 ) {
?>
<div class="row">
<?php
}
?>
<div class="event col-sm-4">
<a href="<?= $url ?>">
<?php the_post_thumbnail('thumb-events'); ?>
</a>
<h1><?= htmlentities($post->post_title) ?></h1>
<div >
<div><?= $date_string; ?></div>
<div><?= htmlentities($location) ?></div>
<div><a href="<?=$url;?>" class="register-now"><?= $cta; ?></a></div>
</div>
<!-- <p><?= $description ?></p> -->
<!-- <p><a href="<?=$url;?>" class="register-now"><?= $cta; ?></a></p> -->
</div> <!-- .event -->
<?php
if ( $i == 3 || ($events->current_post +1) == $events->post_count) {
?>
</div> <!-- <?php echo $i; ?> .row <?php echo $n; ?> -->
<?php
$i = 0;
$n++;
}
endwhile;
endif;
ob_start();
?>
<?php
$return = ob_get_contents();
ob_end_clean();
wp_reset_postdata();
if ( $echo ) {
echo $return;
} else {
return $return;
}
}
在“地址”中创建一个附加字段,其中包含作为主键的ID以及“患者”中唯一引用的外键。它并不理想,但功能齐全。