Geodatabase中的QueryDef对象
QueryDef 对象代表了数据库中基于一个或多个表、要素类的进行的属性查询。通过这个对象,用户可以在多个表间建立连接,并且保证在这个连接基础上的查询可以实现。
QueryDef 中的表必须放在一个工作空间内,而QueryDef 对象也是用IFeatureWorkspace::CreateQueryDef 方法来产生,它并不是一个组件类。需要注意的是,它并不能在Shapefile 和Coverage 数据中使用,而仅仅可以使用在GeoDatabase数据库中。
QueryDef 的查询的结果是Cursor 对象返回的,系统可以依据返回的Cursor 来获得基于查询的要素集合。但是使用这种方式获得的Cursor 对象,仅仅是只读的,Cursor 指向的行对象并没有和它们的父表相关联,因而如果试图对这些被选择出来的数据使用store 方法会出现错误。
IQueryDef 是QueryDef 对象实现的主要接口,它定义了在多个表中定义连接需要使用的属性和方法。SubFields 属性是产生一个QueryDef 对象时的可选项,默认情况下它为“*”,它表示返回所有的字段。下面的例子用于显示如何产生一个QueryDef 对象,并使用它在两个表中产生一个连接,
' 产生一个QueryDef 对象
Dim pQueryDef As IQueryDef
pQueryDef = pFeatureWorkspace.CreateQueryDef
' 基于连接的两个表必须是在一个工作空间内,设置它的各种属性
pQueryDef.Tables = "Counties, States"
pQueryDef.SubFields = "COUNTIES.Shape, COUNTIES.NAME, STATES.STATE_ABBR"
pQueryDef.WhereClause = "COUNTIES.STATE_FIPS = STATES.STATE_FIPS"
IFeatureWorkspace::OpenFeatureQuery 方法会产生一个基于QueryDef 对象的要素类,这个要素类可以被作为一个要素图层被添加到一个Map 对象中去,它和ArcSDE 中的“视图”概念很类似。下面的例子就是基于一个上面产生的QueryDef 对象来新建一个要素类的例子,注意IQueryDed::SubFields 中必须设置一个字段,以保证新建的要素类有最少拥有一个属性字段:
' 新建一个要素类
Dim pFeatureClass As IFeatureClass
Dim pFeatureClassContainer As IFeatureClassContainer
pFeatureClassContainer = pFeatureWorkspace.OpenFeatureQuery ("My counties join", pQueryDef)
' 判断IFeatureClassContainer 对象中是否有要素类存在
If (pFeatureClassContainer.ClassCount <> 1) Then
MsgBox "Failed to create feature class by query"
Else pFeatureClass = pFeatureClassContainer.Class(0)
End If
' 添加要素类到Map 对象
Dim pFeatureLayer As IFeatureLayer
pFeatureLayer = New FeatureLayerClass
pFeatureLayer.FeatureClass = pFeatureClass
pFeatureLayer.Name = pFeatureClass.AliasName
pMap.AddLayer (pFeatureLayer)
QueryDef 对象使用的SQL 语法和关系数据库中使用的SQL 语法是一样的,程序可以使用工作空间对象的ISqlSyntax 接口来获得这个数据库中的SQL 语法信息。
QueryDef 代表了一个查询的子集,在数据库中,用户也可以使用SELECT 语句来得到同样的结果。但是QueryDef 并不能完整地支持SQL 语句。在ArcObjects 中的SQL 语句不能使用SQL 语句的order by,如果需要对选择的结果结果进行排序,可以使用ITablesort 接口进行操作。
Related Items
Comments
在使用QueryFilter对象的whereClause方法时,向作者所举的例子在数据库中北京的值为"Beijing",执行的WhereClause语句必须是"cityname='Beijing'"(注意Beijing外面还带有单引号).
这里如果是一个变量向dim pName as string
pName="Beijing"
现在想在查询语句中使用变量pName来代替"Beijing",不知道该查询语句该怎么写.
Dim pS As String
pS = "'" & "Kansas" & "'"
pQueryFilter.WhereClause = "state_name=" & pS
这样你看明白了吧。![]()
![]()
看懂了.现在还有一个问题,如果PS这个变量我们事先并不知道,而是我们在程序运行的过程中得到的,也就是不能使用pS = "'" & "Kansas" & "'"这个语句,下面的语法又该做那些改动呢?
那就是取代"Kansas"这个字符串,如
p1=Text1.text.toString
pS="'"&p1&"'"
谢谢指教,在你的指教下该问题已经解决!
SELECT Shape, ID, CODE, TYPE_C, AREA, DATE_
FROM xmsd1989
WHERE ID NOT IN (SELECT ID FROM History WHERE Oper = 'A') union
SELECT Shape, ID, CODE, TYPE_C, AREA, DATE_
FROM History
WHERE oper = 'D' AND ID NOT IN (SELECT ID FROM History WHERE oper = 'A'
请问一下,这个复杂的SQL语句通过AO的IQueryDef可以实现吗?如果不能实现,可以采取什么样的方法?还有您可不可以详细讲解一下,AO查询中具体有哪些SQL语句不能用如ORDERBY.
这个问题我研究了差不多有三天了,我找了很多材料,可是都没有详细的说,上面的例子大多都是一些简单的查询.所以想请您帮忙,如果方便,请将解决方法发到我的邮箱,谢谢您
明确的讲,你要的功能AO91版本根本做不到,AO的查询功能只能做到依据属性和空间查询,单纯的sql排序语句还必须通过ITableSort实现,更不必说使用select的方式选择Shape字段,因为简单属性的索引和SHAPE的索引是两码事情,实现的机制都不一样,跟不必说左关联右关联等高级主题了。
这一个还是七楼的问题:
上午的邮件收到了吗?由于我现在所做的项目一定要实现我给您提到的那个查询,也可以通过不同的方法实现同一个结目标,您能指导我一下该怎样才能实现我要的查询吗?
我看到你写的关于ADO.NET直接连接Geodatabase数据库的文章,我想,可不可以通过这种方式来实现我上面的查询?我写了以下代码,帮忙看一下错在哪里?它提示的错误是:
未处理的“System.Data.OleDb.OleDbException”类型的异常出现在 system.data.dll 中。
其他信息: 没有可用的错误信息: E_FAIL(0x80004005)。
代码如下:
Dim ConnStr As String
ConnStr = "Provider=ESRI.GeoDB.OLEDB.1;Data Source= f:\dcy\lx\xmsd\xmsd.mdb;ExtendedProperties=workspacetype=esriDataSourcesGDB.AccessWorkspaceFactory.1;Geometry=WKB"
Dim Myconn As New OleDbConnection(ConnStr)
Myconn.Open()
Dim da As New OleDbDataAdapter
da.SelectCommand = New OleDbCommand("select Shape, ID, CODE, TYPE_C, AREA, DATE_ from History where oper = 'D'and ID not in (select ID from History where oper = 'A')", Myconn)
Dim ds As New DataSet
da.Fill(ds, "states")
DataGrid1.SetDataBinding(ds, "states")
使用直接连接不能访问shape,GDB还没有先进到使用select的方式查询shape字段。
如何将一副地图中的点、线、面都存入到geodatabase中呢?谢谢
Leave a comment
Or, take a look at Archives and Categories
用这个方法加载图层,有一个问题:
无法用IFeatureSelection对这个虚拟图层进行初始化,
即不能高亮显示用户选择的地物,不能方便地用IFeatureSelection和ISelectionSet接口的方法和属性.统计地物信息就比较麻烦.