Использование формы PHP для вставки геометрии из WKT и SRID в SQL Server 2017

У меня есть форма PHP 7.3, которая запрашивает у пользователя имя, WKT и SRID. Я хотел бы загрузить WKT и SRID в SQL Server 2017, чтобы он создавал геометрический объект в Upload_WKT_Test с помощью STGeomFromText:

<?php
    if ($_SERVER['REQUEST_METHOD']=="POST") {
        $wkt = $_POST['wkt'];
        $srid = $_POST['srid'];
        $name = $_POST['name'];
        try {
            $wktQuoted = $pdo->quote ($wkt);
            //$wktQuoted = "'$wkt'";
            $sql = "INSERT INTO Upload_WKT_Test (Name, GeomCol1) VALUES (:name, :wktGeom)";
            $wktGeom1 = "geometry::STGeomFromText(";
            $wktGeom = $wktGeom1."".$wktQuoted.", ".$srid.")";
            //echo $wktGeom."<br><br>".$name."<br><br>";
            $stmnt = $pdo->prepare($sql);
            $theData = [':name'=>$name, ':wktGeom'=>$wktGeom];
            $stmnt->execute($theData);
        } catch(PDOException $e) {
            echo "Error: ".$e->getMessage();
        }
    } else {
        $wkt="";
        $alignment="";
        $srid="";
    }
?>

Мой init.php:

<?php
    ob_start();
    session_start();
     try {
        $pdo = new PDO( "sqlsrv:Server=localhost\SQLEXPRESS;Database=devdb", "", "");
        $pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        $pdo->setAttribute( PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC );
        //$pdo->setAttribute( PDO::ATTR_EMULATE_PREPARES, true );
    }

    catch( PDOException $e ) {  
        //die( "Error connecting to SQL Server" );
        //die(print_r($stmnt->errorInfo(), true));
        echo "Error: ".$e->getMessage();
    }  
    $root_directory = "testwkt";
    $from_email = "[email protected]";
    $reply_email = "[email protected]";
    include "php_functions.php";
?>

Я понимаю, что предпочтительный метод приема пользовательского ввода через формы - использовать параметризованный запрос для предотвращения SQL-инъекции. Я считаю, что источник сообщения об ошибке связан с тем, что кавычки вокруг WKT не попадают в оператор INSERT INTO. Можно ли заключить текстовые значения из формы ввода кавычками (WKT) и использовать их для создания геометрического объекта?

Пример WKT, введенный в форму POINT(100 10)

Пример SRID 0

Пример имени Test

Геометрия от WKT (кавычки обязательны):

geometry::STPointFromText('POINT (100 10)', 0)

Полученное сообщение об ошибке:

SQLSTATE[42000]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]
A .NET Framework error occurred during execution of user-defined routine or
aggregate "geometry": System.FormatException: 24114: The label
geometry::STGeomFrom in the input well-known text (WKT) is not valid. 
Valid labels are POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING,
MULTIPOLYGON, GEOMETRYCOLLECTION, CIRCULARSTRING, COMPOUNDCURVE, 
CURVEPOLYGON and FULLGLOBE (geography Data Type only). 
System.FormatException: at
Microsoft.SqlServer.Types.OpenGisTypes.ParseLabel(String input) at
Microsoft.SqlServer.Types.WellKnownTextReader.ParseTaggedText(OpenGisType type) at 
Microsoft.SqlServer.Types.WellKnownTextReader.Read(OpenGisType type, Int32 srid) at 
Microsoft.SqlServer.Types.SqlGeometry.GeometryFromText(OpenGisType type, SqlChars text, Int32 srid) at
Microsoft.SqlServer.Types.SqlGeometry.Parse(SqlString s) .

Загрузить_WKT_Test table:

CREATE TABLE dbo.Upload_WKT_Test
    ( id int IDENTITY (1,1),
    Name varchar(50),
    GeomCol1 geometry );
GO

WKT - Well Known Text - способ представления геометрического объекта (например, точки, линии, многоугольника) в текстовом формате. Дополнительная информация здесь.

SRID - идентификатор системы пространственной привязки - целое число, представляющее систему координат. Дополнительная информация здесь.

Дополнительную информацию о работе с экземплярами геометрии в SQL Server и базе данных SQL Azure можно найти по адресу здесь.

Дополнительная информация о STGeomFromText


person Rayner    schedule 10.12.2019    source источник
comment
Вы можете попробовать использовать $sql = "INSERT INTO Upload_WKT_Test (Name, GeomCol1) VALUES (:name, geometry::STGeomFromText(:wktGeom, :sridGeom)"; и $theData = [':name'=>$name, ':wktGeom'=>$wktQuoted, ':sridGeom'=>$srid];   -  person Zhorov    schedule 10.12.2019
comment
И я думаю, что использовать $wktQuoted вместо $wkt не нужно.   -  person Zhorov    schedule 10.12.2019


Ответы (1)


Вы должны включить geometry::STGeomFromText в свой T-SQL оператор и связать значение для параметра $wkt без использования PDO::quote:

<?php
    if ($_SERVER['REQUEST_METHOD']=="POST") {
        $wkt = $_POST['wkt'];
        $srid = $_POST['srid'];
        $name = $_POST['name'];
        try {
            $sql = "
               INSERT INTO Upload_WKT_Test (Name, GeomCol1) 
               VALUES (:name, geometry::STGeomFromText(:wkt, :srid))";
            $stmnt = $pdo->prepare($sql);
            $theData = [':name'=>$name, ':wkt'=>$wkt, ':srid'=>$srid];
            $stmnt->execute($theData);
        } catch(PDOException $e) {
            echo "Error: ".$e->getMessage();
        }
    } else {
        $wkt="";
        $alignment="";
        $srid="";
    }
?>
person Zhorov    schedule 10.12.2019
comment
Если вы когда-нибудь будете в Секешфехервар, Венгрия, позвольте мне купить вам пива. Ваше решение сработало отлично. Спасибо. - person Rayner; 10.12.2019
comment
@Rayner Рад помочь. - person Zhorov; 10.12.2019