Files
Stefan 10ecdfa2e4 Add Fuchs_Database SSDT project (schema source of truth)
Adds the SQL Server Data Tools project for the fuchs_fds database — tables,
table types, functions and stored procedures that the backend calls (e.g.
fds__getInvoice, fds__merge_bankingtransactions, fds__tt__bankingtransactions,
fds__admin_getReportCatalog, fis_* auth). Build/model caches (bin, obj,
*.dbmdl, *.jfm, *.user) are git-ignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 14:50:54 +02:00

112 lines
3.6 KiB
Transact-SQL

CREATE FUNCTION [dbo].[json_diffObjectArrays] (@SourceJSON NVARCHAR(MAX), @TargetJSON NVARCHAR(MAX), @uniquekey varchar(50) )
/**
Summary: >
This function 'diffs' a source JSON document with a target JSON document and produces an
analysis of which properties are missing in either the source or target, or the values
of these properties that are different. It reports on the properties and values for
both source and target as well as the path that references that scalar value. The
path reference to the object's parent is exposed in the result to enable a query to
reference the value of any other object in the parent that is needed.
Author: Phil Factor
Date: 06/07/2020
Revised:
- mod: Added the parent reference to the difference report
- Date: 09/07/2020
Database: PhilsRoutines
Examples:
- SELECT * FROM dbo.Compare_JsonObject(@TheSourceJSON, @TheTargetJSON)
WHERE SideIndicator <> '==';
- SELECT *, Json_Value(@TheSourceJSON,TheParent+'.name')
FROM dbo.Compare_JsonObject(@TheSourceJSON, @TheTargetJSON)
WHERE SideIndicator <> '==';
Returns: >
SideIndicator: ( == equal, <- not in target, -> not in source, <> not equal
ThePath: the JSON path used by the SQL JSON functions
TheKey: the key field without the path
TheSourceValue: the value IN the SOURCE JSON document
TheTargetValue: the value IN the TARGET JSON document
**/
RETURNS @returntable TABLE
(
[equal] [bit],
[action] smallint,
[uid] varchar(100),
[diff] nvarchar(max)
)
AS
BEGIN
DECLARE @objects TABLE (
[uid] varchar(100),
[json] NVARCHAR(MAX)
)
INSERT INTO @objects ([uid], [json])
SELECT JSON_VALUE(j.[Value], '$.' + @uniquekey), [value]
FROM OpenJson(@TargetJSON) as j
WHERE type IN (4,5);
DECLARE @intermediate TABLE
(
[equal] [bit],
[SideIndicator] CHAR(2), -- == means equal, <- means not in target, -> means not in source, <> means not equal
[UID] varchar(100),
[parent] VARCHAR(2000), -- the parent object
[path] VARCHAR(2000), -- the JSON path used by the SQL JSON functions
[key] VARCHAR(255), -- the key field without the path
[SourceValue] NVARCHAR(max), -- the value IN the SOURCE JSON document
[TargetValue] NVARCHAR(max) -- the value IN the TARGET JSON document
)
INSERT INTO @intermediate
SELECT * FROM [dbo].[json_compareObjectArrays](@SourceJSON, @TargetJSON, @uniquekey);
WITH d as(
SELECT
[UID]
, [total] = SUM(1)
, [LEFT] = SUM(IIF([sideindicator] = '<-',1,0))
, [RIGHT] = SUM(IIF([sideindicator] = '->',1,0))
, [inequal] = SUM(IIF(i.[equal] = 1,0,1))
FROM @intermediate as i
GROUP BY [UID]
)
INSERT INTO @returntable
SELECT
[equal] = IIF([inequal] = 0, 1 ,0)
, CASE WHEN [total] = [RIGHT] THEN 2
WHEN [total] = [LEFT] THEN -1
WHEN [inequal] > 0 THEN 1
ELSE 0 END
, ISNULL(o.[uid], d.[UID])
, [j] = IIF([inequal] = 0, '{}' , --( SELECT [key] = im.[theKey], [val] = im.[TheTargetValue] FROM @intermediate as im WHERE im.[UID] = d.[UID] AND im.equal = 0 FOR JSON PATH, WITHOUT_ARRAY_WRAPPER )
o.[json]
)
FROM d
FULL OUTER JOIN @objects as o ON d.[UID] = o.[uid]
DECLARE @uid varchar(100), @key varchar(100);
DECLARE im_cursor CURSOR FOR
SELECT [uid], [key]
FROM @intermediate
WHERE [SideIndicator] in ('==');
OPEN im_cursor
FETCH NEXT FROM im_cursor INTO @uid, @key;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE o
SET o.[diff] = JSON_MODIFY(o.[diff], '$.' + @key, null)
FROM @returntable as o
WHERE [uid] = @uid;
FETCH NEXT FROM im_cursor INTO @uid, @key;
END
CLOSE im_cursor ;
DEALLOCATE im_cursor;
RETURN;
END;