# Overview — connecting and querying

## What's actually behind a Historian query

```
   client (SSMS / app / aalog-equivalent)
         │  T-SQL
         ▼
   Microsoft SQL Server   ◄── normal SQL Server tables (Tag, AnalogTag, EngineeringUnit, etc.)
         │  OLE DB
         ▼
   INSQL linked server   ◄── this is the AVEVA Historian OLE DB Provider, name "INSQL"
         │  HCAL
         ▼
   Retrieval subsystem   ◄── reads .aaLGX history blocks on disk, returns rowsets
```

Configuration and event metadata live in real SQL Server tables. **Time-series ("history") data lives in binary history blocks on disk** and is presented through `INSQL` as if it were a SQL table. That's why every history query goes through the linked server.

## The extension tables

The "virtual" tables exposed by `INSQL`:

| Linked-server path | Local view | Purpose |
| --- | --- | --- |
| `INSQL.Runtime.dbo.History` | `History` | Tall format. One row per (tag, timestamp). The default for everything historical. |
| `INSQL.Runtime.dbo.Live` | `Live` | Most recent value per tag. Fast snapshot. |
| `INSQL.Runtime.dbo.WideHistory` | `WideHistory` | Wide format — one row per timestamp, one column per tag. **Must be queried via `OPENQUERY`**. Up to 1024 columns. |
| `INSQL.Runtime.dbo.AnalogSummaryHistory` | `AnalogSummaryHistory` | Pre-summarized analog data. |
| `INSQL.Runtime.dbo.StateSummaryHistory` | `StateSummaryHistory` | Pre-summarized state-tag data. |
| `INSQL.Runtime.dbo.HistoryBlock` | `HistoryBlock` | Metadata about the on-disk blocks (no `WHERE` required). |
| `INSQL.Runtime.dbo.Events` | `Events` | Alarm/event records. See [`06-alarms-events.md`](06-alarms-events.md). |

**Legacy backward-compatibility tables** (still supported, not preferred):
`AnalogHistory`, `DiscreteHistory`, `StringHistory`, `AnalogLive`, `DiscreteLive`, `StringLive`, plus `v_AlarmHistory`, `v_AlarmHistory2`, `v_EventHistory`, `v_AlarmEventHistoryInternal2`, `v_AlarmEventHistory2`. Use the unified `History` / `Live` / `Events` tables for new work.

## Linking `INSQL` to SQL Server

Done automatically by the Historian installer. If you ever need to redo it manually:

```sql
EXEC sp_addlinkedserver  @server='INSQL', @srvproduct='', @provider='INSQL';
EXEC sp_serveroption     'INSQL', 'collation compatible', true;
EXEC sp_addlinkedsrvlogin 'INSQL', 'TRUE', NULL, NULL, NULL;

-- Alias (used when joining the legacy analog and discrete tables in one query):
EXEC sp_addlinkedserver  @server='INSQLD', @srvproduct='', @provider='INSQL';
EXEC sp_serveroption     'INSQLD', 'collation compatible', true;
EXEC sp_addlinkedsrvlogin 'INSQLD', 'TRUE', NULL, NULL, NULL;
```

The `INSQL` OLE DB provider cannot run standalone — it must be hosted by SQL Server.

## Four ways to issue a SELECT

You'll see all four in the wild; each has a niche.

### 1. Four-part naming (preferred for `History`, `Live`, `Events`)

```sql
SELECT *
FROM INSQL.Runtime.dbo.History
WHERE TagName = 'SysTimeSec'
  AND DateTime >= '2001-09-12 12:59:00'
  AND DateTime <= '2001-09-12 13:00:00';
```

The four parts: `linked_server.catalog.schema.object_name`. For `INSQL` the catalog is **always `Runtime`** and the schema is **always `dbo`**.

### 2. Provider view (sugar over four-part)

Each extension table has a SQL Server view of the same name — `History`, `Live`, `Events`, etc.

```sql
SELECT *
FROM History
WHERE TagName = 'SysTimeSec'
  AND DateTime >= '2001-09-12 12:59:00'
  AND DateTime <= '2001-09-12 13:00:00';
```

Backward-compatibility views use `v_<name>`.

### 3. `OPENQUERY` (required for `WideHistory`, useful for pass-through)

```sql
SELECT * FROM OPENQUERY(INSQL, '
  SELECT DateTime, SysTimeSec, ReactTemp
  FROM WideHistory
  WHERE DateTime >= "2001-09-12 12:59:00"
    AND DateTime <= "2001-09-12 13:00:00"
');
```

The body is sent verbatim to `INSQL`. Quoting is **double quotes inside, single quote around the whole body.** Hard caps and quirks:

- 8000-character body limit.
- DateTime format must be `yyyy-mm-dd hh:mm:ss.fff`.
- `ORDER BY` and `GROUP BY` don't work *inside* the body (SQL Server doesn't see them) — apply them outside.
- Joins inside the body are unsupported. Place them outside.
- Variables (`@foo`) cannot appear inside the body.

### 4. `OPENROWSET` (one-off ad-hoc)

```sql
SELECT * FROM OPENROWSET('INSQL', '', '
  SELECT DateTime, Quality, QualityDetail, Value
  FROM History
  WHERE TagName IN ("SysTimeSec")
    AND DateTime >= "2001-09-12 12:59:00"
    AND DateTime <= "2001-09-12 13:00:00"
');
```

Requires that ad-hoc distributed queries be enabled on the SQL Server (`sp_configure 'Ad Hoc Distributed Queries', 1`). Generally not recommended in production code.

## When to use which style

| Scenario | Style |
| --- | --- |
| Tall queries against `History`, `Live`, `Events` | **Four-part** or **view** |
| `WideHistory` (one column per tag) | **OPENQUERY** (mandatory) |
| Heavy filtering you want SQL Server to optimize | **Four-part** (the optimizer can see the predicates) |
| Forcing a predicate down to `INSQL` that the optimizer is dropping | **OPENQUERY** (literal pass-through) |
| Joining a SQL Server table against a Historian extension table | Four-part, with **`INNER REMOTE JOIN`** |
| One-off scripts on a server with ad-hoc DQ enabled | **OPENROWSET** |

## Date format gotcha

For four-part queries on **non-English SQL Server installations** (French, German, etc.), the default datetime format may be `yyyy-dd-mm hh:mm:ss.fff` instead of `yyyy-mm-dd ...`. Use `CONVERT(...)` explicitly when in doubt — output formatting also depends on the OS regional settings.

For `OPENQUERY`, always use `yyyy-mm-dd hh:mm:ss.fff` regardless of locale.

## "No `WHERE` clause" error

If you get:

```
Server: Msg 7320, Level 16, State 2, Line 1
Could not execute query against OLE DB provider 'INSQL'.
[OLE/DB provider returned message: InSQL did not receive a WHERE clause from SQL Server. ...]
```

…the SQL Server query optimizer truncated the `WHERE` clause as "superfluous." Workaround: add a redundant condition such as `AND wwRetrievalMode = 'delta'`. See [`02-syntax-limits.md`](02-syntax-limits.md#where-clause-anomalies).

## Next

- [`02-syntax-limits.md`](02-syntax-limits.md) — what works and what doesn't, plus the `wwXxx` extensions overview.
- [`03-retrieval-modes.md`](03-retrieval-modes.md) — pick a `wwRetrievalMode`.
- [`05-query-recipes.md`](05-query-recipes.md) — practical patterns.
