Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SqlGeometry युक्त डेटाटेबल संग्रहीत कार्यविधि निष्पादन को विफल कर रहा है... क्यों?

आपके प्रश्न पर एक संक्षिप्त टिप्पणी करने के बाद से, मुझे विकल्पों के साथ पूरी तरह से खेलने का मौका मिला है। ऐसा प्रतीत होता है कि वर्तमान में (.NET 4.6 और SQL 2014 की कोशिश कर भी) आप SqlGeography सेट नहीं कर सकते या SqlGeometry typeof() . के रूप में DataTable . के लिए कॉलम को परिभाषित करते समय पैरामीटर . पूर्ण स्पष्टता के लिए, आप इसे .NET में कर सकते हैं और यहां तक ​​कि इसे पॉप्युलेट भी कर सकते हैं, लेकिन फिर आप उस तालिका को टीवीपी के रूप में संग्रहीत प्रक्रिया में पास नहीं कर सकते।

दो विकल्प हैं।

विकल्प 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 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 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 . का उपयोग कर रहे हैं मैं आपको लचीलापन देने के लिए इसे दूसरा पैरामीटर बनाने का सुझाव दूंगा।

इसके अतिरिक्त, यदि प्रदर्शन महत्वपूर्ण है, तो आप WKB का बेहतर उपयोग करते हुए पाएंगे। मेरे परीक्षणों में पाया गया कि डब्ल्यूकेटी ने डब्लूकेटी को 45% से 65% समय में पूरा किया। यह आपके डेटा की जटिलता और आपके सेटअप के अनुसार अलग-अलग होगा।

पैरामीटर का UdtTypeName . निर्दिष्ट करने पर आपको मिली जानकारी चूंकि "ज्यामिति" / "भूगोल" सही है जब आपकी संग्रहीत प्रक्रिया में [ज्यामिति] या [भूगोल] प्रकार का पैरामीटर होता है। यह टीवीपी पर लागू नहीं होता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. गतिरोध के कारण SqlException को कैसे पकड़ें?

  2. दिनांक में एक दिन जोड़ने के लिए दिनांक जोड़ें का उपयोग करते हुए SQL सर्वर 2005

  3. SQL सर्वर में केवल वर्ष पर दिनांक समय क्वेरी

  4. WHERE क्लॉज उन मानों का उपयोग कर रहा है जो NULL हो सकते हैं

  5. TSQL md5 हैश C# .NET md5 से अलग है