Межмашинная несогласованность в преобразовании WKT для пространственных типов SQL

Я наблюдаю непоследовательное поведение на разных машинах при преобразовании пространственных типов в общеизвестный текст (WKT) в SQL Server 2008. Похоже, что данные сохраняются одинаково, но обратное преобразование в WKT действует по-разному в зависимости от машины!

Вот что я собрал, чтобы точно определить проблему:

SET NOCOUNT ON;

DECLARE @TestTable TABLE (TestPoint GEOGRAPHY);
INSERT INTO @TestTable(TestPoint)  VALUES (geography::STGeomFromText('POINT(-124.957140999999993 39.326679)',4326));

DECLARE @PointAsText NVARCHAR(max);
SELECT @PointAsText = TestPoint.STAsText() from @TestTable;
PRINT @PointAsText;

DECLARE @PointAsBinary BINARY(22);
SELECT  @PointAsBinary = CAST(TestPoint AS BINARY(22)) from @TestTable;
print @PointAsBinary;

print @@version;

На разных машинах, которые у меня есть, я вижу два разных результата:

POINT (-124.95714099999999 39.326679)
0xE6100000010C1EA5129ED0A94340492A53CC413D5FC0
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64) 54:03
Авторское право (c) Microsoft Corporation
Developer Edition (64-разрядная версия) для Windows NT 6.1 (сборка 7601: пакет обновления 1)

or

POINT (-124.957141 39.326679)
0xE6100000010C1EA5129ED0A94340492A53CC413D5FC0
Microsoft SQL Server 2008 R2 (окончательная первоначальная версия) — 10.50.1600.1 (Intel X86) 1 апр. :53:02
Авторское право (c) Microsoft Corporation
Developer Edition для Windows NT 6.0 (сборка 6002: пакет обновления 2) (гипервизор)

Другой тестовый пример показывает, что машина X64 с 2008 R2 (RTM) дает -124,95714099999999. Итак, определенно указывает на x86 против x64.

Я, по крайней мере, немного знаком с отсутствием точности с плавающей запятой, но я не знал, что это зависит от архитектуры. Кажется, что работа с пространственным хранилищем SQL включает в себя данные, проходящие через подобные преобразования WKT. Я не вижу более подходящей стратегии для работы с этими данными?


person Johnny Kauffman    schedule 10.02.2012    source источник


Ответы (2)


Я никогда раньше не видел такого поведения... Я тоже ожидал, что преобразование будет полностью детерминированным при работе с той же версией/ОС. Что бы это ни стоило, я могу подтвердить, что я получаю правильный ожидаемый первый результат POINT (-124.95714099999999 39.326679) как для SQL Server 2008 R2 (x64 10.50.2500), так и для SQL Azure (11.0.1831).

Могу ли я попросить вас проверить, что вы также получаете те же результаты от этих машин, когда вы:

ВЫБЕРИТЕ @PointAsText;

скорее, чем:

ПЕЧАТЬ @PointAsText;

Я признаю, что это немного цепляется за соломинку, но я просто пытаюсь предложить что-то, чтобы изолировать, что это определенно значение @PointAsText было округлено, а не какое-то забавное форматирование, которое может применить PRINT...

person Alastair Aitchison    schedule 10.02.2012
comment
О, фасоль!! Извините, я ошибся, скопировав вывод с сервера SQL. Одна из систем x86, а другая x64. Я получу правильные BLOB-объекты @@version, когда снова получу доступ к машинам. - person Johnny Kauffman; 12.02.2012
comment
Хорошо, я обновил вопрос, чтобы исправить эту ошибку копирования и вставки. Кроме того, я быстро проверил SELECT и PRINT, и разницы нет. - person Johnny Kauffman; 13.02.2012

Пару недель не было никакой активности, поэтому я отвечу, что знаю.

Мое лучшее понимание этого состоит в том, что использования общеизвестного текста (WKT) просто нужно избегать. Я не уверен насчет варианта Well-Known-Binary (WKB).

Чтобы быть уверенным, что вы не потеряете точность/детализацию при использовании SqlGeography в своей базе данных, вы можете использовать класс SqlGeography в своем промежуточном программном обеспечении или приложении. Класс бинарно сериализуем, чтобы помочь в этом отношении.

Оставив безопасный класс SqlGeography через Well-Known-Text (WKT), точность начнет исчезать. Предпочтительно делать это только при показе пользователю или при необходимости взаимодействия с платформами, отличными от .NET (например, с использованием веб-службы).

person Johnny Kauffman    schedule 21.02.2012