-1

ADO.NET を使用して SQL Server 2012 データベースに接続するプロジェクトを C# で作成しています。私のデータベース(とりわけ)には2つの列があります。最初の列はポイントの緯度を表し、2 番目の列は経度を表します。マップ上の 2 つの長方形が互いに交差しているかどうかを確認する手順を使用します。列の応答は、0 または 1 のいずれかである 1 つの値を返します。編集: この例では、数値のみで実行します。後で変数を追加する予定です。SQL クエリで実行すると、手順は正常に機能します。しかし、ADO.netを使用して実行するとエラーが発生します

SQLクエリ手順は次のとおりです。

DECLARE @g geography;
DECLARE @h geography;
DECLARE @s geography;

SET @g = geography::STGeomFromText('POLYGON((39.692 23.483, 23.483 39.671, 24.095 39.493, 23.466 39.800,39.692 23.483))', 4326);

SET @h = geography::STGeomFromText('POLYGON((39.800096 23.296509, 39.628961 23.128967,39.43195 23.510742 ,39.7093 23.859558,39.800096 23.296509))', 4326);
SET @h =@h.MakeValid();
SET @g = @g.MakeValid();
SELECT @g.STIntersects(@h) as reply

/*============================================== ================================================== ============

//------------------------ AS ADO.NET の手順は: ----------------- --------------

SqlDataReader rdr = null;
SqlConnection conn = new SqlConnection("Data Source=AGIS-PC;Initial Catalog=ship_maps;Integrated Security=True");// create a connection object


String commandString = @"DECLARE @g geography;
DECLARE @h geography;
DECLARE @s geography;
SET @h =@h.MakeValid();
SET @g = @g.MakeValid();
SET @g = geography::STGeomFromText('POLYGON((39.692 23.483, 23.483 39.671, 24.095 39.493, 23.466 39.800,39.692 23.483))', 4326);
SET @h = geography::STGeomFromText('POLYGON((39.800096 23.296509, 39.628961 23.128967,39.43195 23.510742 ,39.7093 23.859558,39.800096 23.296509))', 4326);
SET @h =@h.MakeValid();
SET @g = @g.MakeValid();
SELECT @g.STIntersects(@h) as reply";
SqlCommand cmd = new SqlCommand(commandString, conn);

try
{
// open the connection
conn.Open();
// 1. get an instance of the SqlDataReader
rdr = cmd.ExecuteReader();

while (rdr.Read())
{
// get the results of each column
string vessel_name = (string)rdr["reply"];
TextBox1.Text += " " + vessel_name;

// .....
}//while
}
finally
{
//...........
}

//================================================ ========= 彼のエラーは makevalid() によるものだと思います。sql の最初のクエリで同様のエラーが発生したため、 makevalid() を挿入すると機能しました。edit : rdr = cmd.ExecuteReader(); で発生します。

Stack Trace:


[SqlException (0x80131904): A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
System.ArgumentException: 24200: The specified input does not represent a valid geography instance. Use MakeValid to convert the instance to a valid instance. Note that MakeValid may cause the points of a spatial instance to shift slightly.
System.ArgumentException:
at Microsoft.SqlServer.Types.SqlGeography..ctor(GeoData g, Int32 srid)
at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid)
.
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
Microsoft.SqlServer.Types.GLArgumentException: 24205: The specified input does not represent a valid geography instance because it exceeds a single hemisphere. Each geography instance must fit inside a single hemisphere. A common reason for this error is that a polygon has the wrong ring orientation. To create a larger than hemisphere geography instance, upgrade the version of SQL Server and change the database compatibility level to at least 110.
Microsoft.SqlServer.Types.GLArgumentException:
at Microsoft.SqlServer.Types.GLNativeMethods.GeodeticIsValid(GeoData& g, Double eccentricity, Boolean forceKatmai)
at Microsoft.SqlServer.Types.SqlGeography.IsValidExpensive(Boolean forceKatmai)
at Microsoft.SqlServer.Types.SqlGeography..ctor(GeoData g, Int32 srid)
at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid)
.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +2084358
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +5096328
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2294
System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33
System.Data.SqlClient.SqlDataReader.get_MetaData() +86
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +311
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +987
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
System.Data.SqlClient.SqlCommand.ExecuteReader() +89
gmaps.Button11_Click(Object sender, EventArgs e) +185
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563 

アドバイスしてください。または、これが別のトピックの場合は教えてください。私はSQLの初心者です

4

1 に答える 1

0

あなたのコードには多くの問題があります....

1.) @g と @h が初期化されていない変数の場合に MakeValid() を呼び出しています。

DECLARE @g geography;
DECLARE @h geography;

SET @h = @h.MakeValid();
SET @g = @g.MakeValid();

2.) @s とは何ですか? 一度も使っていません...

3.) @g は無効な自己交差ポリゴンです。このポイントセットを表す適切な有効なインスタンスは、MULTIPOLYGON (((23.483 39.671, 39.692 23.483, 23.721 39.602, 23.483 39.671)), ((23.466 39.8, 23.721 39.602, 24.095 39.493)8) 3 です。

4.) @h のリングの向きが正しくありません (つまり、地球の表面の 99% をカバーする Polygon を作成しようとしていないと仮定します)。POLYGON((39.43195 23.510742, 39.628961 23.128967, 39.800096 23.296509, 39.7093 23.859558, 39.43195 23.510742)) である必要があります。

したがって、SQL クエリは次のようになります。

DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('MULTIPOLYGON (((23.483 39.671, 39.692 23.483, 23.721 39.602, 23.483 39.671)), ((23.466 39.8, 23.721 39.602, 24.095 39.493, 23.466 39.8)))', 4326);
SET @h = geography::STGeomFromText('POLYGON((39.43195 23.510742, 39.628961 23.128967, 39.800096 23.296509, 39.7093 23.859558, 39.43195 23.510742))', 4326);
SELECT @g.STIntersects(@h) as reply;

以下に示す [SQL Server 空間結果] タブに示されているように、結果は「1」になります。

ここに画像の説明を入力

Pro Spatial と SQL Server 2012

于 2012-08-18T08:30:00.380 に答える