Реализация представления geometry_columns в MS SQL Server - PullRequest
1 голос
/ 02 ноября 2019

(насколько я знаю, мы используем MSSQL Server 2014)

Я никогда не видел хорошего решения для поддержки таблицы geometry_columns в MSSQL Server. https://gis.stackexchange.com/questions/71558 никогда не выясняется, и даже если и так, подход PostGIS с использованием представления (а не таблицы) является гораздо лучшим решением.

С учетом сказанного я не могукажется, выяснить, как реализовать основы того, как это может работать.

Основная схема представления geometry_columns - из PostGIS:

enter image description here

(DDL немного сложнее, но можетпредоставляется при необходимости)

MS SQL Server позволит вам запросить вашу таблицу information_schema для отображения таблиц с типом данных 'geometry':

select * 
FROM information_schema.columns 
where data_type = 'geometry'

Я представляю представление geometry_columnsможно определить с помощью чего-то подобного следующему, но я не могу понять, как получить информацию о столбцах геометрии для заполнения в запросе:

SELECT 
TABLE_CATALOG as f_table_catalog
, TABLE_SCHEMA as f_table_schema
, table_name as f_table_name 
, COLUMN_NAME as f_geometry_column

/*how to deal with these in view?
, geometry_column.STDimension() as coord_dimension
, geometry_column.STSrid as srid
, geometry_column.STGeometryType() as type
*/

FROM information_schema.columns where data_type = 'geometry'

Я завис в том, кактри оператора ST могут динамически сообщать размерность, srid и тип геометрии в представлении при попытке запроса из таблицы information_schema. Возможно, это проблема SQL больше всего на свете, но я почему-то не могу ее обойти.

Вот как выглядит таблица столбцов геометрии PostGIS:

enter image description here

Также, пожалуйста, дайте мне знать, если этот вопрос а) может быть задан по-другому, потому что это общий вопрос SQL и / или б) он принадлежит на другом форуме (GIS.SE не имелответ, так как я считаю, что это больше касается базы данных, чем пространственной / ГИС)

1 Ответ

1 голос
/ 07 ноября 2019

Исходя из небольшого прочтения, кажется, что PostGIS - как и положено выделенной ГИС-системе - немного умнее, чем SQL Server, когда дело доходит до geometry столбцов. Похоже, в PostGIS вы можете сказать, что конкретный столбец geometry будет содержать только когда-либо , скажем, POINT или LINESTRING. Вот как представление geometry_columns может быть более точным в отношении столбцов, которые оно описывает.

Я не верю, что таким способом можно легко ограничить SQL Server geometry (триггеры или ограниченияможет позволить, но будет грязно). PostGIS может иметь общий столбец geometry без дополнительных ограничений. Предположим, вы рады, что представление SQL Server geometry_columns возвращает измерение, SRID и тип на основе произвольной строки данных.

Мы можем получить метаданные столбца из представлений каталога, но я думаю, что единственный способ выполнить необходимые запросы к также получить метаданные геометрии - это динамический SQL. Это исключает взгляды и функции. Я могу сделать вам хранимую процедуру, хотя:

CREATE PROCEDURE GetGeometryColumns
AS
BEGIN
DECLARE @sql nvarchar(max);
SET @sql = ( SELECT 
STUFF((
          SELECT ' UNION ALL ' + Query
          FROM 
( SELECT
    'SELECT ''' + s.name + ''' SchemaName' 
        + ', ''' + t.name + ''' TableName' 
        + ', ''' + c.name + ''' ColumnName'
        + ', ( SELECT TOP (1) ' + c.name + '.STDimension() FROM ' + s.name + '.' + t.name + ') Dimension'
        + ', ( SELECT TOP (1) ' + c.name + '.STSrid FROM ' + s.name + '.' + t.name + ') SRID'
        + ', ( SELECT TOP (1) ' + c.name + '.STGeometryType() FROM ' + s.name + '.' + t.name + ') GeometryType'
    AS Query
FROM
    sys.schemas s
    INNER JOIN sys.tables t ON s.schema_id = t.schema_id
    INNER JOIN sys.columns c on t.object_id = c.object_id
WHERE
    system_type_id = 240
) GeometryColumn

          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 10, '')
);

EXEC ( @sql );

END

Это создает оператор SQL, который является UNION из SELECT с, по одному на каждый столбец geometry, определенный в базе данных. Обратите внимание, что я использую sys. представлений каталога, что для SQL Server лучше, чем использование INFORMATION_SCHEMA.

Каждый из отдельных SELECT s, которые эта сборка будет возвращатьимя столбца плюс метаданные из значения в первой строке (выбрано artibtarily).

Затем sproc выполняет построенные операторы и возвращает.

Для использования:

CREATE TABLE T1 (
Id int NOT NULL PRIMARY KEY
, Region geometry
)
;

CREATE TABLE T2 (
Id int NOT NULL PRIMARY KEY
, Source geometry
, Destination geometry
)
;

INSERT T1 VALUES ( 1, geometry::STGeomFromText('POLYGON((1 1, 3 3, 3 1, 1 1))', 4236)) ;

INSERT T2 VALUES ( 10
                    , geometry::STGeomFromText('POINT(1.3 2.4)', 4236) 
                    , geometry::STGeomFromText('POINT(2.6 2.5)', 4236)) ;

, затем просто

EXEC GetGeometryColumns;

, чтобы получить

SchemaName TableName ColumnName  Dimension   SRID        GeometryType
---------- --------- ----------- ----------- ----------- ----------------------
dbo        T1        Region      2           4236        Polygon
dbo        T2        Source      0           4236        Point
dbo        T2        Destination 0           4236        Point

Если вы хотите получить результаты в таблице, вы можете, например:

DECLARE @geometryColumn TABLE
(
    SchemaName sysname
    , TableName sysname
    , ColumnName sysname
    , Dimension int
    , SRID int
    , GeometryType nvarchar(100)
);

INSERT @geometryColumn EXEC GetGeometryColumns

SELECT * FROM @geometryColumn

Мне было бы интересно узнать, сможет ли кто-нибудь применить необходимую логику в фактическую VIEW ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...