sqlinsight-pro/SQL Scripts/_collectors/AxSequenceCollector.sql
Søren Eggert Lundsteen Olsen be039a6f73 Review 1.4: AX reads put the agent's session settings back
AxSql.Reset ran SET LOCK_TIMEOUT -1 and READ COMMITTED after every AX read
(and after the AX detection in discovery). The collectors of an instance
share one connection, so every collector after the AX ones waited on locks
without limit instead of the agent's 5 s, and no longer read uncommitted.
Reset now restores the agent's own settings, from one place
(Core.Instances.AgentSession) that SqlConnectionFactory.SessionSettings also
uses. The AX reads themselves are unchanged: READ COMMITTED (or SNAPSHOT)
with a 2 s lock timeout inside sp_executesql, never NOLOCK.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 14:14:24 +02:00

105 lines
12 KiB
Transact-SQL

-- ===================================================================================================================
-- Collector: AxSequenceCollector ("dynamics-ax-sequences")
-- ===================================================================================================================
-- Hvad: Hver time, i hver genkendt og overvåget AX-database: de mest brugte nummerserier
-- (NUMBERSEQUENCETABLE, med firma og om en reference bruger serien) og de højeste RecId-serier
-- (SYSTEMSEQUENCES). SQLInsight gemmer én måling pr. serie pr. dag i sit eget repository
-- (insight.AxSequenceSamples) og laver prognoserne ud fra den - aldrig i AX.
-- Fil: src/SQLInsight.Collectors/DynamicsAx/AxSequenceCollector.cs; SQL: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs
-- Interval: 1 time som standard (SQLInsight:CollectorIntervals:dynamics-ax-sequences)
-- Versioner: SQL Server 2005 og nyere (ikke 2000). Axapta 3.0: verificeret mod en kundes skema (docs/dynamics-ax/
-- schema-ax30.tsv). AX 4.0, AX 2009, AX 2012 og F&O: baseret på Microsofts dokumenterede skema - ikke
-- verificeret mod kundedata.
--
-- Rettigheder til agentens login (se db/permissions/grant-least-privilege.sql og grant-dynamics-ax-read.sql):
-- Valgfri AX-læseadgang, kun SELECT (db/permissions/grant-dynamics-ax-read.sql; [bruger] = agentens databasebruger):
-- Axapta 3.0: GRANT SELECT ON [bmssa].[NUMBERSEQUENCETABLE] TO [bruger];
-- GRANT SELECT ON [bmssa].[NUMBERSEQUENCEREFERENCE] TO [bruger]; -- valgfri: om serien bruges
-- AX 4.0/2009: de samme tabeller i [dbo]
-- AX 2012/F&O: desuden GRANT SELECT ON [dbo].[NUMBERSEQUENCESCOPE] TO [bruger]; -- valgfri: firma
-- Mangler NUMBERSEQUENCETABLE, er reglen "ikke målbar" med den nøjagtige GRANT for databasen. Uden GRANT ændres intet.
-- Genkendelsen: kun grant-least-privilege.sql (VIEW ANY DEFINITION; CONNECT ANY DATABASE fra 2014, ellers en
-- databasebruger: CREATE USER [agent] FOR LOGIN [agent];).
-- Valgfri AX-læseadgang, kun SELECT (db/permissions/grant-dynamics-ax-read.sql; [bruger] = agentens databasebruger):
-- Axapta 3.0: GRANT SELECT ON [bmssa].[SYSTEMSEQUENCES] TO [bruger];
-- GRANT SELECT ON [bmssa].[SQLDICTIONARY] TO [bruger]; -- valgfri: tabelnavne
-- AX 4.0/2009/2012/F&O: de samme tabeller i [dbo]
-- Mangler SYSTEMSEQUENCES, er reglen "ikke målbar" med den nøjagtige GRANT for databasen. Uden GRANT ændres intet.
-- Genkendelsen: kun grant-least-privilege.sql (VIEW ANY DEFINITION; CONNECT ANY DATABASE fra 2014, ellers en
-- databasebruger: CREATE USER [agent] FOR LOGIN [agent];).
--
-- Bruges af: SQLI-AX-005..009 og Dynamics AX → Nummerserier og RecId
-- Read-only: Ja: kun SELECT med TOP og SET-sessionsindstillinger. AX-tabellerne læses i AX-databasen via
-- [db].sys.sp_executesql (sessionen skifter aldrig database) under READ COMMITTED med SET LOCK_TIMEOUT 2000
-- (SNAPSHOT, når databasen tillader det), aldrig NOLOCK; bagefter sættes agentens sessionsindstillinger
-- igen. Intet ændrer data, indstillinger eller objekter. Kun i databaser genkendt som AX og valgt til
-- overvågning.
-- Kørsel: Kør i SSMS som agentens login (eller et login med samme rettigheder). Hver variant er sin egen batch
-- (GO); varianter for andre AX-versioner end din fejler eller giver ingen rækker - det er forventet.
-- AX-forespørgslerne er vist for databasen AXDB: ret [AXDB] til din AX-database.
-- ===================================================================================================================
-- -------------------------------------------------------------------------------------------------------------------
-- AxSequenceCollector: Nummerserier i AX-databasen (valgfri AX-læseadgang)
-- -------------------------------------------------------------------------------------------------------------------
-- Variant: Axapta 3.0 (skema bmssa, verificeret mod kundedata): nummerserier
-- Kilde: AxSchemaAdapter.NumberSequences(3.0)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.NumberSequences(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (5000) CAST(n.[RECID] AS bigint), n.[NUMBERSEQUENCE], n.[DATAAREAID], n.[TXT], CAST(n.[LOWEST] AS bigint), CAST(n.[HIGHEST] AS bigint), CAST(n.[NEXTREC] AS bigint), n.[FORMAT], ISNULL(n.[BLOCKED], 0), ISNULL(n.[CONTINUOUS], 0), ISNULL(n.[CYCLIC], 0), ISNULL(n.[MANUAL], 0), CASE WHEN EXISTS (SELECT 1 FROM [bmssa].[NUMBERSEQUENCEREFERENCE] r WHERE r.[NUMBERSEQUENCE] = n.[NUMBERSEQUENCE] AND r.[DATAAREAID] = n.[DATAAREAID]) THEN 1 ELSE 0 END, n.[LATESTCLEANDATE], n.[LATESTCLEANTIME], CAST(n.[CLEANINTERVAL] AS float), DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [bmssa].[NUMBERSEQUENCETABLE] n ORDER BY (CAST(n.[NEXTREC] AS float) - n.[LOWEST]) / NULLIF(CAST(n.[HIGHEST] AS float) - n.[LOWEST], 0) DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- Variant: AX 4.0 (skema dbo) - ikke verificeret mod kundedata: nummerserier
-- Kilde: AxSchemaAdapter.NumberSequences(4.0)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.NumberSequences(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (5000) CAST(n.[RECID] AS bigint), n.[NUMBERSEQUENCE], n.[DATAAREAID], n.[TXT], CAST(n.[LOWEST] AS bigint), CAST(n.[HIGHEST] AS bigint), CAST(n.[NEXTREC] AS bigint), n.[FORMAT], ISNULL(n.[BLOCKED], 0), ISNULL(n.[CONTINUOUS], 0), ISNULL(n.[CYCLIC], 0), ISNULL(n.[MANUAL], 0), CASE WHEN EXISTS (SELECT 1 FROM [dbo].[NUMBERSEQUENCEREFERENCE] r WHERE r.[NUMBERSEQUENCE] = n.[NUMBERSEQUENCE] AND r.[DATAAREAID] = n.[DATAAREAID]) THEN 1 ELSE 0 END, n.[LATESTCLEANDATE], n.[LATESTCLEANTIME], CAST(n.[CLEANINTERVAL] AS float), DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[NUMBERSEQUENCETABLE] n ORDER BY (CAST(n.[NEXTREC] AS float) - n.[LOWEST]) / NULLIF(CAST(n.[HIGHEST] AS float) - n.[LOWEST], 0) DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- Variant: AX 2009 - baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: nummerserier
-- Kilde: AxSchemaAdapter.NumberSequences(2009)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.NumberSequences(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (5000) CAST(n.[RECID] AS bigint), n.[NUMBERSEQUENCE], n.[DATAAREAID], n.[TXT], CAST(n.[LOWEST] AS bigint), CAST(n.[HIGHEST] AS bigint), CAST(n.[NEXTREC] AS bigint), n.[FORMAT], ISNULL(n.[BLOCKED], 0), ISNULL(n.[CONTINUOUS], 0), ISNULL(n.[CYCLIC], 0), ISNULL(n.[MANUAL], 0), CASE WHEN EXISTS (SELECT 1 FROM [dbo].[NUMBERSEQUENCEREFERENCE] r WHERE r.[NUMBERSEQUENCE] = n.[NUMBERSEQUENCE] AND r.[DATAAREAID] = n.[DATAAREAID]) THEN 1 ELSE 0 END, n.[LATESTCLEANDATETIME], CAST(NULL AS int), CAST(n.[CLEANINTERVAL] AS float), DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[NUMBERSEQUENCETABLE] n ORDER BY (CAST(n.[NEXTREC] AS float) - n.[LOWEST]) / NULLIF(CAST(n.[HIGHEST] AS float) - n.[LOWEST], 0) DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- Variant: AX 2012 RTM/R2/R3 - baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: nummerserier
-- Kilde: AxSchemaAdapter.NumberSequences(2012)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.NumberSequences(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (5000) CAST(n.[RECID] AS bigint), n.[NUMBERSEQUENCE], NULLIF(sc.[DATAAREA], N''''), n.[TXT], CAST(n.[LOWEST] AS bigint), CAST(n.[HIGHEST] AS bigint), CAST(n.[NEXTREC] AS bigint), n.[FORMAT], ISNULL(n.[BLOCKED], 0), ISNULL(n.[CONTINUOUS], 0), ISNULL(n.[CYCLIC], 0), ISNULL(n.[MANUAL], 0), CASE WHEN EXISTS (SELECT 1 FROM [dbo].[NUMBERSEQUENCEREFERENCE] r WHERE r.[NUMBERSEQUENCEID] = n.[RECID]) THEN 1 ELSE 0 END, n.[LATESTCLEANDATETIME], CAST(NULL AS int), CAST(n.[CLEANINTERVAL] AS float), DATEDIFF(minute, GETDATE(), GETUTCDATE()) FROM [dbo].[NUMBERSEQUENCETABLE] n LEFT JOIN [dbo].[NUMBERSEQUENCESCOPE] sc ON sc.[RECID] = n.[NUMBERSEQUENCESCOPE] ORDER BY (CAST(n.[NEXTREC] AS float) - n.[LOWEST]) / NULLIF(CAST(n.[HIGHEST] AS float) - n.[LOWEST], 0) DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- -------------------------------------------------------------------------------------------------------------------
-- AxSequenceCollector: RecId pr. tabel og firma i AX-databasen (valgfri AX-læseadgang)
-- -------------------------------------------------------------------------------------------------------------------
-- Variant: Axapta 3.0 (skema bmssa, verificeret mod kundedata): RecId pr. tabel (SYSTEMSEQUENCES)
-- Kilde: AxSchemaAdapter.RecIds(3.0)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.RecIds(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (500) s.[TABID], s.[DATAAREAID], CAST(s.[NEXTVAL] AS bigint), CAST(s.[MAXVAL] AS bigint), (SELECT TOP 1 d.[NAME] FROM [bmssa].[SQLDICTIONARY] d WHERE d.[TABLEID] = s.[TABID] AND d.[FIELDID] = 0) FROM [bmssa].[SYSTEMSEQUENCES] s WHERE s.[NAME] = N''SEQNO'' ORDER BY s.[NEXTVAL] DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- Variant: AX 4.0 (skema dbo) - ikke verificeret mod kundedata: RecId pr. tabel (SYSTEMSEQUENCES)
-- Kilde: AxSchemaAdapter.RecIds(4.0)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.RecIds(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (500) s.[TABID], s.[DATAAREAID], CAST(s.[NEXTVAL] AS bigint), CAST(s.[MAXVAL] AS bigint), (SELECT TOP 1 d.[NAME] FROM [dbo].[SQLDICTIONARY] d WHERE d.[TABLEID] = s.[TABID] AND d.[FIELDID] = 0) FROM [dbo].[SYSTEMSEQUENCES] s WHERE s.[NAME] = N''SEQNO'' ORDER BY s.[NEXTVAL] DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- Variant: AX 2009 - baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: RecId pr. tabel (SYSTEMSEQUENCES)
-- Kilde: AxSchemaAdapter.RecIds(2009)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.RecIds(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (500) s.[TABID], s.[DATAAREAID], CAST(s.[NEXTVAL] AS bigint), CAST(s.[MAXVAL] AS bigint), (SELECT TOP 1 d.[NAME] FROM [dbo].[SQLDICTIONARY] d WHERE d.[TABLEID] = s.[TABID] AND d.[FIELDID] = 0) FROM [dbo].[SYSTEMSEQUENCES] s WHERE s.[NAME] = N''SEQNO'' ORDER BY s.[NEXTVAL] DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO
-- Variant: AX 2012 RTM/R2/R3 - baseret på Microsofts dokumenterede skema, ikke verificeret mod kundedata: RecId pr. tabel (SYSTEMSEQUENCES)
-- Kilde: AxSchemaAdapter.RecIds(2012)
-- Kode: src/SQLInsight.Core/DynamicsAx/AxSchemaAdapter.cs : AxSchemaAdapter.RecIds(database) via AxSql.InDatabase
EXEC [AXDB].sys.sp_executesql N'SET NOCOUNT ON; SET LOCK_TIMEOUT 2000; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SELECT TOP (500) s.[TABID], s.[DATAAREAID], CAST(s.[NEXTVAL] AS bigint), CAST(s.[MAXVAL] AS bigint), (SELECT TOP 1 d.[NAME] FROM [dbo].[SQLDICTIONARY] d WHERE d.[TABLEID] = s.[TABID] AND d.[FIELDID] = 0) FROM [dbo].[SYSTEMSEQUENCES] s WHERE s.[NAME] = N''SEQNO'' ORDER BY s.[NEXTVAL] DESC';
SET LOCK_TIMEOUT 5000; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO