As another use case, rather than just storing the values for later use by another BP, I'm using JSON to pass values to a SQL proc that performs extensive validation on the form data. Trying to use Retrieve Business Process Variables to pass table values to SQL did not end well.
An activity that, given the Forms server and Instance, simply outputs JSON of all current variable values would be ideal. Especially if it would work without having to select a BP.
I ended up writing a SQL proc to build the JSON from the Forms database, which is probably a terrible idea. It's working well for me so far, but I'm sure there are things not being handled correctly (e.g. collections? I haven't used those much).
-- ================================================================================================
-- Author: Scott Minar
-- Create date: 2018-08-10
-- Description: Constructs JSON with all values from an instance
-- /*==============================================================================================
ALTER PROC [forms].[VariableValues_json] (
@instance INT
) AS
SET NOCOUNT ON
--*/
/*
DECLARE @instance INT = 44983;
--*/
DROP TABLE IF EXISTS #members;
SELECT
*
INTO #members
FROM (
SELECT
mi.bp_instance_id
,s.submission_id
,f.form_id
,ds.attribute_type
,ds.member_id
,m.parent_entity_id
,m.entity_associated_id
,m.[name]
,d.[value]
,d.member_path
,rn = ROW_NUMBER() OVER(PARTITION BY d.member_path ORDER BY s.date_created DESC)
FROM LF_Forms.dbo.cf_bp_main_instances mi
INNER JOIN LF_Forms.dbo.cf_submissions s
ON mi.bp_instance_id = s.bp_instance_id
INNER JOIN LF_Forms.dbo.cf_form_submissions fs
ON s.submission_id = fs.submission_id
INNER JOIN LF_Forms.dbo.cf_bp_step_form_mapping sfm
ON mi.process_id = sfm.process_id
AND fs.step_id = sfm.step_id
INNER JOIN LF_Forms.dbo.cf_fields f
ON sfm.form_id = f.form_id
AND f.[type] <> 'table-end'
INNER JOIN LF_Forms.dbo.cf_bp_dataset ds
ON f.attribute_id = ds.attribute_id
INNER JOIN LF_Forms.dbo.members m
ON ds.member_id = m.id
INNER JOIN LF_Forms.dbo.cf_bp_data d
ON fs.submission_id = d.submission_id
AND f.attribute_id = d.attribute_id
WHERE mi.bp_instance_id = @instance
) x
WHERE rn = 1
;
INSERT INTO #members (bp_instance_id,submission_id,form_id,parent_entity_id,[name],[value]) VALUES (@instance,0,0,0,'Instance',@instance);
SELECT [json] = '{' + STUFF((
SELECT
',"' + [name] + '":' + CASE attribute_type
WHEN 'table' THEN
'[' + stuff((
SELECT
',{' + stuff((
SELECT
',"' + [name] + '":"' + STRING_ESCAPE([value],'json') + '"'
FROM (
SELECT
[name]
,[value]
,member_path
FROM #members
UNION ALL
SELECT
'Entry'
,x.[entry]
,p.member_path + x.[entry] + '.0'
) d
WHERE member_path LIKE p.member_path + x.[entry] + '.%'
AND NULLIF([value],'') IS NOT NULL
FOR XML PATH(''), TYPE
).value('.','VARCHAR(MAX)'),1,1,'') + '}'
FROM #members m
INNER JOIN #members p
ON m.parent_entity_id = p.entity_associated_id
CROSS APPLY (VALUES
(LEFT(REPLACE(m.member_path,p.member_path,''),CHARINDEX('.',REPLACE(m.member_path,p.member_path,'')) - 1))
) x ([entry])
WHERE p.member_path = o.member_path
GROUP BY p.member_path
,x.[entry]
FOR XML PATH(''), TYPE
).value('.','VARCHAR(MAX)'),1,1,'') + ']'
ELSE '"' + STRING_ESCAPE([value],'json') + '"' END
FROM #members o
WHERE NULLIF([value],'') IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM #members
WHERE entity_associated_id = o.parent_entity_id
)
FOR XML PATH(''), TYPE
).value('.','VARCHAR(MAX)'),1,1,'') + '}'
;