sql >> データベース >  >> RDS >> Sqlserver

SqlGeometry を含むデータテーブルが原因で、ストアド プロシージャの実行が失敗します...なぜですか?

    あなたの質問に短いコメントをして以来、私はオプションを完全にいじる機会がありました.現在 (.NET 4.6 と SQL 2014 を試しても) SqlGeography を設定できないようです または SqlGeometry typeof() として DataTable の列を定義するときのパラメーター .完全に明確にするために、.NET でそれを行い、データを入力することもできますが、そのテーブルを TVP としてストアド プロシージャに渡すことはできません。

    2 つのオプションがあります。

    オプション 1. WKT 形式で値を渡します。

    次のようにテーブル タイプを定義します。

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

    次に、ストアド プロシージャを次のように定義します。

    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
      

    .NET DataTable を次のように定義します:

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

    次のように設定します:

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

    オプション 2. WKB 形式で値を渡します。

    次のようにテーブル タイプを定義します。

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

    次に、ストアド プロシージャを次のように定義します。

    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
      

    .NET DataTable を次のように定義します:

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

    次のように設定します:

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

    注:

    次のように SqlParameter を定義します:

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

    私は地理学の仕事から 4326 の SRID を残しました。これは好きなように変更できます - 実際に Geography を使用している場合 柔軟性を持たせるために、2 番目のパラメーターにすることをお勧めします。

    さらに、パフォーマンスが重要な場合は、WKB を使用する方が優れていることがわかります。私のテストでは、WKB は WKT にかかった時間の 45% から 65% で完了したことがわかりました。これは、データの複雑さと設定によって異なります。

    パラメータの UdtTypeName の指定に関する情報 as "Geometry" / "Geography" は、ストアド プロシージャに [Geometry] または [Geography] 型のパラメーターがある場合に適切です。 TVP には適用されません。



    1. SQLAlchemyORMを使用した一括挿入

    2. 2つのクエリの合計

    3. ハッシュIDの非バイナリに対するMySQLバイナリ

    4. Jenkinsを使用したPostgreSQLの毎日のタスクの自動化