7.8 KiB
AVEVA Historian — SQL Reference: Tag Value Recording & Tag Registration
Scope: Writing tag values and creating new tags in AVEVA Historian (formerly Wonderware Historian) directly through SQL Server, against the INSQL OLE DB provider / Runtime database. Applies to 2020 and 2023 R2 (history-block / binary storage).
Connection model: Connect to the Historian's SQL Server instance (e.g. Microsoft.Data.SqlClient). The time-series tables are extension tables — they don't physically exist in SQL Server; the INSQL provider routes reads/writes into the on-disk history blocks. No Framework SDK / HCAL required for this path.
Out of scope: Alarm/event recording. In high-speed mode the alarm/event store is fed only by the Application Server alarm provider — there is no supported SQL
INSERTfor alarms/events. Model process outcomes (pass/fail/cancel) as the tags below, or raise real alarms via an AppServer attribute. See the "Alarms/events" note at the end.
1. Recording tag VALUES via SQL
Two different tables depending on tag type. This is the most common trap.
1a. Analog & discrete tags → History table (numeric Value)
INSERT INSQL.Runtime.dbo.History (DateTime, TagName, Value, QualityDetail, wwVersion)
VALUES ('2026-06-18 10:00:00.000', 'LeakTest_Rate', 0.42, 0, 'Latest');
Valueis a float (analog real value, or 0/1 for discrete).- Four-part naming:
INSQL.Runtime.dbo.History.
1b. String tags → StringHistory table (string Value)
INSERT INSQL.Runtime.dbo.StringHistory (DateTime, TagName, Value, QualityDetail, wwVersion)
VALUES ('2026-06-18 10:00:00.000', 'LeakTest_Result', 'PASS', 0, 'Latest');
- Use
StringHistory+Value, notHistory+vValuefor strings. - Inserting a string into
History.vValuefails on 2023 R2 withMsg 8114 ... Error converting data type nvarchar to (null).
Column notes
| Column | Meaning |
|---|---|
DateTime |
Timestamp of the value (local server time unless using a UTC column). |
TagName |
Must already exist (see Section 2 to create it). |
Value |
Float in History; string in StringHistory. |
QualityDetail |
0 = good. (OPC-style alternative: OPCQuality, where 192 = good. Confirm which your queries expect.) |
wwVersion |
'Latest' or 'Original' — see below. |
wwVersion / data versioning
'Latest'— writes a revision that wins on retrieval.'Original'— as-acquired value; never destroyed, still readable withwwVersion = 'Original'.- An "update" is really a new revision layered on top, not an overwrite.
UPDATEof existing points generally must go throughOPENQUERY:SELECT * FROM OPENQUERY(INSQL, 'update History set Value = 40 where TagName = ''LeakTest_Rate'' and DateTime = ''2026-06-18 10:00:00.000''');
Constraints / gotchas
- Real-time window: values are accepted roughly -30 s to +999 ms around Historian time; outside that, a value sent as real-time/streamed may be discarded. Sync clocks for current-time inserts.
- Back-dating originals: to insert original (non-streamed) data into the past, the system parameter
AllowOriginalsmust permit it; otherwise you can only write revisions. Late/back-filled inserts trigger summary recomputation. - Tag must accept manual data — feed values into a manually-acquired / MDAS-style tag (or a tag configured so the Historian isn't expecting IDAS data). Tag ownership governs acceptance.
- Value semantics differ from a relational row: a stored value represents a change that persists until superseded by a later timestamp (step/sample-and-hold), not a discrete row. Timestamp rounding can make an insert look like a duplicate of the original point.
2. Registering (creating) NEW tags via SQL
Tag definitions live in normal SQL config tables in the Runtime database (not extension tables). Insert the definition, then commit to activate it.
Config tables (insert target by type)
| Tag type | Config table | Database Reference pg. |
|---|---|---|
| Analog | AnalogTag |
~294 |
| Discrete | DiscreteTag |
~296 |
| String | StringTag |
~299 |
Dependency order (create these first if they don't exist)
IDAS → IOServer → Topic → (EngineeringUnits for analog / MessagePairs for discrete) → tag
The export/import scanner makes no attempt to resolve ordering, so parents must precede children. For SQL/SDK-fed (manual) tags, set the acquisition type so the Historian does not expect IDAS data — these tags receive values only from your INSERTs (Section 1).
Method
INSERTthe row(s) intoAnalogTag/DiscreteTag/StringTagwith the required columns (TagName, storage/acquisition keys, type-specific fields such asMinEU/MaxEU/EngUnitfor analog or message pair for discrete).- Activate the pending config:
This is the T-SQL equivalent of "Commit Pending Changes" in the System Management Console; config changes on a running Historian don't take effect until committed. (
EXEC aaCommitChanges;aaCommitChangesAtStartupis the deferred-at-restart variant.)
Exact column lists vary and are column-heavy (storage node, acquisition type, storage type/rate, scaling, raw type, etc.). Confirm against the AVEVA Historian Database Reference,
AnalogTag/DiscreteTag/StringTagsections (pp. ~294–299) for your version before scripting.
Alternatives to raw config-table INSERT
- CSV import — the Database Configuration Export/Import utility (sectioned text file:
:(IOServer),:(Topic),:(AnalogTag),:(DiscreteTag),:(StringTag), …). Best for bulk tag creation; copy an existing tag's exported row, change the name/params. - Historian SDK — programmatic tag creation (.NET Framework; pulls HCAL back in).
- SMC GUI — manual, one tag at a time (right-click Topic → New Analog/Discrete/String Tag → Commit Pending Changes).
3. Quick template (manual tag → values), end to end
-- 1) Define a manual analog result tag (illustrative columns — verify vs Database Reference)
INSERT INSQL.Runtime.dbo.AnalogTag (TagName, /* storage/acquisition + EU columns */ ...)
VALUES ('LeakTest_Rate', /* ... */);
-- 2) Activate it
EXEC aaCommitChanges;
-- 3) Write values
INSERT INSQL.Runtime.dbo.History (DateTime, TagName, Value, QualityDetail, wwVersion)
VALUES (SYSDATETIME(), 'LeakTest_Rate', 0.42, 0, 'Latest');
For a string outcome tag, swap AnalogTag→StringTag and History/Value(float)→StringHistory/Value(string).
Alarms / events (why they're not here)
Alarms and events cannot be SQL-inserted into the high-speed (history-block) store — it is populated exclusively by an Application Engine configured as Alarm Provider (with storage-to-Historian enabled). The v_AlarmHistory / v_AlarmHistory2 / v_AlarmEventHistory2 views are read-only retrieval surfaces.
- Want a real alarm/event (live + historical, visible in alarm clients): raise it from an AppServer attribute alarm or the
LogDataChangeEventevent primitive — not SQL. - Want a historical-only event record in
dbo.Events: the documented writer is the Historian SDK; those records are never raised in the live A&E system. A directINSERTintodbo.Eventsis undocumented/unsupported and unverified for high-speed persistence — avoid for production. - Recommended: record process outcomes as the tags in Sections 1–2, and (if an event-style query surface is needed) put a SQL view over the result tags.
Reference compiled from AVEVA Historian documentation (Database Reference, Administration Guide, Retrieval Guide, Concepts Guide) and AVEVA community guidance. Verify exact table columns and system-parameter behavior against the Database Reference for your specific version (2020 / 2023 R2) before production use.