sql >> Database teknologi >  >> RDS >> Sqlserver

Datatabel, der indeholder SqlGeometry, får udførelse af lagret procedure til at mislykkes... Hvorfor?

Siden jeg kom med en kort kommentar til dit spørgsmål, har jeg haft mulighed for at lege med mulighederne. Det ser ud til, at du på nuværende tidspunkt (selv ved at prøve .NET 4.6 og SQL 2014) ikke kan indstille SqlGeography ELLER SqlGeometry som typeof() parameter, når du definerer en kolonne for en DataTable . For absolut klarhed kan du gøre det i .NET og endda udfylde det, men du kan derefter ikke videregive den tabel som en TVP til en lagret procedure.

Der er to muligheder.

Mulighed 1. Send værdien i WKT-format.

Definer din tabeltype som følger.

CREATE TYPE [dbo].[WKT_Example] AS TABLE
(
    [geom] [varchar](max) NOT NULL
)

Definer derefter din Stored Procedure som følger.

CREATE PROCEDURE [dbo].[BulkInsertFromWKT]

    @rows [dbo].[WKT_Example] READONLY

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    INSERT INTO [dbo].[Table1]
        ([SpatialData])
    SELECT
        geometry::STGeomFromText(R.[SpatialData], 4326)
    FROM
        @rows R;

END

Definer din .NET DataTable som følger:

DataTable wktTable = new DataTable();
wktTable.Columns.Add("SpatialData", typeof(string));

Udfyld det som følger:

for (int j = 0; j < geometryCollection.Count; j++)
{
    System.Data.SqlTypes.SqlString wkt = geometryCollection[j].STAsText().ToSqlString();

    wktTable.Rows.Add(wkt.ToString());
}

Mulighed 2. Send værdien i WKB-format.

Definer din tabeltype som følger.

CREATE TYPE [dbo].[WKB_Example] AS TABLE
(
    [geom] [varbinary](max) NOT NULL
)

Definer derefter din Stored Procedure som følger.

CREATE PROCEDURE [dbo].[BulkInsertFromWKB]

    @rows [dbo].[WKB_Example] READONLY

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    INSERT INTO [dbo].[Table1]
        ([SpatialData])
    SELECT
        geometry::STGeomFromWKB(R.[SpatialData], 4326)
    FROM
        @rows R;

END

Definer din .NET DataTable som følger:

DataTable wkbTable = new DataTable();
wkbTable.Columns.Add("SpatialData", typeof(System.Data.SqlTypes.SqlBytes));

Udfyld det som følger:

for (int j = 0; j < geometryCollection.Count; j++)
{
    wkbTable.Rows.Add(geographyCollection[j].STAsBinary());
}

Bemærkninger:

Definer din SqlParameter som følger:

SqlParameter p = new SqlParameter("@rows", SqlDbType.Structured);
p.TypeName = "WKB_Example"; // The name of your table type
p.Value = wkbTable;

Jeg har efterladt et SRID på 4326 fra mit geografiarbejde. Du kan ændre dette til hvad du ønsker - og faktisk hvis du bruger Geography Jeg vil foreslå at gøre det til en anden parameter for at give dig fleksibilitet.

Derudover, hvis ydeevnen er kritisk, vil du opleve at bruge WKB bedre. Mine test viste, at WKB gennemførte i 45% til 65% af den tid, WKT tog. Dette vil variere afhængigt af kompleksiteten af ​​dine data og din opsætning.

De oplysninger, du fandt ved angivelse af parameterens UdtTypeName da "Geometry" / "Geography" er korrekt, når din Stored Procedure har en parameter af typen [Geometry] eller [Geography]. Det gælder ikke TVP'er.



  1. Brug af uendelig scroll med en MySQL-database

  2. Vis SQLite-data i RecyclerView

  3. Referencealias (beregnet i SELECT) i WHERE-sætning

  4. PDO henter en kolonne fra tabel til 1-dimensionel array