sql >> Databasteknik >  >> RDS >> Mysql

Felsök PDO mySql infoga NULL i databasen istället för tomt

Detta verkar för mig vara en (n orapporterad?) bugg i PDO:s förberedda uttalandeemulering:

  1. implementeringen av PDOStatement::execute() så småningom anropar pdo_parse_params() ;

  2. som i sin tur försöker att citera/escape värden baserat på den relevanta parameterns datatyp (som indikeras av $data_type argument till PDOStatement::bindValue() och PDOStatement::bindParam() —alla parametrar tillhandahålls som $input_parameters till PDOStatement::execute() behandlas som PDO::PARAM_STR , som anges i dokumentationen för den funktionen);

  3. strängtypade värden escapes/citeras genom att anropar den relevanta databasdrivrutinens quoter() metod oavsett om de är null :i fallet med PDO_MySQL är det mysql_handle_quoter() , som (så småningom) skickar värdet till antingen >mysqlnd_cset_escape_quotes() eller mysql_cset_escape_slashes() , beroende på serverns NO_BACKSLASH_ESCAPES SQL-läge;

  4. ges en null argument returnerar båda dessa funktioner en tom sträng.

Min åsikt är att innan du slår på parameterns typ (i steg 2 ovan), pdo_parse_params() bör ställa in typen till PDO::PARAM_NULL om värdet är null . Vissa kanske menar att detta skulle förhindra typspecifik hantering av null värden där så är lämpligt, i vilket fall strängfallet (i steg 3 ovan) borde definitivt hantera null värden innan du fortsätter med ett anrop till förarens quoter() metod.

Som en tillfällig lösning är att inaktivera emulering av förberedda uttalanden vanligtvis det bästa ändå:

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);



  1. Ladda om MySQL-data inuti en DIV med Ajax

  2. Få ett objekts ID från dess namn i SQL Server:OBJECT_ID()

  3. Anonymisera dina plandetaljer inbyggt i Plan Explorer

  4. Hur man får århundradet från en dejt i Oracle