-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapply_filter.sql
94 lines (83 loc) · 1.88 KB
/
apply_filter.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
DROP PROCEDURE IF EXISTS dbo.apply_filter;
GO
/*
* Procedure to filter any table based on JSON params in SQL
*/
CREATE PROCEDURE dbo.apply_filter (
@table NVARCHAR(255),
@params NVARCHAR(MAX),
@conjunction NVARCHAR(3) = 'AND'
)
AS
BEGIN
DECLARE @columns TABLE (
[name] NVARCHAR(255)
);
--
-- Step 1: Get the column list
--
INSERT INTO @columns
SELECT
column_name
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_NAME = @table;
DECLARE @param_table TABLE (
filter_key VARCHAR(255),
filter_value NVARCHAR(MAX)
);
--
-- Step 2: Parse the supplied JSON parameter
--
INSERT INTO @param_table (filter_key, filter_value)
SELECT
[key] AS filter_key,
[value] AS filter_value
FROM OPENJSON(@params);
DECLARE @invalid_keys NVARCHAR(MAX) = (
SELECT
STRING_AGG([name], ', ')
FROM (
SELECT [filter_key] AS [name] FROM @param_table
EXCEPT
SELECT [name] FROM @columns
) x
);
--
-- Step 3: Error handling for invalid columns in JSON
--
IF (@invalid_keys <> '')
BEGIN
DECLARE @e VARCHAR(MAX) = CONCAT(
'The source table does not have some filter key(s) that exist in the param: ',
@invalid_keys
);
THROW 51000, @e, 1;
END
--
-- Step 4: Generate dynamic SQL statement
--
DECLARE @sql NVARCHAR(MAX) =
N'SELECT ' + (
--
-- Append comma separated string of column names in @table
--
SELECT STRING_AGG([name], ',') FROM @columns
)
+ N' FROM ' + @table + ' s
WHERE ' + (
--
-- Generate and add the where clause based on
-- @param and @conjunction
--
SELECT
STRING_AGG(
' s.' + [filter_key] + ' = ''' + [filter_value] + ''' ',
@conjunction
)
FROM @param_table
);
-- Show the generated SQL query
PRINT @sql;
-- Execute the generated SQL query to get the filtered result set
EXEC sp_executesql @sql;
END