오류 코드 1292-잘못된 DOUBLE 값 잘림-MySQL


85

이 오류가 무엇인지 잘 모르겠습니다!

#1292 - Truncated incorrect DOUBLE value: 

이중 값 필드 또는 데이터가 없습니다!

나는 이것을 알아 내기 위해 한 시간을 낭비했다!

여기 내 질문입니다

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

여기에 결과가 들어가는 테이블에 대한 내 쇼 생성 테이블이 있습니다.

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

7
이 버그 보고서 에 따르면 메시지는 문자열 열을 정수와 비교하는 데서 나옵니다. 둘 다 double비교 를 위해 변환되기 때문 입니다. 방법입니다 ac.company_codeta.company_code선언?
Barmar

또한 bugs.mysql.com/bug.php?id=46641을 참조하십시오 . 포스터에서이 오류 메시지를 "숫자 열과 비 숫자 열 사이의 비교가 허용되지 않는 곳"으로 변경 될 것을 제안했습니다.
Barmar

이 두 열은 모두 int (11)이며 문자열이 아닙니다!
Mike

샘플 데이터로 sqlfiddle을 만들 수 있습니까?
Barmar 2011-04-17

답변:


156

이 메시지는 WHEREor ON절 에서 숫자와 문자열을 비교하려고 함을 의미합니다 . 귀하의 쿼리에서 발생할 수있는 유일한 잠재적 인 장소는 ON ac.company_code = ta.company_code; 유사한 선언이 있는지 확인하거나 명시 적을 사용 CAST하여 숫자를 문자열로 변환하십시오.

strict모드 를 끄면 오류가 경고로 바뀝니다.


1
와, 오해의 소지가있는 오류 메시지입니다. 도움을 주셔서 감사합니다. 당신이 옳았. 변경 DB::table('contacts')->where('attendance', $int) ->update(["attendance" => $string]);해야했습니다DB::table('contacts')->where('attendance', '' . $int) ->update(["attendance" => $string]);
Ryan

4
감사합니다. 확장하려면 : 이것이 트리거 될 수있는 모든 종류의 방법이 있습니다. 제 경우에는 정규 표현식을 사용하여 문자열에서 정수를 추출하고 이것을 정수와 비교했습니다. 이상하게도 방금 SELECT 문을 사용했을 때 모든 것이 괜찮 았습니다. ..SELECT, 오류가 발생했습니다.
xgretsch

22

쿼리에 구문 오류 또는 원치 않는 문자가 있었기 때문에이 오류를 수정했지만 MySQL은이를 잡을 수 없었습니다. and업데이트하는 동안 여러 필드 사이 에서 사용 했습니다.

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

위 쿼리의 문제는 and쉼표 ( ,) 로 대체 하여 해결할 수 있습니다.


감사합니다 이것은 큰 문제가되지 않지만 언젠가 작은 문제가 큰 문제가된다
수밋 쿠마르 굽타

정말 고맙습니다!!!! 이것은 업데이트 진술의 맥락에서 나에게 일어났다
KC Baltz

8

나는 같은 문제에 직면했다. varchar (100) 열을 숫자 1과 비교하려고합니다. 1292 오류가 발생했습니다. 1 ( '1') 주위에 작은 따옴표를 추가하여 수정되었습니다.

위의 설명에 감사드립니다


3

TL; DR

OR문자열 열 / 리터럴 에 적용 하여 발생할 수도 있습니다 .

풀 버전

INSERT보기와 관련된 간단한 문에 대해 동일한 오류 메시지 가 나타납니다.

insert into t1 select * from v1

모든 소스 및 대상 열이 VARCHAR. 디버깅 후 근본 원인을 찾았습니다. 뷰에는 다음 조각이 포함되었습니다.

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

아마도 Oracle의 다음 스 니펫을 자동으로 변환 한 결과 일 것입니다.

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

( ||는 Oracle의 문자열 연결입니다). 해결책은

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

대신.


감사합니다! MySQL을 처음 접한 저는 SQL Server에서 허용하는 방식 (예 : string1 + string2 + string3)을 사용하여 연결했습니다. concat 함수에 대한 제안으로이 오류가 수정되었습니다.
Marcy

1

나는이 오류를 받았을 때 나는 그러나 당신이 SELECT 문과 같은과 별도의 쿼리를 할 경우 WHERE 절 다음에서 기본 ID의를 잡을 수 있다는 것을 명심해야한다, 그것은 버그였다 믿는 SELECT : SELECT CONCAT(primary_id, ',')) 문 및 삽입 조건-> "WHERE [primary_id] IN ([SELECT 문에서 쉼표로 구분 된 기본 ID 목록)"을 사용하여 실패한 UPDATE 쿼리에 삽입하면 원래 (실패한) 쿼리의 WHERE 절로 인해 발생하는 문제를 완화 할 수 있습니다.

개인적으로 "WHERE ____ IN ([values ​​here])"의 값에 따옴표를 사용했을 때 300 개의 예상 항목 중 10 개만 영향을 받았으며 제 생각에는 버그처럼 보입니다.


1

이 오류가 발생하는 몇 가지 경우를 보았습니다.

1. 여러 값 목록이 !=있는 where절 에서 같지 않음 연산자 사용or

예 :

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

이것은 다음을 사용하여 해결할 수 있습니다.

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

2. if()함수 에서 비교 연산자 누락 :

select if(col1,col1,col2);

col1존재하는 경우 값을 선택 하고 그렇지 않으면 col2... 의 값을 표시 하려면 오류가 발생합니다. 다음을 사용하여 해결할 수 있습니다.

select if(col1!='',col1,col2);

0

제 경우에는 뷰 (높은 중첩, 뷰 인 뷰) 삽입으로 오류가 발생했습니다. :

CREATE TABLE tablename AS
  SELECT * FROM highly_nested_viewname
;

우리가 수행 한 해결 방법은 구체화 된 뷰 (실제로는 테이블)를 시뮬레이션하고 저장 프로 시저를 사용하여 주기적으로 삽입 / 업데이트하는 것이 었습니다.


0

통과하는 동안이 ES6와 문제 및 TypeORM을했다 .where("order.id IN (:orders)", { orders }), 어디는 orders쉼표는 숫자의 문자열을 분리했다. 템플릿 리터럴로 변환했을 때 문제가 해결되었습니다.

.where(`order.id IN (${orders})`);

0

문자열 필드 길이에 대해 테이블에서 CHECK CONSTRAINT 를 사용한 경우

예 : 사용자 이름 길이> = 8 확인

사용하다:

CHECK (CHAR_LENGTH(username)>=8)

대신에

CHECK (username>=8)

잘못된 데이터 유형 비교가있는 경우 검사 제약을 수정합니다.


0

이중 값 필드 또는 데이터가없는 경우 SQL 엄격 모드를 비활성화해야 할 수 있습니다.

이렇게하려면 MySQL 설치 폴더에있는 " my.ini "파일 을 편집해야합니다. "Set the SQL mode to strict"줄을 찾아 아래 줄을 변경합니다.

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

여기에 "STRICT_TRANS_TABLES"삭제

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

그런 다음이 변경 사항을 활성화하려면 MySQL 서비스다시 시작 해야합니다 .

변경 사항을 확인하려면 편집기를 열고 다음 SQL 문장을 실행하십시오.

SHOW VARIABLES LIKE 'sql_mode';

매우 중요 : 저장 후 파일 형식에주의하십시오. 서비스가 다시 시작되지 않으므로 "UTF8"로 저장하고 "TFT8 with BOM"으로 저장하지 마십시오.


세션별로이 작업을 수행하는 것이 더 안전하거나 '문제가되는 테이블'을 수정하는 특정 스크립트에서만 더 좋습니다. $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"')
Piemol
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.