【问题标题】:Error 145: Cannot add or update a child row within inserting data into database .. mySQL错误 145:无法在将数据插入数据库中添加或更新子行 .. mySQL
【发布时间】:2026-02-16 03:30:02
【问题描述】:

我在 MySQL 中创建了一个数据库,并使用脚本将数据添加到该数据库中。但是当我想向我的 Pnumbers 表中添加一些数据时,我遇到了这个问题。

Cannot add or update a child row: a foreign key constraint fails (`blahari1/Pnumbers`, CONSTRAINT `Pnumbers_ibfk_1` FOREIGN KEY (`customerID`) REFERENCES `Customers` (`ID`))

任何想法如何解决这个问题?

数据库的实现:

USE blahari1;
DROP TABLE IF EXISTS Calls;
DROP TABLE IF EXISTS Pnumbers;
DROP TABLE IF EXISTS Customers;
DROP TABLE IF EXISTS Operators;
DROP TABLE IF EXISTS Tarifs;

CREATE TABLE Customers (
  ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(30) UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

CREATE TABLE Operators (
ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

CREATE TABLE Tarifs (
  ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  Name VARCHAR(30) UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

CREATE TABLE Pnumbers (
  ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  pnumber VARCHAR(9) NOT NULL UNIQUE,
  minutes INTEGER UNSIGNED NOT NULL,
  customerID INTEGER UNSIGNED NOT NULL,
  operatorID INTEGER UNSIGNED NOT NULL,
  tarifID INTEGER UNSIGNED NOT NULL,
  FOREIGN KEY (customerID) REFERENCES Customers (ID),
  FOREIGN KEY (operatorID) REFERENCES Operators (ID),
  FOREIGN KEY (tarifID) REFERENCES Tarifs (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

CREATE TABLE Calls (
  ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  length INTEGER UNSIGNED NOT NULL,
  fk_PNFrom INTEGER UNSIGNED NOT NULL,
  fk_PNTo INTEGER UNSIGNED NOT NULL,
  FOREIGN KEY (fk_PNFrom) REFERENCES Pnumbers (ID),
  FOREIGN KEY (fk_PNTo) REFERENCES Pnumbers (ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

应该将数据添加到数据库的脚本:

#!/bin/bash
# blahari1
LOGIN="mysql --user=blahari1 --password=animate --database=blahari1"

#-------------
insertion() {
    if [ "$1" == "numbers" ]; then
        while read line; do
            name="`echo $line | sed 's/,.*//'`";
            numberV="`echo $line | awk '{print $2}' | sed 's/,.*//'`";
            operatorV="`echo $line | awk '{print $3}' | sed 's/,.*//'`";
            tarifV="`echo $line | awk '{print $4}' | sed 's/,.*//'`";
            minutesV="`echo $line | awk '{print $5}'`";
            if [ ! "`echo "SELECT name '' FROM Customers WHERE name='$name';" | $LOGIN`" ]; then
                echo "INSERT INTO Customers (name) VALUES ('$name');" | $LOGIN
            fi
            if [ ! "`echo "SELECT name '' FROM Operators WHERE name='$operatorV';" | $LOGIN`" ]; then
                echo "INSERT INTO Operators (name) VALUES ('$operatorV');" | $LOGIN
            fi
            if [ ! "`echo "SELECT name '' FROM Tarifs WHERE name='$tarifV';" | $LOGIN`" ]; then
                echo "INSERT INTO Tarifs (name) VALUES ('$tarifV');" | $LOGIN
            fi
            idC="`echo "SELECT ID FROM Customers WHERE name='$name';" | $LOGIN`";
            idO="`echo "SELECT ID FROM Operators WHERE name='$operatorV';" | $LOGIN`";
            idT="`echo "SELECT ID FROM Tarifs WHERE name='$tarifV';" | $LOGIN`";
            echo "INSERT INTO Pnumbers (pnumber, operatorID, tarifID, minutes, customerID) VALUES ('$numberV', '$idO', '$idT', '$minutesV', '$idC');" | $LOGIN;
        done < customers.txt
    elif [ "$1" == "calls" ]; then
        while read line; do
            fromV="`echo $line | sed 's/,.*//'`";
            fromV="`echo "SELECT ID FROM Pnumbers WHERE pnumber='$fromV';" | $LOGIN`";
            toV="`echo $line | awk '{print $2}' | sed 's/,.*//'`";
            toV="`echo "SELECT ID FROM Pnumbers WHERE pnumber='$toV';" | $LOGIN`";
            lengthV="`echo $line | awk '{print $3}'`";
            echo "INSERT INTO Calls (fk_PNFrom, fk_PNTo, length) VALUES ('$fromV', '$toV', '$lengthV');" | $LOGIN;
        done < calls.txt
    fi
    echo "SELECT * FROM Customers;" | $LOGIN
    echo "SELECT * FROM Operators;" | $LOGIN
    echo "SELECT * FROM Pnumbers;" | $LOGIN
    echo "SELECT * FROM Tarifs;" | $LOGIN
    echo "SELECT * FROM Calls;" | $LOGIN
}

queries(){

if [ "$1" = "calls" ];then
    id="`echo "SELECT NumbersFrom.number as PNFrom, NumbersTo.number as PNTo 
        FROM Calls, Pnumbers as NumbersFrom,Pnumbers as NumbersTo, Operators
        WHERE Operators.name = '$1' AND Operators.ID = NumbersFrom.operatorID AND  Calls.fk_PNFrom = NumbersFrom.ID
        AND Calls.fk_PNTo = NumbersTo.ID;" | $LOGIN`"
    echo "$id"
    elif [ "$1" = "credit" ];then
      kredit="`echo "SELECT (SELECT SUM(Pnumbers.minutes) FROM Pnumbers, Customers
            WHERE Customers.name = '$1' AND Customers.ID = Pnumbers.customerID) - SUM(Calls.length)
            FROM Customers,Pnumbers,Calls
            WHERE Customers.name = '$1' AND Customers.ID = Pnumbers.customerID AND Pnumbers.ID = Calls.fk_PNFrom;" | $LOGIN`"  
    echo "$kredit"
    elif [ "$1" = "maxcalls" ];then
    maxcalls="`echo "SELECT Customers.name FROM Customers, Pnumbers, Calls 
    WHERE Customers.ID = Pnumbers.customerID AND Pnumbers.ID = Calls.fk_PNFrom
    GROUP BY Customers.ID ORDER BY SUM(Calls.length) DESC LIMIT 1;" | $LOGIN`"      
    echo "$maxcalls"

    elif [ "$1" = "longest" ];then
    maxlength="`echo "SELECT Customers.name FROM Customers,Pnumbers AS NumbersFrom,Pnumbers AS NumbersTo, Calls, Operators 
    WHERE Operators.name = '$1' AND Operators.ID = NumbersFrom.operatorID AND Customers.ID = NumbersTo.customerID
    AND NumbersTo.ID = Calls.fk_PNTo AND NumbersFrom.ID = Calls.fk_PNFrom 
    ORDER BY Calls.length DESC LIMIT 1;" | $LOGIN`"
    echo "$maxlength"

        #response=`echo "select person.name from phone_number, calls, person where person.id = phone_number.personId and phone_number.id=calls.receipienId and select calls.receipienId where calls.length=max(calls.length);" | $LOGIN`
fi
}


if [ "$1" = "--variant" ]; then
    echo "5"
elif [ "$1" = "--insert" ];then 
    insertion "$2" "$3"
elif [ "$1" = "--query" ];then
    queries "$2" "$3"
elif [ "$1" = "--debug" ];then
    echo "debug"
fi

非常感谢您的帮助。谢谢

【问题讨论】:

  • @user1613360 他刚刚插入了它们,然后他在INSERT 之前的行中选择了ID。它们不必存在吗?

标签: mysql database bash foreign-key-relationship


【解决方案1】:

您需要在mysql 命令上使用--skip-column-names 选项。否则,SELECT 语句的输出将类似于:

ID
123

您将尝试将此两行字符串插入Pnumbers 表中。当它尝试将其转换为整数时,它会转换为0,而Customer 表中不存在该0。 所以使用:

LOGIN="mysql --user=blahari1 --password=animate --database=blahari1 --skip-column-names"

【讨论】:

    【解决方案2】:

    您的一个外键中可能有 NULL 值,请先尝试摆脱这些值。

    【讨论】:

    • 他如何获得空值?它们是其他表的主键,它们使用AUTO_INCREMENT,所以它们不能为空。