2015-12-09 23 views
6

Vì vậy, tôi có một table với một cột kiểu VARCHAR (100) và tôi tự hỏi nếu có một cách để cấu hình SQL Server 2012 (T-SQL) do đó nếu một giao dịch cố gắng nộp một chuỗi các Trên 101 ký tự sau đó phải mất người đầu tiên 100.Làm thế nào tôi có thể làm cho SQL Server 2012 cắt ngắn chèn nếu chúng quá lớn?

Điều này có thể xảy ra hoặc tôi có nên thực hiện truncation ở mặt bên của sự vật không?

+0

Bạn có thể đăng câu lệnh 'INSERT' của mình không? –

+2

Tôi giả định rằng nó có thể được thực hiện DB-side, nhưng nó có thể là một ý tưởng tồi. Tốt hơn để có điều đó trong lớp ứng dụng, nếu không bạn sẽ chạy vào một lỗi trong (cho phép nói) 6 tháng và không có ý tưởng tại sao DB của bạn là ngẫu nhiên dữ liệu bị hỏng. – Rob

Trả lời

4

Thông thường, SQL Server sẽ trình bày một lỗi trên bất kỳ nỗ lực để chèn dữ liệu hơn vào một lĩnh vực hơn nó có thể giữ

String hoặc dữ liệu nhị phân sẽ được rút ngắn. Các tuyên bố này đã bị chấm dứt.

Máy chủ SQL sẽ không cho phép cắt ngắn dữ liệu im lặng chỉ vì cột quá nhỏ để chấp nhận dữ liệu. Nhưng có những cách khác mà SQL Server có thể cắt ngắn dữ liệu sắp được chèn vào một bảng sẽ không tạo ra bất kỳ dạng lỗi hoặc cảnh báo nào.

Theo mặc định, ANSI_WARNINGS được bật và một số hoạt động nhất định như tạo chỉ mục trên cột được tính toán hoặc chế độ xem được lập chỉ mục yêu cầu bật chúng. Nhưng nếu chúng bị tắt, SQL Server sẽ cắt bớt dữ liệu khi cần để làm cho nó vừa với cột. Các ANSI_WARNINGS thiết lập cho một phiên có thể được điều khiển bởi

SET ANSI_WARNINGS { ON|OFF } 

Không giống với một chèn vào một bảng, SQL Server sẽ âm thầm cắt đứt dữ liệu đang được gán cho một biến, không phụ thuộc vào trạng thái của ANSI_WARNINGS. Ví dụ:

declare @smallString varchar(5) 
declare @testint int 
set @smallString = 'This is a long string' 
set @testint = 123.456 
print @smallString 
print @testint 

Kết quả là:

This 
123 

này đôi khi có thể hiển thị bản thân theo những cách tinh tế kể từ khi đi qua một giá trị vào một thủ tục lưu trữ hoặc chức năng gán nó vào các biến tham số và sẽ lặng lẽ làm một chuyển đổi .Một phương pháp có thể giúp bảo vệ chống lại tình trạng này là đưa ra bất kỳ tham số nào sẽ được chèn trực tiếp vào bảng một kiểu dữ liệu lớn hơn cột mục tiêu sao cho SQL Server sẽ tăng lỗi hoặc có thể kiểm tra độ dài của tham số và mã tùy chỉnh để xử lý khi quá dài.

Ví dụ: nếu quy trình được lưu trữ sẽ sử dụng thông số để chèn dữ liệu vào bảng có cột là varchar (10), hãy tạo tham số varchar (15). Sau đó, nếu dữ liệu được truyền vào quá dài cho cột, dữ liệu sẽ được khôi phục và tăng lỗi cắt ngắn thay vì âm thầm cắt xén và chèn. Tất nhiên, điều đó có nguy cơ gây hiểu nhầm cho bất kỳ ai xem thông tin tiêu đề thủ tục được lưu trữ mà không hiểu những gì đã được thực hiện.

Source: Silent Truncation of SQL Server Data Inserts

0

Đề xuất của tôi sẽ làm cho bên ứng dụng chịu trách nhiệm xác thực thông tin nhập trước khi gọi bất kỳ hoạt động nào DB.

Máy chủ SQL âm thầm cắt bớt bất kỳ varchars nào bạn chỉ định là stored procedure parameters với chiều dài varchar. Vì vậy, bạn nên thử xem xét stored procedures cho các yêu cầu của bạn. Vì vậy, nó sẽ được xử lý tự động.

1

Thực hiện điều này ở cấp mã. Khi bạn đang chèn chiều dài trường trường kiểm tra hiện tại và chuỗi con nó.

string a = "string with more than 100 symbols"; 

if(a.Length > 100) 
    a = a.Substring(0, 100); 

Sau đó bạn thêm thông số làm tham số sql vào truy vấn chèn.

Cách khác là làm điều đó trong truy vấn, nhưng một lần nữa tôi không khuyên bạn làm điều đó.

INSERT INTO Table1('YourColumn') VALUES(LEFT(RTRIM(stringMoreThan100symbols), 100)) 

LEFT đang cắt chuỗi và RTRIM đang thực hiện Thao tác cắt chuỗi.

+0

Có cách nào tôi có thể nhận được độ dài của cột 'VARCHAR' để tôi không có" số ma thuật "100 không? – user5648283

+0

@ user5648283: bạn có thể tìm thấy [Kích thước cột và kiểu dữ liệu từ bechemaTable] (http://stackoverflow.com/a/17211438/3796048) –

0

Nếu bạn có các lớp thực thể (không nhất thiết phải từ EF), bạn có thể sử dụng StringLength(your field length) thuộc tính để làm điều này.

Các vấn đề liên quan