1. ECSQL

ECSQL 是针对 iModel 或 ECDb 文件中的业务数据的 CRUD(创建、读取、更新、删除)操作的基于文本的命令语言。

ECSQL 是 SQL 一种实现-一种经过验证的、经过充分采用的基于文本的命令语言。尽可能遵守标准 SQL (SQL-92 和 SQL-99)。

ECSQL 和 SQL 之间的主要区别在于,ECSQL 针对的是逻辑模式,而不是基础数据库的持久性模式。

01

1.1. ECSQL 参数

  • ? : 占位参数,按顺序赋值;

    SELECT ECInstanceId FROM bis.GeometricElement3d WHERE Model=? AND LastMod>=?
    
  • :aaa : 命名参数。这允许将相同的值绑定到多个占位符。

    SELECT ECInstanceId FROM bis.GeometricElement3d LIMIT :pagesize OFFSET (:pageno * :pagesize)
    

// 查询构件数目,真实世界存在的构件
SELECT count(*) FROM bis.spatialElement ,

// 查询每个实际元素类型在 iModel 中有多少空间元素
SELECT ECClassId, count(*) ElementCount FROM bis.SpatialElement GROUP BY ECClassId ORDER BY ECClassId

// 支持LIMIT 和 OFFSET 分页参数查询,即查询11-15行的数据
SELECT ECInstanceId, ECClassId, CodeValue FROM bis.SpatialLocationElement LIMIT 5 OFFSET 10

// 格式化输出
SELECT count(*) ElementCount FROM bis.SpatialElement

// 基本的数学计算
SELECT 10 Radius, (2 * 3.1415 * 10) Perimeter, (3.1415 * 10 * 10) Area FROM bis.Element LIMIT 1

// NULL 值判定,使用 IS NULL判断,而非 value = NULL(返回空值)
SELECT ECInstanceId,ECClassId FROM bis.SpatialElement WHERE UserLabel IS NULL LIMIT 5

// 时间段查询,支持TIMESTAMP
SELECT ECInstanceId, CodeValue, LastMod FROM bis.Element WHERE LastMod BETWEEN TIMESTAMP '2020-03-11T12:30:20.492Z' AND TIMESTAMP '2020-03-11T12:31:03.494Z'

// IIF 关键字
-- Returns 'Big' if Length is greater than 1, and 'Small' otherwise
SELECT IIF(Length > 1.0, 'Big', 'Small') FROM test.Foo;

-- Returns DisplayLabel if Name is NULL, and Name otherwise
SELECT IF(Name IS NULL, DisplayLabel, Name) FROM test.Foo;

// 复杂的CASE-WHEN-THEN-ELSE
CASE
      WHEN <expr> THEN <expr>
    [ WHEN <expr> THEN <expr> ...]
    [ ELSE <expr> ]
END

// Demo
-- CASE without ELSE. Returns NULL if the IF case is not met
SELECT
    CASE
         WHEN Length > 1 THEN 'Big'
    END
FROM test.Foo

-- CASE with ELSE. If Length is not greater than 1 then the ELSE expression is returned.
SELECT
    CASE
        WHEN Length > 1 THEN 'Big'
        ELSE 'Small'
    END
FROM test.Foo

-- Multiple CASE with ELSE
SELECT
    CASE
        WHEN weekDay=1 THEN 'Mon'
        WHEN weekDay=2 THEN 'Tue'
        WHEN weekDay=3 THEN 'Wen'
        WHEN weekDay=4 THEN 'Thr'
        WHEN weekDay=5 THEN 'Fri'
        WHEN weekDay=6 THEN 'Sat'
        WHEN weekDay=7 THEN 'Sun'
        ELSE 'Wrong value'
    END
FROM test.Foo

// 几何查询,例如查询构件的包围盒
// 详情可查询: https://www.itwinjs.org/learning/geometrysqlfuncs/
  SELECT
    iModel_bbox_union(
      iModel_placement_aabb(
        iModel_placement(
          iModel_point(g.Origin.X, g.Origin.Y, g.Origin.Z),
          iModel_angles(g.Yaw, g.Pitch, g.Roll),
          iModel_bbox(g.BBoxLow.X, g.BBoxLow.Y, g.BBoxLow.Z, g.BBoxHigh.X, g.BBoxHigh.Y, g.BBoxHigh.Z)
        )
      )
    )
  FROM ${Element.classFullName} AS e, ${GeometricElement3d.classFullName} AS g
    WHERE e.model.id=? AND e.ecinstanceid=g.ecinstanceid

// 空间关系--Overlap 
// code
const spaceElement: SpatialElement = iModelDb.elements.getElement("0x1000000001f") as SpatialElement;
iModelDb.withPreparedStatement("SELECT e.ECInstanceId, e.ECClassId, e.CodeValue FROM bis.SpatialElement e JOIN bis.SpatialIndex i ON e.ECInstanceId=i.ECInstanceId WHERE i.ECInstanceId MATCH iModel_spatial_overlap_aabb(?) AND e.Category.Id=0x1000000000a",
   (stmt: ECSqlStatement) => {
     stmt.bindRange3d(1, spaceElement.placement.calculateRange());
     while (stmt.step() === DbResult.BE_SQLITE_ROW) {
        const row: any = stmt.getRow();
        console.log(row);
     }
   });

// result
{ id : "0x1000000001e", className: "MyDomain.Story", codeValue: "A-G" }
{ id : "0x10000000023", className: "MyDomain.Story", codeValue: "A-1" }

results matching ""

    No results matching ""