Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Datatable yang berisi SqlGeometry menyebabkan eksekusi prosedur tersimpan gagal... Mengapa?

Sejak membuat komentar singkat tentang pertanyaan Anda, saya memiliki kesempatan untuk sepenuhnya bermain-main dengan opsi. Tampaknya saat ini (bahkan mencoba .NET 4.6 dan SQL 2014) Anda tidak dapat mengatur SqlGeography ATAU SqlGeometry sebagai typeof() parameter saat mendefinisikan kolom untuk DataTable . Untuk kejelasan mutlak, Anda dapat melakukannya di .NET dan bahkan mengisinya, tetapi Anda kemudian tidak dapat meneruskan tabel itu sebagai TVP ke Prosedur Tersimpan.

Ada dua opsi.

Opsi 1. Teruskan nilai dalam format WKT.

Tentukan tipe tabel Anda sebagai berikut.

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

Kemudian tentukan Prosedur Tersimpan Anda sebagai berikut.

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

Tentukan .NET DataTable Anda sebagai berikut:

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

Isi sebagai berikut:

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

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

Opsi 2. Berikan nilai dalam format WKB.

Tentukan tipe tabel Anda sebagai berikut.

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

Kemudian tentukan Prosedur Tersimpan Anda sebagai berikut.

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

Tentukan .NET DataTable Anda sebagai berikut:

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

Isi sebagai berikut:

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

Catatan:

Tentukan SqlParameter Anda sebagai berikut:

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

Saya telah meninggalkan SRID 4326 dari pekerjaan geografi saya. Anda dapat mengubahnya menjadi apa pun yang Anda inginkan - dan memang jika Anda menggunakan Geography Saya sarankan menjadikannya sebagai parameter kedua untuk memberi Anda fleksibilitas.

Selain itu, jika kinerja sangat penting, Anda akan menemukan penggunaan WKB lebih baik. Tes saya menemukan bahwa WKB selesai dalam 45% hingga 65% dari waktu yang dibutuhkan WKT. Ini akan bervariasi tergantung pada kerumitan data Anda dan oleh penyiapan Anda.

Informasi yang Anda temukan saat menentukan UdtTypeName parameter sebagai "Geometri" / "Geografi" benar ketika Prosedur Tersimpan Anda memiliki parameter tipe [Geometri] atau [Geografi]. Ini tidak berlaku untuk TVP.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jalankan prosedur tersimpan menggunakan kerangka entitas

  2. Buat Server Tertaut di SQL Server (Contoh T-SQL)

  3. Menangkap beberapa pesan kesalahan dari satu pernyataan di dalam TRY CATCH

  4. Bagaimana cara memperbaiki konflik pemeriksaan dalam kueri SQL Server?

  5. MS SQL membandingkan tanggal?