SQL Server Chèn vào - Cách xác định cột gây ra lỗi cắt ngắn


11

Tôi có một thủ tục được lưu trữ chèn 650 trường vào một bảng. Việc chèn không thành công với lỗi cắt ngắn.

Thật đơn giản

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

Dưới đây là thông báo lỗi:

Msg 8152, Cấp 16, Trạng thái 14, Quy trình DSP_Procedure, Dòng 1075 Chuỗi hoặc dữ liệu nhị phân sẽ bị cắt ngắn.

Có cách nào nhanh chóng để tôi có thể xác định trường nào gây ra lỗi cắt ngắn không?

Việc câu lệnh select được chèn vào bảng có 650 trường khiến cho việc xác định trường nào gây ra lỗi cắt ngắn khó khăn.

Tôi nghĩ rằng tôi có thể nhận xét các khối trường tại một thời điểm để chỉ có SP chèn 100 trường cùng một lúc và sau đó chạy SP 6 hoặc 7 lần khác nhau cho đến khi tôi ít nhất có thể thu hẹp vào một nhóm 100 trường sẽ chứa trường gây ra lỗi cắt ngắn.

Ngoài ra, tôi nghĩ rằng có lẽ tôi chỉ có thể SELECT INTOmột bảng mới và sau đó so sánh độ dài dữ liệu trong bảng với độ dài dữ liệu của bảng mục tiêu mà tôi đang cố gắng chèn vào SP của mình để xem trường nào chứa chiều dài trường dài hơn dự kiến. ..

Tôi đang sử dụng SQL Server 2014.

Bất kỳ lựa chọn thay thế dễ dàng hơn?


1
Tôi sẽ truy cập vào Information_SCHema.COLUMNS và so sánh các loại dữ liệu với các loại dữ liệu bạn đang cố gắng chèn. Thật không may, máy chủ SQL không có kiểu dữ liệu động để khai báo biến như ORACLE.
MguerraTorres

2
Tôi sẽ sử dụng tùy chọn thứ hai của bạn, chèn vào bảng mới (hoặc #temp) và sau đó so sánh độ dài cột. Hoặc bạn có thể bao bọc LEN () xung quanh tất cả các cột trong phần chọn và sau đó có phần ngoài thực hiện MAX () cho mỗi ... sẽ cung cấp cho bạn độ dài văn bản lớn nhất cho các trường. Tất nhiên, điều đó giả định rằng đó là một lĩnh vực char đang mang đến cho bạn những vấn đề. Không sử dụng smalldatetime hay tinyint?
Jonathan Fite

1
Tôi sẽ sử dụng phương pháp "Chọn vào" và so sánh độ dài cột, vâng. Có thể với "WHERE 1 = 0" để bảng không có hàng. Lúng túng nếu CHỌN của bạn không bao gồm tên duy nhất cho các cột được chọn. Tôi định dạng danh sách cột dài dưới dạng một dòng tập lệnh cho mỗi cột, sau đó tên cột "NHƯ" trên dòng tiếp theo nếu được yêu cầu và một dòng trống sau bốn cột để dễ dàng giữ vị trí trong danh sách. Điều đó cũng hỗ trợ chọn nhiều dòng và thực hiện Ctrl + K Ctrl + C để thay đổi chúng thành nhận xét, do đó bạn có thể tấn công thao tác Chèn theo cách đó, nhưng các cột bị bỏ lại sẽ phải là null.
Robert Carnegie

Câu trả lời:


3

Nếu bạn đang sử dụng SQL Server 2016 (SP2, CU6 hoặc mới hơn), một tùy chọn là bật cờ theo dõi 460, vd (QUERYTRACEON 460). Đầu ra sẽ chỉ ra cột và dữ liệu vi phạm.

Xem bài viết này để biết chi tiết. https://www.brentozar.com/archive/2019/03/how-to-fix-the-error-opes-or-binary-data-would-be-truncated/

Nếu bạn không quan tâm đến việc cắt ngắn, bạn có thể sử dụng SET ANSI_WARNINGS OFFđể bỏ qua loại cắt ngắn đó.


9

Thật không may, bạn đã gặp một "tính năng" khá cũ . Đã có một vé Connect được mở từ năm 2008 và trong gần mười năm, điều này không đủ quan trọng để đảm bảo sửa chữa.

Cách giải quyết tiêu chuẩn là, như bạn đã tìm ra, select into...tiếp theo là so sánh siêu dữ liệu bảng. Một khả năng khác là tìm kiếm nhị phân cột vi phạm, nhưng đó cũng là công việc thủ công. Có một số hack để so sánh siêu dữ liệu, nhưng giải pháp đơn giản, thanh lịch không tồn tại. Có thể một số công cụ của bên thứ ba sẽ giúp ích, nhưng tôi không biết điều đó.


1

Việc sử dụng (QUERYTRACEON 460) không hiệu quả với tôi khi đặt nó ở cuối truy vấn của tôi.

Tôi đã bật nó ở cấp DB và nó hoạt động:

DBCC TRACEON(460, -1);
GO

Nhưng, hãy đảm bảo tắt nó đi sau khi bạn đã tìm thấy và khắc phục sự cố, đừng để nó xảy ra!

DBCC TRACEOFF(460, -1);
GO
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.