รหัสข้อผิดพลาด 1292 - ค่า DOUBLE ที่ถูกตัดทอนไม่ถูกต้อง - Mysql


87

ฉันไม่แน่ใจว่านี่คือข้อผิดพลาดอะไร!

#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

8
ตามรายงานข้อบกพร่องนี้ข้อความมาจากการเปรียบเทียบคอลัมน์สตริงกับจำนวนเต็มเนื่องจากทั้งสองได้รับการแปลงเป็นเพื่อdoubleการเปรียบเทียบ เป็นอย่างไรac.company_codeและta.company_codeประกาศอย่างไร?
Barmar

ดูbugs.mysql.com/bug.php?id=46641ที่ผู้โพสต์แนะนำให้เปลี่ยนข้อความแสดงข้อผิดพลาดนี้เป็น "WHERE เปรียบเทียบระหว่างคอลัมน์ที่เป็นตัวเลขและไม่ใช่ตัวเลขไม่อนุญาตให้ใช้"
Barmar

คอลัมน์ทั้งสองนั้นเป็น int (11) ไม่ใช่สตริง!
Mike

คุณสามารถสร้าง sqlfiddle ด้วยข้อมูลตัวอย่างได้หรือไม่?
Barmar

คำตอบ:


159

ข้อความนี้หมายความว่าคุณกำลังพยายามเปรียบเทียบตัวเลขและสตริงใน a WHEREหรือONclause ในแบบสอบถามของคุณสถานที่ที่อาจเกิดขึ้นเฉพาะในกรณีที่ที่อาจจะเกิดขึ้นคือON ac.company_code = ta.company_code; ตรวจสอบให้แน่ใจว่ามีการประกาศที่คล้ายกันหรือใช้ Explicit CASTเพื่อแปลงตัวเลขเป็นสตริง

หากคุณปิดstrictโหมดข้อผิดพลาดควรกลายเป็นการเตือน


1
ว้าวข้อความแสดงข้อผิดพลาดที่ทำให้เข้าใจผิด ขอบคุณสำหรับการช่วยเหลือ. คุณคิดถูก ฉันต้องการเปลี่ยนDB::table('contacts')->where('attendance', $int) ->update(["attendance" => $string]);เป็นDB::table('contacts')->where('attendance', '' . $int) ->update(["attendance" => $string]);
Ryan

4
ขอบคุณสำหรับสิ่งนี้. หากต้องการขยาย: มีหลายวิธีที่สามารถเรียกใช้สิ่งนี้ได้ ในกรณีของฉันมันใช้ regexp เพื่อแยกจำนวนเต็มจากสตริงและเปรียบเทียบสิ่งนี้กับจำนวนเต็ม น่าแปลกเมื่อฉันใช้คำสั่ง SELECT มันก็ใช้ได้ดี: เลือก xxxx จาก t1 inner join t2 บน t1.id = substr (value, locate (':', tagvalue) +1) เมื่อฉันเปลี่ยนเป็น INSERT .. เลือกข้อผิดพลาดเกิดขึ้น
xgretsch

22

ฉันแก้ไขข้อผิดพลาดนี้เนื่องจากมีข้อผิดพลาดทางไวยากรณ์หรืออักขระที่ไม่ต้องการในแบบสอบถาม แต่ MySQL ไม่สามารถตรวจจับได้ ฉันใช้andระหว่างหลายฟิลด์ระหว่างการอัปเดตเช่น

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

ปัญหาในแบบสอบถามข้างต้นสามารถแก้ไขได้โดยแทนที่andด้วยลูกน้ำ ( ,)


ขอบคุณนี่ไม่ใช่ปัญหาใหญ่ แต่บางครั้งปัญหาเล็ก ๆ ก็กลายเป็นปัญหาใหญ่
Sumit Kumar Gupta

ขอบคุณมาก!!!! สิ่งนี้เกิดขึ้นกับฉันในบริบทของคำชี้แจงการอัปเดต
KC Baltz

8

ฉันประสบปัญหาเดียวกัน พยายามเปรียบเทียบคอลัมน์ varchar (100) กับตัวเลข 1 พบข้อผิดพลาด 1292 แก้ไขโดยการเพิ่มเครื่องหมายคำพูดเดี่ยวรอบ 1 ('1')

ขอบคุณสำหรับคำอธิบายข้างต้น


3

TL; ดร

นอกจากนี้ยังอาจเกิดจากการนำ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 CONCAT(primary_id, ',')คำสั่งSELECT นั้น :) และแทรก ลงในแบบสอบถาม UPDATE ที่ล้มเหลวโดยมีเงื่อนไข -> "WHERE [primary_id] IN ([list of comma-Separated primary ID's from the SELECT statement)" ซึ่งช่วยให้คุณสามารถบรรเทาปัญหาใด ๆ ที่เกิดจากคำสั่ง WHERE ของข้อความค้นหาเดิม (ล้มเหลว)

สำหรับฉันโดยส่วนตัวแล้วเมื่อฉันใช้เครื่องหมายคำพูดสำหรับค่าใน "WHERE ____ IN ([ค่าที่นี่])" มีเพียง 10 รายการจากทั้งหมด 300 รายการที่คาดว่าจะได้รับผลกระทบซึ่งในความคิดของฉันดูเหมือนว่าเป็นข้อบกพร่อง


1

ฉันเคยเห็นสองสามกรณีที่เกิดข้อผิดพลาดนี้:

1. ใช้ตัวดำเนินการ not equals !=ใน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

ในการทำเช่นนั้นคุณต้องแก้ไขไฟล์ " my.ini " ที่อยู่ในโฟลเดอร์การติดตั้ง MySQL ให้ค้นหาบรรทัด "Set the SQL mode to เข้มงวด" และเปลี่ยนบรรทัดด้านล่าง:

# 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 พร้อม 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.