SQL Server แทรกเข้าไป - วิธีการระบุคอลัมน์ที่ทำให้เกิดข้อผิดพลาดการตัด


11

ฉันมีขั้นตอนการจัดเก็บที่แทรก 650 ฟิลด์ลงในตาราง การแทรกล้มเหลวด้วยข้อผิดพลาดการตัด

มันง่ายมาก

INSERT INTO
SELECT (a bunch of fields) 
FROM (a bunch of tables)

ด้านล่างนี้เป็นข้อความแสดงข้อผิดพลาด:

ข่าวสารเกี่ยวกับ 8152, ระดับ 16, สถานะ 14, กระบวนงาน DSP_Procedure, สาย 1075 สายอักขระหรือข้อมูลไบนารีจะถูกตัดทอน

มีวิธีที่รวดเร็วที่ฉันสามารถระบุฟิลด์ที่ทำให้เกิดข้อผิดพลาดการตัด?

ความจริงที่ว่าคำสั่ง select ที่จะแทรกลงในตารางมี 650 ฟิลด์ทำให้ยากที่จะระบุว่าฟิลด์ใดที่ทำให้เกิดข้อผิดพลาดการตัด

ฉันคิดว่าฉันสามารถแสดงความคิดเห็นบล็อกของเขตข้อมูลได้ครั้งละหนึ่งครั้งเพื่อให้มีการแทรก SP เพียง 100 ครั้งในแต่ละครั้งจากนั้นจึงเรียกใช้ SP 6 หรือ 7 ครั้งที่แตกต่างกันจนกว่าฉันจะแคบลงอย่างน้อย 100 กลุ่ม ที่จะมีฟิลด์ที่ทำให้เกิดข้อผิดพลาดการตัด

อีกทางหนึ่งฉันคิดว่าบางทีฉันสามารถSELECT INTOสร้างตารางใหม่และเปรียบเทียบความยาวข้อมูลในตารางเทียบกับความยาวข้อมูลของตารางเป้าหมายที่ฉันพยายามแทรกลงใน SP ของฉันเพื่อดูว่าเขตข้อมูลใดมีความยาวของเขตข้อมูลที่ยาวเกินกว่าที่คาดหมาย ..

ฉันใช้ SQL Server 2014

ทางเลือกที่ง่ายกว่านี้ไหม?


1
ฉันจะไปที่ INFORMATION_SCHEMA.COLUMNS และเปรียบเทียบประเภทข้อมูลกับประเภทที่คุณพยายามแทรก น่าเสียดายที่เซิร์ฟเวอร์ SQL ไม่มีประเภทข้อมูลแบบไดนามิกสำหรับการประกาศตัวแปรเช่น ORACLE
MguerraTorres

2
ฉันจะใช้ตัวเลือกที่สองแทรกลงในตาราง (หรือ #temp) ใหม่แล้วเปรียบเทียบความยาวคอลัมน์ หรือคุณสามารถล้อม LEN () รอบ ๆ คอลัมน์ทั้งหมดในตัวเลือกจากนั้นให้ข้อความค้นหาภายนอกมีค่า MAX () สำหรับแต่ละ ... ที่จะให้ความยาวข้อความที่ใหญ่ที่สุดสำหรับฟิลด์ แน่นอนว่ามันเป็นเขตข้อมูลถ่านที่ทำให้คุณมีปัญหา ไม่ได้ใช้เล็ก ๆ น้อย ๆ ตลอดกาลหรือจิ๋วจิ๋ว
Jonathan Fite

1
ฉันจะไปกับวิธี "เลือกเข้าไป" และเปรียบเทียบความยาวของคอลัมน์ใช่ อาจด้วย "WHERE 1 = 0" เพื่อให้ตารางไม่มีแถว อึดอัดใจหาก SELECT ของคุณไม่มีชื่อเฉพาะสำหรับคอลัมน์ที่เลือก ฉันจัดรูปแบบรายการคอลัมน์แบบยาวเป็นหนึ่งบรรทัดของสคริปต์ต่อคอลัมน์จากนั้นชื่อคอลัมน์ "AS" ในบรรทัดถัดไปหากจำเป็นและบรรทัดว่างหลังจากสี่คอลัมน์เพื่อให้ง่ายต่อการเก็บไว้ในรายการ นอกจากนี้ยังสนับสนุนการเลือกหลายบรรทัดและทำ Ctrl + K Ctrl + C เพื่อเปลี่ยนเป็นความคิดเห็นดังนั้นคุณสามารถโจมตีการดำเนินการแทรกได้ด้วยวิธีดังกล่าว แต่คอลัมน์ที่เหลืออยู่จะต้องเป็นโมฆะ
Robert Carnegie

คำตอบ:


3

ถ้าคุณอยู่ใน SQL Server 2016 (SP2, CU6 หรือใหม่กว่า) ซึ่งเป็นหนึ่งในตัวเลือกคือการเปิดสถานะการติดตาม 460 (QUERYTRACEON 460)กรัม ผลลัพธ์จะระบุคอลัมน์และข้อมูลที่ละเมิด

ดูบทความนี้สำหรับรายละเอียด https://www.brentozar.com/archive/2019/03/how-to-fix-the-error-string-or-binary-data-would-be-truncated/

หากคุณไม่สนใจเกี่ยวกับการตัดทอนคุณสามารถใช้SET ANSI_WARNINGS OFFเพื่อละเว้นการตัดทอนชนิดนั้นได้


9

น่าเสียดายที่คุณได้พบกับ"คุณสมบัติ" ที่ค่อนข้างเก่า มีตั๋ว Connect เปิดให้บริการมาตั้งแต่ปี 2551 และเป็นเวลาเกือบสิบปีแล้วที่เรื่องนี้ไม่สำคัญพอที่จะรับประกันการแก้ไข

วิธีแก้ปัญหามาตรฐานเป็นเช่นคุณคิดที่select into...ตามมาด้วยการเปรียบเทียบข้อมูลเมตาตาราง ความเป็นไปได้อีกอย่างหนึ่งคือการค้นหาแบบไบนารี่คอลัมน์ที่ละเมิด มีแฮ็กสำหรับการเปรียบเทียบข้อมูลเมตา แต่ไม่มีวิธีแก้ปัญหาที่เรียบง่ายและสง่างาม บางทีเครื่องมือของบุคคลที่สามอาจช่วยได้ แต่ฉันไม่ทราบ


1

การใช้ (QUERYTRACEON 460) ไม่ได้ผลสำหรับฉันเมื่อวางไว้ที่ส่วนท้ายของแบบสอบถาม

ฉันเปิดใช้งานที่ระดับ DB และใช้งานได้:

DBCC TRACEON(460, -1);
GO

แต่ให้แน่ใจว่าได้ปิดมันทันทีที่คุณพบและแก้ไขปัญหาอย่าปล่อยทิ้งไว้!

DBCC TRACEOFF(460, -1);
GO
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.