IQueryFilter.whereclause屬性

本文详细介绍了在ArcGIS中使用IQueryFilter接口进行查询选择的方法,涵盖了SQL语法、字段名规则、字符串规则等内容,并提供了针对不同数据源的具体指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:http://edndoc.esri.com/arcobjects/9.2/ComponentHelp/esrigeodatabase/IQueryFilter_WhereClause.htm

 (這篇隨筆是根據ESRI Document Library里對IQueryFilter接口的描述翻譯成的,有些地方覺得原文不太清晰,又自己找了點資料完善了一下,看資料還是中文快啊...)

IQueryFilter.whereclause屬性

      IQueryFilter是進行查詢選擇時經常用到的接口,它可以幫助用戶過濾不需要的值或者選擇適當的要素。     

     IQueryFilter.whereclause屬性允許用戶設定過濾表達式限定返回的要素。舉個例子,我們可以使用下面的表達式來選取面積大于1500平方米的多邊形: "Area" >1500.

     這種表達式實質上是一種SQL查詢。其查詢語法視乎用戶正在使用的數據源,即數據庫或者數據源上的原本格式(native format). 為了方便用戶,ARCGIS提供了一個叫ISQLSyntax 的接口(在workspace下),用來獲取數據源的SQL語法信息,包括間隔符,大小寫等信息。對于SQL語法規則不清楚的,也可參見:http://webhelp.esri.com/arcgisdesktop/9.2/index.cfm?TopicName=SQL_reference.

      

字段名規則
     1)如果是在file geodatabase, shapefile, dBase table, coverage, INFO table進行查詢,那么字段名應該包含在雙引號內:   "AREA"
     2)如果是在personal geodatabase進行查詢,字段名需用方括號括起來:[AREA]
     3)假如在ArcSDE的地理地理數據庫(例如通過數據庫連接方式連接到某個ArcSDE的企業地理數據庫,或者連接到某個運行著ArcSDE Personal Edition or Workgroup Edition的數據庫服務器)或是在ArcIMS image service or feature service是,字段在查詢時不需括起来: AREA.
     4)在Excel或者文本文件上查詢時,字段需用單引號括起,除非你正使用的是表格窗口上Select By Attributes對話框,这种情況下,使用方括號[AREA].

字符串規則
     在whereclause表達式里,字符串要用單引號括著,例如: "STATE_NAME" = 'California'.
     存儲在Access的Personal geodatabases是不區分大小寫的(case insensetive),而ArcSDE, File and shapefiles則會區分大小寫(case sensetive)。對區分大小寫的數據源(datasource),可以使用SQL函數來統一大小寫,以避免查詢失敗。

     舉個例子,假設某個給定的字段名為"Florida", 如果whereclause 是 "State_name = 'florida'",personal geodatabase返回的是美國的一個州,而在shapefiles and ArcSDE則查詢不到。

     下面的表達式會選擇姓氏為Jones或者JONES的客戶:UPPER("LAST_NAME") = 'JONES'

通配符規則
     當你不確定查詢字段名或者想用簡短的字符串時,可以使用通配符。通配符是一個特殊的符號,用于代表一個或者多個字符,一般包括這幾個: “%”,“*”,“ _”,“ ?". 

     如果你是在coverage, shapefile, INFO table, dBASE table, or shared geodatabase查詢,那么'_' 表示任何一個字符,而 '%' 表示0到任意個字符.

     如果你是在personal geodatabase查詢,那么'?' 表示任何一個字符,而 '*' 表示0到任意個字符.

     注意:如果字符串中通配符跟著操作符“=”,那么它將被視為字符串,而不是通配符。

            

 NULL關鍵字

     在geodatabases里字段支持NULL,在shapefiles/dBASE tables and coverages/INFO tables,時間字段可以為NULL.

     NULL一般前面都跟著IS或者IS NOT.

 

 唯一(Distinct)关键字 
     file geodatabases不支持關鍵字Distinct,建議使用IDataStatistics::UniqueValues方法返回唯一值。

 

SubQuery(子查詢)

     子查詢就是允許嵌套的SQL查詢,只適用于geodatabase數據源。

Query Numbers(查詢數字)

     操作數字的操作符包括: equal (=), not equal (<>), greater than (>), less than (<), greater than or equal (>=), and less than or equal (<=) operators. 

 Query Date (查詢時間)
     查詢時間的語法取決于數據類型。在查詢時間值時,應該了解正在使用的data source如何表示Date.

     舉個例子,在.dbf下查詢時間,用"Date_Carte = date '1992/02/04'" ,而

     "Date_Carte = '1992/02/04'" 或者"Date_Carte = '#1992/02/04#'"將發生錯誤。

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; namespace WindowsFormsApplication1 { public partial class Form2 : Form { private Form1 mainForm; // 主窗体引用 private ILayer selectedLayer; // 当前选中的图层 public Form2(Form1 form) { InitializeComponent(); mainForm = form; } private void Form2_Load(object sender, EventArgs e) { // 初始化图层列表 LoadLayers(); } // 加载图层到下拉列表 private void LoadLayers() { cboLayers.Items.Clear(); IMap map = mainForm.axMapControl1.Map; for (int i = 0; i < map.LayerCount; i++) { ILayer layer = map.get_Layer(i); cboLayers.Items.Add(layer.Name); } if (cboLayers.Items.Count > 0) { cboLayers.SelectedIndex = 0; } } // 获取当前选中的图层 private ILayer GetSelectedLayer() { if (cboLayers.SelectedIndex < 0) return null; string layerName = cboLayers.SelectedItem.ToString(); IMap map = mainForm.axMapControl1.Map; for (int i = 0; i < map.LayerCount; i++) { if (map.get_Layer(i).Name == layerName) { return map.get_Layer(i); } } return null; } // 图层选择改变时加载字段 private void cboLayers_SelectedIndexChanged(object sender, EventArgs e) { LoadFields(); } // 加载字段到字段下拉框 private void LoadFields() { cboFields.Items.Clear(); selectedLayer = GetSelectedLayer(); if (selectedLayer == null) return; IFeatureLayer featureLayer = selectedLayer as IFeatureLayer; if (featureLayer == null) return; IFeatureClass featureClass = featureLayer.FeatureClass; IFields fields = featureClass.Fields; for (int i = 0; i < fields.FieldCount; i++) { IField field = fields.get_Field(i); cboFields.Items.Add(field.Name); } if (cboFields.Items.Count > 0) { cboFields.SelectedIndex = 0; } } // 获取唯一值 private void btnGetUniqueValues_Click(object sender, EventArgs e) { selectedLayer = GetSelectedLayer(); if (selectedLayer == null) return; IFeatureLayer featureLayer = selectedLayer as IFeatureLayer; if (featureLayer == null) { MessageBox.Show("请选择一个要素图层"); return; } IFeatureClass featureClass = featureLayer.FeatureClass; if (cboFields.SelectedIndex < 0) { MessageBox.Show("请选择字段"); return; } string fieldName = cboFields.SelectedItem.ToString(); int fieldIndex = featureClass.FindField(fieldName); if (fieldIndex == -1) { MessageBox.Show($"字段 '{fieldName}' 不存在"); return; } // 获取唯一值 IDataStatistics dataStats = new DataStatisticsClass(); dataStats.Field = fieldName; ICursor cursor = featureClass.Search(null, true); dataStats.Cursor = cursor; IEnumerator enumerator = dataStats.UniqueValues; lstValues.Items.Clear(); while (enumerator.MoveNext()) { lstValues.Items.Add(enumerator.Current.ToString()); } } // 添加到查询条件 private void btnAddToQuery_Click(object sender, EventArgs e) { if (lstValues.SelectedItem != null) { string value = lstValues.SelectedItem.ToString(); string field = cboFields.SelectedItem.ToString(); if (!string.IsNullOrEmpty(field) && !string.IsNullOrEmpty(value)) { if (txtWhereClause.Text.Length > 0) { txtWhereClause.Text += " "; } txtWhereClause.Text += $"{field} = '{value}'"; } } } // 双击列表项添加到查询条件 private void lstValues_DoubleClick(object sender, EventArgs e) { if (lstValues.SelectedItem != null) { string value = lstValues.SelectedItem.ToString(); string field = cboFields.SelectedItem.ToString(); if (!string.IsNullOrEmpty(field) && !string.IsNullOrEmpty(value)) { if (txtWhereClause.Text.Length > 0) { txtWhereClause.Text += " "; } txtWhereClause.Text += $"{field} = '{value}'"; } } } // 验证查询条件 private void btnValidate_Click(object sender, EventArgs e) { selectedLayer = GetSelectedLayer(); if (selectedLayer == null) return; IFeatureLayer featureLayer = selectedLayer as IFeatureLayer; if (featureLayer == null) { MessageBox.Show("请选择一个要素图层"); return; } string whereClause = txtWhereClause.Text.Trim(); if (string.IsNullOrEmpty(whereClause)) { MessageBox.Show("查询条件不能为空"); return; } try { IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.WhereClause = whereClause; // 尝试获取一个要素来验证查询 IFeatureCursor cursor = featureLayer.FeatureClass.Search(queryFilter, false); IFeature feature = cursor.NextFeature(); if (feature != null) { MessageBox.Show("查询条件有效"); } else { MessageBox.Show("查询条件有效,但没有匹配的记录"); } } catch (Exception ex) { MessageBox.Show($"查询条件无效: {ex.Message}"); } } // 应用查询 private void btnApply_Click(object sender, EventArgs e) { selectedLayer = GetSelectedLayer(); if (selectedLayer == null) return; IFeatureLayer featureLayer = selectedLayer as IFeatureLayer; if (featureLayer == null) { MessageBox.Show("请选择一个要素图层"); return; } string whereClause = txtWhereClause.Text.Trim(); if (string.IsNullOrEmpty(whereClause)) { MessageBox.Show("查询条件不能为空"); return; } try { IQueryFilter queryFilter = new QueryFilterClass(); queryFilter.WhereClause = whereClause; // 执行查询 IFeatureCursor cursor = featureLayer.FeatureClass.Search(queryFilter, false); IFeature feature; List<int> oidList = new List<int>(); // 获取所有符合条件的OID while ((feature = cursor.NextFeature()) != null) { oidList.Add(feature.OID); } // 在Form1中高亮显示 mainForm.HighlightFeatures(selectedLayer, oidList); // 加载属性数据 LoadAttributeData(featureLayer, queryFilter); MessageBox.Show($"找到 {oidList.Count} 条记录"); } catch (Exception ex) { MessageBox.Show($"查询失败: {ex.Message}"); } } // 加载属性数据到DataGridView private void LoadAttributeData(IFeatureLayer featureLayer, IQueryFilter queryFilter) { ITable table = featureLayer.FeatureClass as ITable; if (table == null) return; DataTable dataTable = new DataTable(); IFields fields = table.Fields; // 添加列 for (int i = 0; i < fields.FieldCount; i++) { IField field = fields.get_Field(i); dataTable.Columns.Add(field.AliasName, typeof(string)); } // 查询数据 ICursor cursor = table.Search(queryFilter, false); IRow row; int maxRecords = 1000; // 限制记录数 int recordCount = 0; while ((row = cursor.NextRow()) != null && recordCount < maxRecords) { DataRow dataRow = dataTable.NewRow(); for (int i = 0; i < fields.FieldCount; i++) { object value = row.get_Value(i); dataRow[i] = value == null ? string.Empty : value.ToString(); } dataTable.Rows.Add(dataRow); recordCount++; } dgvResults.DataSource = dataTable; } // 关闭窗体 private void btnClose_Click(object sender, EventArgs e) { this.Close(); } // 清除查询条件 private void btnClear_Click(object sender, EventArgs e) { txtWhereClause.Text = ""; } // 逻辑运算符按钮点击事件 private void OperatorButton_Click(object sender, EventArgs e) { Button btn = sender as Button; if (btn != null) { if (txtWhereClause.Text.Length > 0) { txtWhereClause.Text += " "; } txtWhereClause.Text += btn.Text + " "; } } // 括号按钮点击事件 private void btnParentheses_Click(object sender, EventArgs e) { Button btn = sender as Button; if (btn != null) { if (txtWhereClause.Text.Length > 0) { txtWhereClause.Text += " "; } txtWhereClause.Text += btn.Text; } } } }不改变代码内容,仅将美元符号的字符串插值,全部替换为format方法,因为我是vs2010版本不支持美元字符串插值
最新发布
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值