【问题标题】:MySQL int column allows null but enters null as zeroMySQL int 列允许 null 但输入 null 作为零
【发布时间】:2016-10-19 02:23:10
【问题描述】:

我环顾四周,注意到一些人遇到了同样的问题,但他们的疏忽似乎不适用于这里。

我有一个 PHP 函数可以将一组值添加到表中。它首先检查值是否为空,如果是,则将它们替换为NULL,以便在表字段中放置null。我将null 放入的每个字段都允许null,但在其中放置0

这里有一些代码:

public static function AddGame($array, $tId)
{
    global $db; // Bring DB into scope
    // Get IDs from particular names
    $locId = $array['fLocation'];
    // Ensure empty values are SQL null
    $hTeamId = "'{$array['fHomeTeam']}'";
    $vTeamId = "'{$array['fVisitTeam']}'";
    $hScore = "'{$array['fHomeScore']}'";
    $vScore = "'{$array['fVisitScore']}'";
    $hHoldFor = "'{$array['fHomeHoldFor']}'";
    $vHoldFor = "'{$array['fVisitHoldFor']}'";
    // Prepare row for insertion
    $row = "'','$tId','$locId',$hTeamId,$vTeamId,'{$array['fDate']}','{$array['fTime']}',$hScore,$vScore,'{$array['fGameType']}',$hHoldFor,$vHoldFor";
    $stmt = $db->prepare("INSERT INTO `game` VALUES($row)");
    if($stmt->execute()) return true;
    else return false;
}

我已经在多行调试了这个函数并转储了 $row 字符串,它显示了这个,这是预期的:

'','1','1','21','21','10/10/12','10:30AM','NULL','NULL','pool','NULL ','NULL'

然而,当我检查表格文本类型字段时,字面上的值 NULL 这不是我想要的,而且 int 字段也显示为 0。如果我将值留空或 PHP 的 null 则文本字段显示为空(或正确 null 我想)但整数仍显示为 0

我认为这只是由于我间接插入值的方式造成的。

这里是 SHOW CREATE TABLE game

创建表`游戏`( `id` int(11) NOT NULL AUTO_INCREMENT, `tId` int(11) 非空, `盖子` int(11) 非空, `hTeamId` int(11) 默认为空, `vTeamId` int(11) 默认为空, `date` 文本不为空, `time` 文本不为空, `hScore` int(11) 默认为空, `vScore` int(11) 默认为空, `type` 文本不为空, `hHoldFor` 文本, `vHoldFor` 文本, 主键(`id`) ) 引擎=InnoDB AUTO_INCREMENT=17 默认字符集=latin1

更新:

插入“游戏”值('','1','1','','','10/09/12','9:30AM','','','pool','winner池 A','池 B 的获胜者')

【问题讨论】:

    标签: php mysql database


    【解决方案1】:

    您将所需的NULL 列的值物理设置为'NULL' 的字符串

    NULL != 'NULL'

    如果您将这些列的表结构设置为 NULL,您可以在查询中省略它们,插入时它们将自动为 NULL

    改为这样做:

    if(!empty($hHoldFor)) $hHoldFor = $array['fHomeHoldFor'];
    

    更新

    我正在进一步研究您的示例,并且存在第二个失败点。

    $row = ... ",'$hHoldFor','$vHoldFor'";
    

    如果您设置$hHoldFor = NULL,上述行将在NULL 周围插入引号,将其转换回NULL 的字符串。

    试试这个:

    if(!empty($hHoldFor)) $hHoldFor = "'{$array['fHomeHoldFor']}'";
    ...  
    $row = ... ",$hHoldFor,$vHoldFor";
    

    这将删除 QUERY 字符串中该值周围的单引号并将它们添加到变量本身。

    更新 2

    这是一个使用您的架构的SQLFiddle。它为 NULL 列返回 NULL。你能做一个echo "INSERT INTOgameVALUES($row)"; 并发布输出吗?问题是 PHP 仍在某处将 NULL 转换为 'NULL'。这将帮助我们深入了解它。

    更新 3

    问题和想象的一样。您的 PHP 正在将一个空白字符串 '' 插入到您的数据库中,这不是 NULL 值。 NULL 是一个类型,'' 是一个没有长度的字符串。

    INSERT INTO `game` VALUES('','1','1','','','10/09/12','9:30AM','','','pool','winner of pool A','winner of pool B')
    

    试试这个:

    public static function AddGame($array, $tId)
    {
        global $db; // Bring DB into scope
        // Get IDs from particular names
        $locId = $array['fLocation'];
        // Ensure empty values are SQL null
        $hTeamId = (strlen($array['fHomeTeam']) != 0 ? "'{$array['fHomeTeam']}'" : 'NULL');
        $vTeamId = (strlen($array['fVisitTeam']) != 0 ? "'{$array['fVisitTeam']}'" : 'NULL');
        $hScore = (strlen($array['fHomeScore']) != 0 ? "'{$array['fHomeScore']}'" : 'NULL');
        $vScore = (strlen($array['fVisitScore']) != 0 ? "'{$array['fVisitScore']}'" : 'NULL');
        $hHoldFor = (strlen($array['fHomeHoldFor']) != 0 ? "'{$array['fHomeHoldFor']}'" : 'NULL');
        $vHoldFor = (strlen($array['fVisitHoldFor']) != 0 ? "'{$array['fVisitHoldFor']}'" : 'NULL');
        // Prepare row for insertion
        $row = "'','$tId','$locId',$hTeamId,$vTeamId,{$array['fDate']}','{$array['fTime']}',$hScore,$vScore,'{$array['fGameType']}',$hHoldFor,$vHoldFor";
        $stmt = $db->prepare("INSERT INTO `game` VALUES($row)");
        if($stmt->execute()) return true;
        else return false;
    }
    

    【讨论】:

    • 我预计会是这种情况,所以我也尝试了不带引号的情况,所以 = null。这将是 PHP 对 null 的表示。这也不起作用。不过,我现在正在尝试您的答案,谢谢。
    • 好的,所以我首先将所有变量定义为 null 以避免未定义变量错误。 int 字段仍显示为零。
    • 我在更新中指出了第二个故障点。看看吧。
    • 这很好,谢谢。如果这可行,我不需要检查空的条件吗?不管它会把值还是空值放进去?
    • 好的,我照你说的做了,但省略了空检查,它似乎没有必要。我修改了原始帖子中的代码,但那些该死的整数仍然显示为零。
    【解决方案2】:

    您不能插入'NULL'。删除 NULL 周围的单引号。

    你的字符串

    '','1','1','21','21','10/10/12','10:30AM','NULL','NULL','pool','NULL','NULL'
    

    应该是这样的

    '','1','1','21','21','10/10/12','10:30AM',NULL,NULL,'pool',NULL,NULL
    

    您还应该在创建INSERT 时定义一个列列表(即INSERT INTO table (col1, col2) VALUES ...

    编辑 1

    我建议您查看您的SHOW CREATE TABLE tbl_name

    编辑 2

    testing this 之后,我仍然会说问题在于您如何插入数据。

    (18,1,1,21,21,'10/10/12','10:30AM',NULL,NULL,'pool',NULL,NULL)

    工作。

    ('18','1','1','21','21','10/10/12','10:30AM','NULL','NULL','pool','NULL','NULL')

    不起作用:Incorrect integer value: 'NULL' for column 'hScore' at row 1:

    编辑 3

    这是您的课程的改进版本:

    public static function AddGame($array, $tId)
    {
        global $db; // Bring DB into scope
    
        // Get IDs from particular names
        $locId = $array['fLocation'];
    
        // Ensure empty values are SQL null
        $hTeamId = empty($array['fHomeTeam']) ? 'NULL' : "'" . $array['fHomeTeam'] . "'";
        $vTeamId = empty($array['fVisitTeam']) ? 'NULL' : "'" . $array['fVisitTeam'] . "'";
        $hScore = empty($array['fHomeScore']) ? 'NULL' : "'" . $array['fHomeScore'] . "'";
        $vScore = empty($array['fVisitScore']) ? 'NULL' : "'" . $array['fVisitScore'] . "'";
        $hHoldFor = empty($array['fHomeHoldFor']) ? 'NULL' : "'" . $array['fHomeHoldFor'] . "'";
        $vHoldFor = empty($array['fVisitHoldFor']) ? 'NULL'  : "'" . $array['fVisitHoldFor'] . "'";
    
        // Prepare row for insertion
        $row = "$tId,$locId,$hTeamId,$vTeamId,'{$array['fDate']}','{$array['fTime']}',$hScore,$vScore,'{$array['fGameType']}',$hHoldFor,$vHoldFor";
        $stmt = $db->prepare("INSERT INTO game (tId, Lid, hTeamId, vTeamId, date, time, hScore, vScore, type, hHoldFor, vHoldFor) VALUES($row)");
        if($stmt->execute()) return true;
        else return false;
    }
    

    NULL 值将用引号括起来,否则将分配给NULL。我还定义了INSERT 的列列表并排除了id,因为它是AUTO_INCREMENT 列。

    【讨论】:

    • 那还是不行。我提到我在帖子底部尝试过这个。
    • 你可以试试你的字符串的编辑版本吗?如果这不起作用,您可以回复您收到的错误吗?
    • 没有错误,所有内容都会插入,这就是为什么我从不先定义列名的原因,因为它只会增加不必要的复杂性。问题是 int 字段显示零而不是空白,或 (null)。
    • @Lee 你能贴出你的SHOW CREATE TABLE tbl_name 的样子吗?
    • 我贴出来了。 Navicat 设计视图一直在骗我? :S
    【解决方案3】:

    您的列是否允许NULL 值?再次检查 DDL,可能您已将 DEFAULT VALUE 设置为零。

    当您尝试在列中插入 null 值时,不要用单引号括起来。示例

    INSERT INTO tableName (colName, ColNameB) VALUES (1, NULL)
    

    【讨论】:

    • 是的,勾选了允许 null 复选框,并且它们也设置为默认 null。
    • 插入值时,不要用单引号括起来。
    【解决方案4】:

    就我而言,我必须显示三种情况:Case-empty、Case-yes 和 Case-no。我计划使用空、一和零。但是空值始终保存为 0。我正在工作的列接受空条目,但我所有的空值都保存为零。 我的解决方案是将 Case-empty 视为零,将 Case-yes 视为第一,将 case-no 视为第二。这是一种解决方法,但解决了问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 2018-03-09
      • 2015-06-29
      • 2016-08-29
      • 1970-01-01
      • 2010-09-17
      相关资源
      最近更新 更多