-- Migration: 047_CreateComplexTableFunctions -- Inline TVFs to extract complex object arrays from Search.Criteria JSON -- Pattern: CTE pre-filters valid JSON, OPENJSON...WITH for type-safe extraction -- fn_GetSearchComponentLots: Extract ComponentLotNumbers array of objects IF OBJECT_ID('dbo.fn_GetSearchComponentLots', 'IF') IS NOT NULL DROP FUNCTION dbo.fn_GetSearchComponentLots; GO CREATE FUNCTION dbo.fn_GetSearchComponentLots(@SearchId INT) RETURNS TABLE AS RETURN ( WITH ValidSearch AS ( SELECT Criteria FROM dbo.Search WHERE ID = @SearchId AND Criteria IS NOT NULL AND ISJSON(Criteria) = 1 ) SELECT j.LotNumber, j.ItemNumber FROM ValidSearch s CROSS APPLY OPENJSON(s.Criteria, '$.ComponentLotNumbers') WITH ( LotNumber VARCHAR(30) '$.LotNumber', ItemNumber VARCHAR(128) '$.ItemNumber' ) j ); GO -- fn_GetSearchPartOperations: Extract PartOperations array of objects IF OBJECT_ID('dbo.fn_GetSearchPartOperations', 'IF') IS NOT NULL DROP FUNCTION dbo.fn_GetSearchPartOperations; GO CREATE FUNCTION dbo.fn_GetSearchPartOperations(@SearchId INT) RETURNS TABLE AS RETURN ( WITH ValidSearch AS ( SELECT Criteria FROM dbo.Search WHERE ID = @SearchId AND Criteria IS NOT NULL AND ISJSON(Criteria) = 1 ) SELECT j.ItemNumber, j.OperationNumber, j.MisNumber, j.MisRevision FROM ValidSearch s CROSS APPLY OPENJSON(s.Criteria, '$.PartOperations') WITH ( ItemNumber VARCHAR(128) '$.ItemNumber', OperationNumber VARCHAR(10) '$.OperationNumber', MisNumber VARCHAR(10) '$.MisNumber', MisRevision VARCHAR(10) '$.MisRevision' ) j ); GO