Làm cách nào để trả về null từ thẻ XML trống trong máy chủ SQL chỉ bằng Xpath?


8

Tôi có một ứng dụng lưu trữ các điểm dữ liệu do người dùng xác định khác nhau về một bản ghi trong một cột XML. Tôi không kiểm soát được cách thức chúng được lưu trữ hoặc cập nhật.

Khi tôi truy vấn một cột, nó có thể trả về 1 trong 3 giá trị:

  1. Giá trị
  2. Vô giá trị
  3. Một chuỗi rỗng

Câu hỏi $ 64 Tôi muốn trả về các chuỗi trống đó dưới dạng null bằng xpath.

Tôi đã tìm thấy rất nhiều câu trả lời về việc trả lại null dưới dạng sting trống nhưng không có gì theo cách này.

Họ kết thúc theo cách đó khi ai đó đã xóa giá trị và thay vì xóa thẻ, nó sẽ xóa nó thành một <value />thẻ. Các null xảy ra khi giá trị chưa bao giờ được đặt. Họ chưa bao gồm xsi: nil.

Tôi đã thực hiện nó với một tuyên bố trường hợp:

    select
    so.SalesOrderId,
    Case
        when sopc.value('(Value)[1]','smalldatetime') IS null then Null
        when sopc.value('(Value)[1]','smalldatetime') ='' then Null
        Else sopc.value('(Value)[1]','smalldatetime')
    End as sopc
    From
    SalesOrders so
    Outer apply so.CustomColumns.nodes('/CustomColumnsCollection/CustomColumn[Name="ProjCompleted"]') sopc(sopc)

nhưng điều này cảm thấy không hiệu quả và đây không phải là cột duy nhất nên nó làm cho mã dài hơn và khó bảo trì hơn.

Chỉnh sửa để bao gồm dữ liệu mẫu

SalesOrderId    CustomColumns
SO 1            "<CustomColumnsCollection>
                   <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value />
                   </CustomColumn>
                 </CustomColumnsCollection>"
SO 2           "<CustomColumnsCollection>
                  <CustomColumn>
                     <Name>ProjCompleted</Name>
                     <DataType>1</DataType>
                     <Value>'2017-11-21'</Value>
                  </CustomColumn>
                </CustomColumnsCollection>"
SO 3           "<CustomColumnsCollection>
                </CustomColumnsCollection>"

**Output**
Current      Desired
''           null
2017-11-21   2017-11-21
null         null

Cảm ơn trước.


Cảm ơn Scott - như bạn có thể thấy đó là câu hỏi đầu tiên của tôi, có định dạng ưa thích không?
TimNewman

Chỉ cần cập nhật câu hỏi của bạn với một khối mã (tương tự như mã bạn đã đăng) có mẫu XML và bao gồm một khối mã khác của kết quả dự kiến. Xem Cách tạo một ví dụ tối thiểu, đầy đủ và có thể kiểm chứng
Scott Hodgin

Cảm ơn - Tôi đã chấp nhận một câu trả lời nhưng tôi vẫn sẽ chỉnh sửa câu hỏi để làm cho nó hữu ích cho bất kỳ ai khác tìm thấy câu hỏi này.
TimNewman

Câu trả lời:


11

Chỉ định text()nút trong Valuephần tử. Nút đó bị thiếu khi bạn có một thẻ trống.

Thử cái này:

declare @X xml;
set @X = '<Value/>';

select @X.value('(Value/text())[1]', 'smalldatetime'),
       @X.value('(Value/text())[1]', 'varchar(max)'),
       @X.value('(Value/text())[1]', 'int'),
       @X.value('(Value)[1]', 'smalldatetime'),
       @X.value('(Value)[1]', 'varchar(max)'),
       @X.value('(Value)[1]', 'int');

Kết quả:

------------------- ---------- ----------- ----------------------- ---------- -----------
NULL                NULL       NULL        1900-01-01 00:00:00                0

Nói chung là luôn luôn chỉ định text()nút. Kế hoạch truy vấn đơn giản và hiệu quả hơn.

nhập mô tả hình ảnh ở đây

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.