技术开发 频道

SQL Server 2008:新位置感知数据类型

  重温欧几里得几何

  如果你上数学课时没有打瞌睡,你一定会回忆得起欧几里得几何和最简单的直角坐标系,如图3所示,在这个坐标系中,起点的坐标是(0,0),x轴是从左往右递增,y轴是从下向上递增,无论使用哪种单位,计算出来的距离都是一样的。

  图 3 经典的直角坐标系

  SQL Server的geometry数据类型在这种模型下可以工作得很好,SQL Server内部将其当作.Net类型,因此你可以在应用程序中直接使用相同的类型,这个类型定义在Microsoft.SqlServer.Types.dll中,这个动态库默认位于C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies。

  如果你想将这些数据类型真正用起来,看看图4的例子就会有一点感觉,这个示例程序很简单,上面是数据库中存储的数值,下面是在地图上对这些点位的标注,此外,它可以检查一个点是否在某个多边形范围内。

  图 4 示例应用程序

  按下最顶端的按钮,它可以将一个几何点保存到数据库中,为了存储这些数据,首先需要创建表: 

CREATE TABLE [dbo].[GeometryTest](

  
[ID] [int] IDENTITY(1,1) NOT NULL,

  
[Points] [geometry] NOT NULL,

  
[Description] [nvarchar](50) NULL

  )

  有了这个表,你就可以使用下面的C#代码将值存储到该字段中了:

Microsoft.SqlServer.Types;

  ...

  
private void geometryAddPointButton_Click(

  
object sender, EventArgs e)

  {

  
int x = int.Parse(geometryXTextBox.Text);

  
int y = int.Parse(geometryYTextBox.Text);

  SqlGeometry geom
= SqlGeometry.Point(x, y, 0);

  
// add to database

  
string sql = "INSERT INTO [geometrytest] " +

  
"([points], [description]) VALUES " +

  
"(@points, @description)";

  StorePointIntoDatabase(geom, sql,
"geometry",

  
"My first geometry point");

  }

  首先,代码从用户界面读取x和y坐标,然后利用x和y值构造一个SqlGeometry实例,SqlGeometry类型位于Microsoft.SqlServer.Types命名空间中,那么如何使用类的Point方法构造一个点对象呢,最后一步,构造一个SQL insert语句,真正的数据库访问由StorePointIntoDatabase方法完成,而它又是这样实现的:

 internal int StorePointIntoDatabase(

  object geoPoint, string sql,

  string udtTypeName, string description)

  {

  SqlConnection conn
= GetConnection();

  try

  {

  SqlCommand cmd
= new SqlCommand(

  sql, conn);

  SqlParameter param
= cmd.Parameters.

  AddWithValue("
@points", geoPoint);

  param.UdtTypeName
= udtTypeName;

  cmd.Parameters.AddWithValue(

  "
@description", description);

  conn.
Open();

  
int rows = cmd.ExecuteNonQuery();

  MessageBox.Show("Added "
+ rows +

  " row(s)
to the database.");

  cmd.Dispose();

  
return rows;

  }

  finally

  {

  conn.Dispose();

  }

  }

  如果你之前曾经使用过SQL Server,上面的代码你应该很熟悉。首先,打开一个SQL Server数据库连接(关于打开数据库连接的细节在这里并不重要),然后使用给定的insert语句构造一个SqlCommand对象。

  注意Parameters.AddWithValue调用是如何指定参数值的,在其它大多数参数类型中,单独调用AddWithValue就足够了,但新的地理空间类型是当作UDF类型(.Net类型)的,参数对象的UdtTypeName属性必需设置,对于geometry类型,它设为geometry,对于geography类型就设为geography。

  现在你应该知道空间数据是如何添加到SQL Server 2008的数据库表中的了,现在你需要知道如何从这些表中读取空间数据,假设你的数据库表名是GeometryTest,这个表有一个id值,你可能需要根据给定的id值进行检索,在程序代码,可能需要实现下面的代码:

 internal SqlGeometry ReadPointFromDatabase(int id)

  {

  SqlConnection conn
= GetConnection();

  try

  {

  string sql
= "SELECT [points] " +

  "
FROM [geometrytest] " +

  "
WHERE ([id] = @id)";

  SqlCommand cmd
= new SqlCommand(

  sql, conn);

  cmd.Parameters.AddWithValue("
@id", id);

  conn.
Open();

  object geometryPoint
= cmd.ExecuteScalar();

  
if ((geometryPoint != null) &&

  (geometryPoint
is SqlGeometry)) {

  
return (SqlGeometry)geometryPoint;

  }

  
else return null;

  }

  finally

  {

  conn.Dispose();

  }

  }

  这里实现得非常简单,你只需要一个SQL Server连接,一个命令对象和一条简单的SQL语句,然后你就可以设定参数值读取结果。

0
相关文章