Pytanie Jak wstawić wartości NULL za pomocą PDO?


Używam tego kodu i jestem poza frustracją:

try {
    $dbh = new PDO('mysql:dbname=' . DB . ';host=' . HOST, USER, PASS);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
}
catch(PDOException $e)
{
    ...
}
$stmt = $dbh->prepare('INSERT INTO table(v1, v2, ...) VALUES(:v1, :v2, ...)');
$stmt->bindParam(':v1', PDO::PARAM_NULL); // --> Here's the problem

PDO::PARAM_NULL, null, '', wszystkie z nich zawodzą i rzucają ten błąd:

Błąd krytyczny: Nie można przekazać parametru 2 przez odniesienie w / opt / ...


93
2017-09-08 03:14


pochodzenie




Odpowiedzi:


Właśnie uczę się ChNP, ale myślę, że musisz użyć bindValue, nie bindParam

bindParam pobiera zmienną, odwołuje się i nie pobiera wartości w czasie wywoływania bindParam. Znalazłem to w komentarzu do dokumentów php:

bindValue(':param', null, PDO::PARAM_INT);

EDYCJA: P.S. Możesz ulec pokusie, aby to zrobić bindValue(':param', null, PDO::PARAM_NULL); ale to nie działało dla wszystkich (dziękuję Willowi Shaverowi za zgłoszenie).


121
2017-09-08 03:23



Nie jestem pewien różnicy między tymi dwoma, ale zbadam niektóre. Dzięki, twoja odpowiedź też była wspaniała. - Nacho
Myślę, że to może być lepsza odpowiedź niż moja (jeśli rzeczywiście działa) - Joe Phillips
Miałem problemy z PDO :: PARAM_NULL na MySql 5.1.53, ale PDO :: PARAM_INT z wartością null działało świetnie. - Will Shaver
Odyn: Myślę, że najważniejszą częścią jest przekazanie wszystkich trzech parametrów :). w pytaniu ign przekazywał PDO :: PARAM_NULL jako wartość, zamiast jako typ (i nie przekazując w ogóle typu). - JasonWoof
FYI: w większości przypadków nie masz nic przeciwko używaniu bindValue() koniec bindParam(); dla wszystkiego, nie tylko dla NULL wartość. Nie mogę wymyślić pojedynczego przypadku, w którym musiałbyś powiązać parametr z referencją zmiennej PHP - ale to właśnie bindParam() robi. - low_rents


Podczas używania bindParam() musisz przekazać zmienną, a nie stałą. Przed tą linią musisz utworzyć zmienną i ustawić ją null

$myNull = null;
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL);

Otrzymasz ten sam komunikat o błędzie, jeśli spróbujesz:

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);

42
2017-09-08 03:21



Masz rację, po prostu zdałem sobie sprawę, że zrobiłem to wcześniej w moim kodzie, $ null = PDO :: PARAM_NULL; dzięki. - Nacho
Lepiej używać bindValue () w tym przypadku, jeśli masz zamiar zrobić placeholder. Metoda bindParam () jest pierwotnie przeznaczona do wykonania zapytania, a następnie zmiany zmiennych i ponownego wykonania bez ponownego wiązania parametrów. bindValue () wiąże się natychmiast, bindParam () tylko przy wykonywaniu. - Hugo Zink
Zauważyłem, że wartość null musi być pisana małymi literami w wierszu $ myNull = null. $ myNull = NULL nie działa. - raphael75


Podczas używania INTEGER kolumny (które mogą być NULL) w MySQL, PDO ma pewne (dla mnie) nieoczekiwane zachowanie.

Jeśli użyjesz $stmt->execute(Array), musisz podać literał NULL i nie może dać NULL według zmiennej odniesienia. Więc to nie zadziała:

// $val is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => $val
));
// will cause the error 'incorrect integer value' when $val == null

Ale to zadziała:

// $val again is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => isset($val) ? $val : null
));
// no errors, inserts NULL when $val == null, inserts the integer otherwise

Próbowałem tego na MySQL 5.5.15 z PHP 5.4.1


25
2017-12-23 13:17



$ stmt-> execute (array (': param' =>! empty ($ val)? $ val: null)); Użyj! Empty, ponieważ w przypadku pustego łańcucha chciałbyś ustawić null w bazie danych - Shehzad Nizamani
@ShehzadNizamani Tylko jeśli typ kolumny jest liczbą całkowitą, tak jak w jego przykładzie, tak. Ale inaczej isset() lepiej koreluje NULL. Pusty ciąg jest także wartością. - StanE


Miałem ten sam problem i znalazłem to rozwiązanie działające z bindParam:

    bindParam(':param', $myvar = NULL, PDO::PARAM_INT);

6
2018-04-21 16:34





Dla tych, którzy nadal mają problemy (nie można przekazać parametru 2 przez odniesienie), zdefiniuj zmienną o wartości pustej, a nie tylko przekazuj pustą wartość do PDO:

bindValue(':param', $n = null, PDO::PARAM_INT);

Mam nadzieję że to pomoże.


5
2017-09-24 18:27





Jeśli chcesz wstawić NULL tylko wtedy, gdy value jest empty lub '', ale wstaw value kiedy jest dostępna.

A) Odbiera dane formularza za pomocą metody POST i wywołuje funkcję insert z tymi wartościami.

insert( $_POST['productId'], // Will be set to NULL if empty    
        $_POST['productName'] ); // Will be to NULL if empty                                

B) Ocenia, czy pole nie zostało wypełnione przez użytkownika i wstawia NULL Jeśli o to chodzi.

public function insert( $productId, $productName )
{ 
    $sql = "INSERT INTO products (  productId, productName ) 
                VALUES ( :productId, :productName )";

    //IMPORTANT: Repace $db with your PDO instance
    $query = $db->prepare($sql); 

    //Works with INT, FLOAT, ETC.
    $query->bindValue(':productId',  !empty($productId)   ? $productId   : NULL, PDO::PARAM_INT); 

    //Works with strings.
    $query->bindValue(':productName',!empty($productName) ? $productName : NULL, PDO::PARAM_STR);   

    $query->execute();      
}

Na przykład, jeśli użytkownik nie wprowadzi niczego na productName pole formularza $productName będzie SET ale EMPTY. Musisz sprawdzić, czy tak jest empty(), a jeśli tak, to wstaw NULL.

Testowane w PHP 5.5.17

Powodzenia,


3
2017-10-18 01:28



Lub możesz użyć MySQL IFNULL() funkcja w ciągu zapytania. Lubię to: $sql = "INSERT INTO products ( productId, productName ), VALUES ( IFNULL(:productId, NULL), IFNULL(:productName, NULL) )"; - starleaf1
Podoba mi się czystość twojego rozwiązania. Właśnie go przetestowałem, ale niestety wstawia puste ciągi zamiast NULL, gdy użytkownik nie pisze niczego na wejściu. To tylko kwestia preferencji, ale raczej mam wartości NULL zamiast pustych łańcuchów. - Arian Acosta


Spróbuj tego.

$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null

0
2018-05-04 01:11



Zanim spróbujesz odpowiedzieć na tak stare pytanie, najpierw powinieneś przeczytać inne odpowiedzi. Być może to już zostało wysłuchane. - Your Common Sense