2011-08-17 26 views
7

Tôi có CSV tôi đang nhập vào cơ sở dữ liệu của mình. Một trong "cột" chứa dữ liệu nên là INT nhưng một số hàng có số chỉ nằm trong phạm vi BIGINT (vì chúng là dữ liệu thử nghiệm từ một trong các đối tác của chúng tôi). Chúng tôi lưu trữ INT nội bộ và không có mong muốn thay đổi.SQL - AN TOÀN xuống một cách an toàn BIGINT thành INT

Tôi muốn downcast an toàn từ BIGINT sang INT. Bởi một cách an toàn, tôi có nghĩa là không có lỗi nên được nêu ra nếu một số lượng tràn xảy ra. Nếu dàn diễn viên/chuyển đổi thành công, tôi muốn kịch bản của tôi tiếp tục. Nếu nó không thành công, tôi muốn nó ngắn mạch. Tôi dường như không thể tìm ra cú pháp thích hợp. Đây là những gì tôi đã có:

DECLARE @UserIDBigInt BIGINT = 9723021913; -- actually provided by query param 
--Setting within the INT range successfully converts 
--SET @UserIDBigInt = 5; 
DECLARE @UserID INT = CONVERT(INT, @UserIDBigInt); 
--DECLARE @UserID INT = CAST(@UserIDBigInt AS INT); 
SELECT @UserIDBigInt 
SELECT @UserID 
IF @UserID IS NOT NULL BEGIN 
    SELECT 'Handle it as reliable data' 
END 

Tôi đã nghĩ đến việc so sánh @UserIDBigInt đến phạm vi giá trị của một INT (-2^31 (-2.147.483.648) để 2^31-1 (2.147.483.647)), nhưng tôi thực sự không thích cách tiếp cận đó. Đó là dự phòng của tôi. Tôi đã hy vọng cho một số cấu trúc ngôn ngữ hoặc xây dựng trong chức năng tôi có thể sử dụng. Nếu tôi hoàn toàn phải so sánh với phạm vi hợp lệ, có ít nhất một số hằng số tích hợp (như int.MinValue của C# & int.MaxValue) không?

EDIT: Lỗi chính tả.

+0

Hiện tại không có built-in hằng số. Nếu bạn kết thúc muốn so sánh với các hằng số, câu hỏi đó đã được trả lời trước đây: http://stackoverflow.com/questions/7092774/max-value-represented-by-bigint/7092844#7092844 –

+0

Tại sao không chỉ gán giá trị cho một biến INT trong thủ tục lưu sẵn của bạn, gán giá trị đó ngược lại cho biến BIGINT, sau đó so sánh giá trị BIGINT với giá trị ban đầu (cũng là một BIGINT).Nếu có tràn sẽ gán cho một INT, các giá trị sẽ không khớp. –

+0

@Conspicuous Compiler, tôi không bao giờ nói rằng tôi đang sử dụng một thủ tục được lưu trữ. Bất kể, làm như vậy làm tăng một biểu thức chuyển đổi lỗi tràn số học thành kiểu dữ liệu int. " như được ám chỉ trong câu hỏi ban đầu của tôi. –

Trả lời

0

Bạn cũng có thể chuyển đổi giá trị thành chuỗi, cắt nó thành độ dài và chuyển thành int. không phải là cách tốt nhất, nhưng một cách an toàn dễ dàng cho chắc chắn

1

Tôi không chắc chắn này là câu trả lời tốt nhất nhưng nó là một trong tôi đã đưa ra trước đó một mình. Có thể bắt ngoại lệ/lỗi và thực hiện tiếp tục một cách duyên dáng.

Ví dụ:

DECLARE @UserIDBigInt BIGINT = 9723021913; 
DECLARE @UserID INT; 
BEGIN TRY 
    SET @UserID = @UserIDBigInt; 
END TRY BEGIN CATCH 
END CATCH 

IF @UserID IS NULL BEGIN 
    SELECT 'Handle it as unreliable data' 
    RETURN 
END 

SELECT 'Handle it as reliable data' 
3

Truyền của bạn bigint để varbinary, sau đó lưu trữ nửa dưới để @UserID và kiểm tra nửa trên:

  • nếu nửa trên là tất cả của 0 và nửa dưới đại diện cho giá trị không âm, @UserID sau đó chứa giá trị int chính xác;

  • nếu nửa trên là tất cả 1 và @UserID là số âm, tất cả đều đúng;

  • nếu không có lỗi tràn số học.

Dưới đây là một thực hiện:

DECLARE @UserIDBigInt BIGINT = 9723021913; 
DECLARE @UserID INT, @HighInt INT; 

WITH v AS (SELECT CAST(@UserIDBigInt AS varbinary) AS bin) 
SELECT 
    @HighInt = SUBSTRING(bin, 1, 4), 
    @UserID = SUBSTRING(bin, 5, 4) 
FROM v; 

IF (@HighInt = 0 AND @UserID >= 0 OR @HighInt = -1 AND @UserID < 0) BEGIN 
    SELECT 'Handle it as reliable data' 
END