2011-08-25 39 views
5

Chúng tôi có một SQL thực hiện chức năng CAST (tới FLOAT) trên ColumnA. SQL có một bộ lọc mà cuối cùng sẽ gián tiếp lọc ra những hàng có giá trị không số trong ColumnA. Tuy nhiên, vì những gì tôi tin là do chạy các phần của SQL song song, tôi tin rằng CAST thậm chí được áp dụng cho các hàng được lọc ra và điều này làm cho SQL thất bại về "không thể truyền giá trị như float ... "không thể truyền giá trị dưới dạng float

tôi biết rằng nếu tôi chạy với một proc bằng cách thêm các gợi ý truy vấn

OPTION (MAXDOP 1) 

rằng SQL chạy như mong đợi. Tôi nghi ngờ rằng chạy trên 1 proc buộc các bộ lọc được áp dụng để loại bỏ hàng với các giá trị số không trong cộtA để các giá trị của nó thành công. Tôi cũng thấy rằng việc sử dụng các gợi ý truy vấn

OPTION (FORCE ORDER) 

sửa chữa vấn đề này, tôi giả định becausethis quá đảm bảo rằng các bộ lọc được áp dụng đầu tiên và tôi có được hiệu suất truy vấn tốt hơn nhiều mà một chạy trên một xi lanh.

Tôi nghiêng nghiêng về phía sau để khắc phục sự cố bằng tùy chọn thứ 2. Nếu tôi có bất kỳ quan niệm sai lầm về những gì đang xảy ra ở đây hoặc nếu ai đó muốn giải thích về hiểu chung của tôi hoặc đưa ra một đề nghị, tôi sẽ đánh giá cao nó.

Tôi đang chạy trên

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1720.0 (X64) ngày 12 Tháng 6 năm 2010 01:34:59 Bản quyền (c) Tập đoàn Microsoft Enterprise Edition (64 bit) trên Windows NT 5.2 (Build 3790: Service Pack 2)

một suy nghĩ:

có vẻ như rằng nó sẽ được tốt đẹp là T-SQL có các chức năng sau để kiểm tra xem một chuỗi có thể beve rted đến một datatype cụ thể.

IsFloat IsNumeric IsInteger vv

Tôi thực sự cảm thấy khó chịu ở bao nhiêu cột của tất cả các loại dữ liệu mà tôi tìm thấy trong cơ sở dữ liệu của chúng tôi được xác định là varchar (255). Tôi đoán giải pháp là "không làm điều đó!"

+2

Bạn có thể hiển thị SQL không? – MatBailie

+1

Bạn đang yêu cầu chúng tôi giúp sửa xe của bạn mà không thực sự nhìn thấy chiếc xe. Cho chúng tôi xem xe. – JNK

+0

T-SQL có IsNumeric – MatBailie

Trả lời

4

Về sau suy nghĩ của bạn.

Dường như có vẻ tốt đẹp là T-SQL có các chức năng sau đây để kiểm tra xem chuỗi có thể được chuyển đổi thành một kiểu dữ liệu cụ thể hay không.

SQL Server 2012 giới thiệu TRY_CONVERT cho nhu cầu này. Vì vậy, truy vấn sau đây sẽ trả lại NULL thay vì lỗi.

SELECT TRY_CONVERT (FLOAT, 'Fish') 

Không có đảm bảo ngay cả với kế hoạch nối tiếp rằng mệnh đề WHERE sẽ xảy ra trước khi SELECT được đánh giá. Theo giải thích in this blog post từ SQL Server 2005 trở đi, điều này có nhiều khả năng xảy ra hơn trong các phiên bản trước. Các Behavior Changes to Database Engine Features in SQL Server 2005 cụ thể gọi này như sau.

SQL Server 2005 đôi khi đánh giá biểu thức trong các truy vấn sớm hơn khi họ được đánh giá trong SQL Server 2000. Hành vi này cung cấp lợi ích quan trọng sau đây:

  • Khả năng để phù hợp với các chỉ số trên các cột tính toán để biểu thức trong truy vấn giống với biểu thức cột được tính toán.
  • Ngăn chặn tính toán dư thừa kết quả biểu thức.

Thảo luận nhiều hơn về hành vi này là trong một bài đăng blog tốt bởi Craig Freedman Conversion and Arithmetic Errors.

Trên các phiên bản trước năm 2012 và TRY_CONVERT bạn cần phải quấn CAST AS FLOAT trong tuyên bố CASE. ví dụ.

SELECT CASE WHEN ISNUMERIC(Col)=1 THEN CAST(Col AS FLOAT) END AS Col 
    FROM Table 
    WHERE ISNUMERIC(Col)=1 

này vẫn chưa hoàn toàn được bảo đảm để ngăn cản bạn nhận được lỗi như ISNUMERIC bản thân chỉ cần kiểm tra rằng giá trị sẽ đúc một trong các kiểu dữ liệu số chứ không phải là đặc biệt nổi An example of an input that would fail is '.'

CASE được ghi chép lại để chủ yếu ngắn mạch trong sách trực tuyến (some exceptions are discussed here)

Bạn cũng có thể tìm thấy thảo luận thêm/khiếu nại về vấn đề này trong mục connect SQL Server should not raise illogical errorsgood explanation of a similar issue bởi SQLKiwi

012.351.
1

Tôi tin rằng bạn là chính xác. Hàm CONVERT() đang được áp dụng trước khi các vị từ "lọc gián tiếp" các hàng.

Để tránh ngoại lệ, bạn đúng, một cách tiếp cận là cố gắng đạt được một số lượng kiểm soát đối với thứ tự các hoạt động trong kế hoạch thực hiện. Nếu gợi ý phát biểu đang làm việc cho bạn, thì bạn có thể đi với điều đó. (Cá nhân, gợi ý là phương sách cuối cùng cho tôi.)

Lưu ý rằng SQL Server có chức năng IsNumeric.

Hàm IsNumeric có phần không đủ, theo nghĩa là có một số giá trị sẽ "vượt qua" thử nghiệm IsNumeric nhưng sẽ tăng ngoại lệ khi chúng được chuyển thành kiểu dữ liệu số.

Cá nhân, tôi sẽ có xu hướng đi với cách tiếp cận này:

select convert(float,case when isnumeric(t.foo)=1 then t.foo else null end) 

hơn mức tuyên bố gợi ý.

Hoặc, tôi sẽ chỉ định các vị từ khác sẽ "lọc" ra các giá trị không được chuyển đổi.

select convert(float,case when t.fi in ('fo','fum') then t.foo else null end) 
Các vấn đề liên quan