我正在为学校目的构建一个简单的基于Web的应用程序,该应用程序应该允许某些用户从下拉菜单中购买他们选择的某些产品。每当用户点击购买他们从下拉菜单中选择的产品时,该产品就会存储到购买的商品表中,同时从另一个名为products的表中删除。据我所知,为了能够做到这一点,我需要有3个表:用户,产品,购买和购买表中我应该有2列外键,购买者#1和#2为购买的产品。我以为我解决了这个问题,但是我的glassfish服务器不断向我抛出以下错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
无法添加或更新子行:外键约束失败
(`webprodaja``kupljeno`,CONSTRAINT`kupljeno_ibfk_1` FOREIGN KEY(`id`)REFERENCESusers
(`id`))
好的,这是有问题的表格和外键:
表'用户':
id | name
1 | Ivan
2 | Beka
3 | Ogi
表'proizvodi'(英国产品):
id | name
1 | kafa
2 | jafa
3 | ratluk
表'kupljeno'(英国购买):
id | name | proizvod
2 | Beka | 3
3 | Ogi | 2
表'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>
答案 0 :(得分:2)
你说,
同时从名为products
的另一个表中删除
你也说过,
表'kupljeno'[购买]还有2个外键: 一个放在'id'列上并引用表'users'及其列'id'; 另一个被放在'proizvod'[产品]专栏并参考表'proizvodi'[产品]及其专栏'id';
当表的行对另一个表的行有一个fk约束时,在删除第一个表的行之前,不能删除第二个表的行。您应该阅读有关外键约束的this文章。
为什么这样?这是糟糕的设计。不要从产品表中删除。
而是使用您的代码控制此操作,以防止用户在需要时两次购买相同的产品。不要强迫MySQL做它不应该做的事情;让你的代码尽其所能!
答案 1 :(得分:0)
你真的需要在kupljeno表中提供该外键列的值(而不是奇怪地命名为id
,而不是users_id
。我们通常在每个表上添加一个主键,这个似乎没有。
insert into kupljeno(id, name, proizvod) values (null, '"+user+"', "+proizvod+")"
^^ ^^^^
我怀疑您已使用kupljeno
表中的AUTO_INCREMENT属性声明了id列,就好像它是表的主键,而不是另一个表的外键。
我怀疑的原因是,因为您正在插入NULL值,但是尝试插入的行具有值。这是由于列上的AUTO_INCREMENT属性而被分配,或者(在这种情况下不太可能)由触发器分配。
(实际识别问题的方法很长的是实际表格定义,可以使用SHOW CREATE TABLE
语句轻松获得。)
我认为你真正想要的是将表的PRIMARY KEY与引用users
表的FOREIGN KEY分开,如下所示:
id - primary key
user_id - foreign key references user(id)
user_name - (redundant, copied from user.name)
product_id - foreign key to product(id)