Kod błędu 1292 - Obcięta niepoprawna wartość DOUBLE - MySQL

85

Nie jestem pewien, co to za błąd!

#1292 - Truncated incorrect DOUBLE value: 

Nie mam pola ani danych z podwójną wartością!

Straciłem całą godzinę, próbując to rozgryźć!

oto moje zapytanie

INSERT INTO call_managment_system.contact_numbers 
    (account_id, contact_number, contact_extension, main_number, created_by)
SELECT
    ac.account_id,
    REPLACE(REPLACE(REPLACE(REPLACE(ta.phone_number, '-', ''), ' ', ''), ')', ''),'(','') AS Phone,
    IFNULL(ta.ext, '') AS extention,
    '1' AS MainNumber,
    '2' AS created_by
FROM 
    cvsnumbers AS ta
    INNER JOIN accounts AS ac ON ac.company_code = ta.company_code
WHERE 
    LENGTH(REPLACE(REPLACE(REPLACE(REPLACE(ta.phone_number, '-', ''), ' ', ''), ')', ''),'(','') ) = 10

oto mój pokaz tworzenia tabeli dla tabeli, do której trafiają wyniki

CREATE TABLE `contact_numbers` (  
    `number_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  
    `account_id` int(10) unsigned NOT NULL DEFAULT '0',  
    `person_id` int(11) NOT NULL DEFAULT '0',  
    `contact_number` char(15) NOT NULL,  
    `contact_extension` char(10) NOT NULL DEFAULT '',  
    `contact_type` enum('Primary','Direct','Cell','Fax','Home','Reception','Office','TollFree') NOT NULL DEFAULT 'Primary',  
    `contact_link` enum('Account','PDM','Other') NOT NULL DEFAULT 'Account',  
    `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '0 = inactive, 1=active', 
    `main_number` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1 = main phone number',  
    `created_on` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,  
    `created_by` int(11) NOT NULL,  
    `modified_on` datetime DEFAULT NULL,  
    `modified_by` int(11) NOT NULL DEFAULT '0',  
    PRIMARY KEY (`number_id`),  
    KEY `account_id` (`account_id`),  
    KEY `person_id` (`person_id`)
) ENGINE=InnoDB AUTO_INCREMENT=534 DEFAULT CHARSET=utf8
Mikrofon
źródło
7
Zgodnie z tym raportem o błędzie wiadomość pochodzi z porównania kolumny łańcuchowej z liczbą całkowitą, ponieważ obie są konwertowane do doubleporównania. Jak są ac.company_codei ta.company_codedeklarowane?
Barmar
Zobacz też bugs.mysql.com/bug.php?id=46641, gdzie plakat sugerował, że ten komunikat o błędzie powinien zostać przeredagowany na „GDZIE porównania między kolumnami liczbowymi i
nienumerycznymi
Obie te kolumny to int (11), a nie łańcuchy!
Mike
Czy możesz stworzyć sqlfiddle z przykładowymi danymi?
Barmar

Odpowiedzi:

156

Ten komunikat oznacza, że ​​próbujesz porównać liczbę i ciąg znaków w klauzuli WHERElub ON. W twoim zapytaniu jedynym potencjalnym miejscem, w którym może się to zdarzyć, jest ON ac.company_code = ta.company_code; albo upewnij się, że mają podobne deklaracje, albo użyj jawnego, CASTaby przekonwertować liczbę na ciąg.

Jeśli wyłączysz stricttryb, błąd powinien zmienić się w ostrzeżenie.

Barmar
źródło
1
Wow, co za mylący komunikat o błędzie. Dzięki za pomoc. Miałeś rację. Musiałem przesiąść się DB::table('contacts')->where('attendance', $int) ->update(["attendance" => $string]);naDB::table('contacts')->where('attendance', '' . $int) ->update(["attendance" => $string]);
Ryan
4
Dzięki za to. Aby rozszerzyć: istnieje wiele sposobów, w jakie można to wywołać. W moim przypadku było to użycie wyrażenia regularnego do wyodrębnienia liczby całkowitej z ciągu i porównania jej z liczbą całkowitą. Co dziwne, kiedy właśnie użyłem instrukcji SELECT, wszystko było w porządku: wybierz xxxx z t1 wewnętrznego sprzężenia t2 na t1.id = substr (value, locate (':', tagvalue) +1) Kiedy zmieniłem to w INSERT. ..SELECT, wystąpił błąd.
xgretsch
22

Poprawiłem ten błąd, ponieważ wystąpił błąd składni lub jakieś niechciane znaki w zapytaniu, ale MySQL nie był w stanie go złapać. andPodczas aktualizacji korzystałem między wieloma polami, np

update user 
set token='lamblala', 
    accessverion='dummy' and 
    key='somekey' 
where user = 'myself'

Problem w powyższym zapytaniu można rozwiązać zastępując andprzecinek ( ,)

user1926248
źródło
Dzięki nie jest to duży problem, ale kiedyś mały problem staje się wielkim problemem
Sumit Kumar Gupta
Dziękuję bardzo!!!! Zdarzyło mi się to w kontekście oświadczenia aktualizacyjnego
KC Baltz
8

Miałem ten sam problem. Próba porównania kolumny varchar (100) z wartością numeryczną 1. W rezultacie wystąpił błąd 1292. Naprawiono przez dodanie pojedynczych cudzysłowów wokół 1 („1”).

Dzięki za powyższe wyjaśnienie

ForeverLearner
źródło
3

TL; DR

Może to być również spowodowane zastosowaniem ORdo kolumn / literałów ciągów.

Pełna wersja

Otrzymałem ten sam komunikat o błędzie dla prostego INSERTstwierdzenia obejmującego widok:

insert into t1 select * from v1

chociaż wszystkie kolumny źródłowe i docelowe były typu VARCHAR. Po pewnym debugowaniu znalazłem główną przyczynę; widok zawierał ten fragment:

string_col1 OR '_' OR string_col2 OR '_' OR string_col3

który prawdopodobnie był wynikiem automatycznej konwersji następującego fragmentu z Oracle:

string_col1 || '_' || string_col2 || '_' || string_col3

( ||to konkatenacja ciągów znaków w Oracle). Rozwiązaniem było użycie

concat(string_col1, '_', string_col2, '_', string_col3)

zamiast.

Frank Schmitt
źródło
Dziękuję Ci! Nowy w MySQL, konkatenowałem używając SQL Server dozwolony sposób, coś w rodzaju string1 + string2 + string3. Twoja sugestia funkcji concat naprawiła ten błąd.
Marcy
1

Kiedy otrzymałem ten błąd, uważam, że był to błąd, jednak powinieneś pamiętać, że jeśli wykonasz oddzielne zapytanie z instrukcją SELECT i tą samą klauzulą ​​WHERE, możesz pobrać podstawowe ID z tej instrukcji SELECT SELECT CONCAT(primary_id, ','):) i wstawić je do nieudanego zapytania UPDATE z warunkami -> „WHERE [pierwotny_id] IN ([lista oddzielonych przecinkami podstawowych identyfikatorów z instrukcji SELECT)”, co pozwala złagodzić wszelkie problemy spowodowane przez klauzulę WHERE pierwotnego (nieudanego) zapytania.

Dla mnie osobiście, gdy użyłem cudzysłowów dla wartości w „WHERE ____ IN ([wartości tutaj])”, dotyczyło to tylko 10 z 300 oczekiwanych wpisów, co moim zdaniem wydaje się błędem.

Kylan Hurt
źródło
1

Widziałem kilka przypadków, w których występuje ten błąd:

1. użycie operatora nie równa się !=w whereklauzuli z listą wielu orwartości

Jak na przykład:

where columnName !=('A'||'B')

Można to rozwiązać za pomocą

where columnName not in ('A','B')

2. brak operatora porównania w if()funkcji:

select if(col1,col1,col2);

w celu wybrania wartości w, col1jeśli istnieje, i wyświetlenia wartości w col2... powoduje to błąd; można go rozwiązać za pomocą:

select if(col1!='',col1,col2);
enharmoniczny
źródło
0

W moim przypadku był to widok (mocno zagnieżdżony, widok w widoku) wstawka powodująca błąd w pliku :

CREATE TABLE tablename AS
  SELECT * FROM highly_nested_viewname
;

Rozwiązaniem, które ostatecznie zrobiliśmy, było zasymulowanie zmaterializowanego widoku (który w rzeczywistości jest tabelą) i okresowe wstawianie / aktualizowanie go przy użyciu procedur składowanych.

Nie
źródło
0

Wystąpił problem z ES6 i TypeORM podczas próby przekazania .where("order.id IN (:orders)", { orders }), gdzie ordersbył ciąg liczb oddzielonych przecinkami. Po przekonwertowaniu na literał szablonu problem został rozwiązany.

.where(`order.id IN (${orders})`);
mdawsondev
źródło
0

Jeśli użyłeś CHECK CONSTRAINT w tabeli dla długości pola łańcuchowego

np .: aby sprawdzić długość nazwy użytkownika> = 8

posługiwać się:

CHECK (CHAR_LENGTH(username)>=8)

zamiast

CHECK (username>=8)

napraw ograniczenie sprawdzania, jeśli któryś z nich ma nieprawidłowe porównanie typu danych

Varadhan Work
źródło
0

Jeśli nie masz pola lub danych z podwójną wartością, może powinieneś spróbować wyłączyć tryb ścisły sql.

W tym celu należy wyedytować plik „ my.ini ” znajdujący się w folderze instalacyjnym MySQL, znaleźć wiersz „Ustaw tryb SQL na ścisły” i zmienić poniższy wiersz:

# Set the SQL mode to strict
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

do tego, usuwanie „STRICT_TRANS_TABLES”

# Set the SQL mode to strict
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

Następnie musisz ponownie uruchomić usługę MySQL, aby włączyć tę zmianę.

Aby sprawdzić zmianę, otwórz edytor i wykonaj następujące zdanie sql:

SHOW VARIABLES LIKE 'sql_mode';

Bardzo ważne : po zapisaniu uważaj na format pliku. Zapisz to jako „UTF8” i nie jako „TFT8 z BOM”, ponieważ usługa nie uruchomi się ponownie.

Marc
źródło
Bezpieczniej jest to robić na podstawie sesji lub nawet lepiej tylko w konkretnym skrypcie, który modyfikuje $pdo->query('SET SESSION SQL_MODE = "ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"')$pdo->query('SET SESSION SQL_MODE = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"')
``