10ecdfa2e4
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>
112 lines
3.6 KiB
Transact-SQL
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; |