开发者社区 问答 正文

删除具有外键的行时如何在数据库中保留条目

我有这样的数据库设置:

CREATE TABLE farms ( id SERIAL8 primary key, name VARCHAR(255) not null, address VARCHAR(255), phone_num VARCHAR(255) );

CREATE TABLE products ( id SERIAL8 primary key, name VARCHAR(255) not null, description VARCHAR(255), stock FLOAT, cost FLOAT, price FLOAT, farm_id INT8 references farms(id) ) 我遇到的问题是删除服务器场时,它还删除了该服务器场中所有可用的产品,但我只想删除服务器场,而不是产品。

这是我删除场的方法

def delete sql = "DELETE FROM farms WHERE id = $1" values = [@id] SqlRunner.run(sql, values) end 我是如何构建表的问题,还是我的SQL语句不正确?

展开
收起
保持可爱mmm 2019-11-18 10:08:09 484 分享 版权
阿里云 AI 助理回答

根据您提供的信息,问题并不在于表的结构或者SQL删除语句本身。您的数据库表设计已经正确地使用了外键约束(farm_id INT8 references farms(id)),这本应防止当删除一个农场(farms表中的记录)时,直接级联删除关联的产品(products表中的记录)。但是,从您的描述来看,似乎这种约束并没有按预期工作,导致删除农场时同时删除了相关产品。

这种情况可能是因为在创建外键约束时,没有明确指定级联操作的行为。默认情况下,PostgreSQL不会自动级联删除,除非在创建外键时显式指定了ON DELETE CASCADE。但根据您的描述,看起来不像是这个原因导致的问题,因为通常未指定级联操作时,尝试删除会被约束阻止,而不是错误地执行级联删除。

更有可能的原因是,在您的应用程序逻辑中,除了显示的这个SQL删除语句之外,还有其他逻辑或触发器在起作用,导致了产品的意外删除。或者是数据库设置、配置问题,比如在某些数据库管理系统中,外键约束的行为可以被会话级设置临时改变。

为了解决这个问题,请检查以下几点:

  1. 确认外键约束定义:虽然从您的建表语句看没有问题,但还是建议通过查询系统表确认products表上的外键约束是否真的没有设置ON DELETE CASCADE。可以使用如下SQL查询:

    \d+ products
    

    查看输出中关于farm_id列的外键约束部分。

  2. 检查数据库配置和会话设置:确认是否有任何特定的数据库配置或当前会话的设置改变了外键行为。

  3. 检查触发器:确认farms表上或与之相关的任何触发器没有在执行删除操作时额外删除products表的数据。

  4. 应用程序逻辑审查:仔细检查您的应用程序代码,确保没有其他地方在删除农场后有逻辑去删除关联的产品。

如果以上检查都没有发现问题,可能需要更深入地调查数据库日志,以获取导致这一行为的具体线索。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答分类:
问答地址: