MySQL数据库中的外键
我正在为学校的目的构建一个简单的基于web的应用程序,它应该允许某些用户从下拉菜单中购买他们选择的某些产品。每当用户点击购买他们从下拉菜单中选择的产品时,该产品将存储到“已购买项目”表中,同时从另一个名为“产品”的表中删除。据我所知,为了能够做到这一点,我需要有3个表:用户、产品、购买。在购买表中,我应该有两列外键,即#1表示购买人,2表示购买的产品。我以为我解决了这个问题,但我的glassfish服务器不断向我抛出以下错误: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:MySQL数据库中的外键,mysql,foreign-keys,jsp-tags,Mysql,Foreign Keys,Jsp Tags,我正在为学校的目的构建一个简单的基于web的应用程序,它应该允许某些用户从下拉菜单中购买他们选择的某些产品。每当用户点击购买他们从下拉菜单中选择的产品时,该产品将存储到“已购买项目”表中,同时从另一个名为“产品”的表中删除。据我所知,为了能够做到这一点,我需要有3个表:用户、产品、购买。在购买表中,我应该有两列外键,即#1表示购买人,2表示购买的产品。我以为我解决了这个问题,但我的glassfish服务器不断向我抛出以下错误: com.mysql.jdbc.exceptions.jdbc4.My
无法添加或更新子行:外键约束失败
(`webprodaja`.`kupljeno`,约束`kupljeno_ibfk_1`外键(`id`)引用
用户
(`id`))
好的,下面是有问题的表和外键:
表“用户”:
id | name
1 | Ivan
2 | Beka
3 | Ogi
表“proizvodi”(工程产品):
表“kupljeno”(工程采购):
表“kupljeno”也有2个外键:
放在“id”列上并引用表“users”及其列“id”的一个
另一个放在“proizvod”列上,并引用表“proizvodi”及其列“id”
所以我要做的是删除买家选择的任何产品,并在“proizvod”列中删除其名称,因此将相同的产品放入“kupljeno”列。然而,我能够购买并将详细信息存储到“kupljeno”列中,但由于某些原因,我无法再这样做,更不用说删除“proizvod”列中购买的产品了
此外,以下是完整的index.jsp代码,说明它的价值:
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.DriverManager"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<%
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/webprodaja","root","");
Statement st = conn.createStatement();
// if(request.getParameter("add")!=null){
ResultSet rs = st.executeQuery("select * from users");
%>
<form action="index.jsp" method="post">
<select name="user">
<%
while(rs.next())
{
String name=rs.getString(2);
String id = rs.getString(1);
%>
<option value="<%=name%>" ><%=name%></option>
<%
}
%>
</select>
<%
ResultSet rs1 = st.executeQuery("select * from proizvodi");
%>
<select name="proizvod">
<%
while(rs1.next())
{
String name1=rs1.getString(2);
String id1 = rs1.getString(1);
%>
<option value="<%=id1%>" ><%=name1%></option>
<%
}
%>
</select>
<input type="submit" name="add" value="buy"/>
</form>
<%
if(request.getParameter("add")!=null)
{
String user = request.getParameter("user");
String proizvod = request.getParameter("proizvod");
st.execute("insert into kupljeno(id, name, proizvod) values (null, '"+user+"', "+proizvod+")");
}
%>
<%-- <form action="index.jsp" method="post">
<input type="submit" name="add" value="buy">
</form> --%>
</body>
</html>
JSP页面
您真的需要为kupljeno表中的外键列(相当奇怪的名称是id
,而不是users\u id
)提供值。我们通常在每个表上添加一个主键,而这个表似乎没有主键
insert into kupljeno(id, name, proizvod) values (null, '"+user+"', "+proizvod+")"
^^ ^^^^
我怀疑您在kupljeno
表中用AUTO_INCREMENT属性声明了id列,好像它是表的主键,而不是另一个表的外键
我怀疑的原因是,因为您正在插入一个空值,但尝试插入的行有一个值。这要么是由于列上的AUTO_INCREMENT属性而赋值,要么(在本例中不太可能)是由触发器赋值
(真正确定问题的方法是实际的表定义,可以使用showcreatetable
语句轻松获得。)
我认为您真正想要的是将表的主键与引用users
表的外键分开,如下所示:
id - primary key
user_id - foreign key references user(id)
user_name - (redundant, copied from user.name)
product_id - foreign key to product(id)
你说,
同时从另一个名为products的表中删除
你还说
表“kupljeno”[purchase]也有2个外键:
放在“id”列上并引用表“users”及其列“id”的一个;
另一个放在“proizvod”[product]列上,并引用表“proizvodi”[product]及其列“id”
当一个表的行对另一个表的行具有fk约束时,则在删除第一个表的行之前,无法删除第二个表的行。您应该阅读有关外键约束的文章
为什么这样做?这是糟糕的设计。不要从产品表中删除
相反,用代码控制这一点,以防止用户在需要时两次购买同一产品。不要强迫MySQL做它不应该做的事情;让代码做它应该做的事情!从产品表中删除产品的原因是什么?我想将从表“proizvodi”中购买的产品放入表“kupljeno”中,然后删除已购买的产品,使其看起来像已购买且不再可用。如何复制产品ID并将其存储在“kupljeno”表的引用列中,然后在“proizvodi”表中删除该值?因此,当一个用户购买某个产品时,其他用户是否不再可以购买该产品?因为是的,这正是我想要达到的效果。为什么不在产品表中设置“库存”列,然后当单位有0个库存时,它不可供购买,当有一个库存时,它可供购买。然后,当一个库存被购买时,它会被购买的库存量减少。在“kupljeno.id”列存储用户/产品表中的哪个id,它不需要主键,此表的目的是显示谁购买了什么,而不是将值按升序排列。我要做的是去掉这些值在“proizvodi”表中,并根据用户购买的产品将这些值放在“kupljeno”表中。这应该很容易,但由于我正在处理这些问题,我需要一个解决方法的想法。有人告诉我使用外键解决方案吗?@IvanĆeličanin:你在分配一个空vinsert语句中id列的值。因此,表中的值应为NULL。但NULL值不会引发所获得的异常。但是,如果尝试插入id值在
users.id
列中找不到的行,则会引发该异常。至于如何反
insert into kupljeno(id, name, proizvod) values (null, '"+user+"', "+proizvod+")"
^^ ^^^^
id - primary key
user_id - foreign key references user(id)
user_name - (redundant, copied from user.name)
product_id - foreign key to product(id)