Skip to content

Commit 9144b8d

Browse files
committed
Update helper_script_for_adding_schemabinding_to_scalar_functions.sql
1 parent b0ae4e0 commit 9144b8d

1 file changed

Lines changed: 50 additions & 23 deletions

File tree

Utility Scripts/helper_script_for_adding_schemabinding_to_scalar_functions.sql

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ The script ignores the following functions:
99
- Self-referencing functions.
1010
- Functions that contain code that uses sp_executesql or OLE Automation procedures.
1111
- Functions in schemas "sys" and "tSQLt".
12+
- Functions that use OPENROWSET or OPENQUERY
1213
- Functions dependent on synonyms (can be disabled by setting @IgnoreFunctionsDependentOnSynonyms to 0)
1314
- Functions that have constraints dependent on them (can be disabled by setting @IgnoreFunctionsWithConstraintDependencies to 0)
1415
- Functions dependent on linked servers (can be disabled by setting @IgnoreFunctionsDependentOnLinkedServers to 0)
16+
- Functions dependent on objects in other databases (can be disabled by setting @IgnoreFunctionsWithCrossDatabaseDependencies to 0)
1517
- Functions referencing functions fitting any of the above criteria (recursive).
1618
1719
Instructions:
@@ -33,6 +35,9 @@ DECLARE
3335
,@IgnoreFunctionsDependentOnSynonyms BIT = 1 -- optionally filter out functions that depend on synonyms (cannot be schemabound)
3436
,@IgnoreFunctionsWithConstraintDependencies BIT = 1 -- optionally filter out functions that have constraints dependant on them (cannot be altered)
3537
,@IgnoreFunctionsDependentOnLinkedServers BIT = 0 -- optionally filter out functions that possibly depend on linked servers (cannot be schemabound)
38+
,@IgnoreFunctionsWithTableValuedParameters BIT = 1 -- optionally filter out functions that have table-valued parameters (cannot be schemabound)
39+
,@IgnoreFunctionsWithCrossDatabaseDependencies BIT = 1 -- optionally filter out functions that depend on objects in another database (cannot be schemabound)
40+
,@EnableRecursiveCheck BIT = 1 -- optionally perform recursive exclusions (i.e. exclude functions that depend on excluded functions). Beware of infinite recursion here!
3641

3742
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
3843
SET NOCOUNT ON;
@@ -56,37 +61,44 @@ SET @CMD_Template = N'WITH Exclusions AS
5661
('
5762
-- exclude modules invalid for schemabinding
5863
+ N'
59-
SELECT d.referenced_major_id AS object_id
64+
SELECT d.object_id
6065
from sys.sql_dependencies AS d
61-
WHERE OBJECTPROPERTY(d.referenced_major_id, ''IsScalarFunction'') = 1 AND (
66+
WHERE OBJECTPROPERTY(d.object_id, ''IsScalarFunction'') = 1 AND (
6267
d.referenced_major_id = d.object_id
63-
OR OBJECT_DEFINITION(d.referenced_major_id) LIKE N''%sp_OACreate%sp_OA%''
64-
OR LOWER(OBJECT_DEFINITION(d.referenced_major_id)) LIKE N''%exec%sp_executesql%''
65-
OR OBJECT_SCHEMA_NAME(d.referenced_major_id) IN (''tSQLt'',''sys'')
68+
OR OBJECT_DEFINITION(d.object_id) LIKE N''%sp_OACreate%sp_OA%''
69+
OR LOWER(OBJECT_DEFINITION(d.object_id)) LIKE N''%exec%sp_executesql%''
70+
OR LOWER(OBJECT_DEFINITION(d.object_id)) LIKE N''%OPENROWSET%''
71+
OR LOWER(OBJECT_DEFINITION(d.object_id)) LIKE N''%OPENQUERY%''
72+
OR OBJECT_SCHEMA_NAME(d.object_id) IN (''tSQLt'',''sys'')
6673
)
6774
UNION ALL
68-
select d.referenced_id
75+
select d.referencing_id
6976
from sys.sql_expression_dependencies AS d
70-
WHERE OBJECTPROPERTY(d.referenced_id, ''IsScalarFunction'') = 1 AND (
77+
WHERE OBJECTPROPERTY(d.referencing_id, ''IsScalarFunction'') = 1 AND (
7178
d.referencing_id = d.referenced_id
72-
OR OBJECT_DEFINITION(d.referenced_id) LIKE N''%sp_OACreate%sp_OA%''
73-
OR LOWER(OBJECT_DEFINITION(d.referenced_id)) LIKE N''%exec%sp_executesql%''
74-
OR OBJECT_SCHEMA_NAME(d.referenced_id) IN (''tSQLt'',''sys'')
75-
)'
79+
OR OBJECT_DEFINITION(d.referencing_id) LIKE N''%sp_OACreate%sp_OA%''
80+
OR LOWER(OBJECT_DEFINITION(d.referencing_id)) LIKE N''%exec%sp_executesql%''
81+
OR LOWER(OBJECT_DEFINITION(d.referencing_id)) LIKE N''%OPENROWSET%''
82+
OR LOWER(OBJECT_DEFINITION(d.referencing_id)) LIKE N''%OPENQUERY%''
83+
OR OBJECT_SCHEMA_NAME(d.referencing_id) IN (''tSQLt'',''sys'')' +
84+
CASE WHEN @IgnoreFunctionsWithCrossDatabaseDependencies = 1 THEN CONVERT(nvarchar(max), N'
85+
OR d.referenced_database_name <> DB_NAME()')
86+
ELSE N''
87+
END + N')'
7688
-- dependant on synonyms
77-
+ CASE WHEN @IgnoreFunctionsDependentOnSynonyms = 1 THEN N'
89+
+ CASE WHEN @IgnoreFunctionsDependentOnSynonyms = 1 THEN CONVERT(nvarchar(max), N'
7890
UNION ALL
7991
select d.object_id
8092
from sys.sql_dependencies AS d
8193
INNER JOIN sys.synonyms AS syn ON d.referenced_major_id = syn.object_id
8294
UNION ALL
8395
select d.referencing_id
8496
from sys.sql_expression_dependencies AS d
85-
INNER JOIN sys.synonyms AS syn ON d.referenced_id = syn.object_id'
97+
INNER JOIN sys.synonyms AS syn ON d.referenced_id = syn.object_id')
8698
ELSE N''
8799
END
88100
-- has constraint dependencies
89-
+ CASE WHEN @IgnoreFunctionsWithConstraintDependencies = 1 THEN N'
101+
+ CASE WHEN @IgnoreFunctionsWithConstraintDependencies = 1 THEN CONVERT(nvarchar(max), N'
90102
UNION ALL
91103
select d.referenced_major_id
92104
from sys.sql_dependencies AS d
@@ -96,11 +108,21 @@ UNION ALL
96108
select d.referenced_id
97109
from sys.sql_expression_dependencies AS d
98110
INNER JOIN sys.sysconstraints AS con ON d.referencing_id = con.constid
99-
WHERE OBJECTPROPERTY(d.referenced_id, ''IsScalarFunction'') = 1'
111+
WHERE OBJECTPROPERTY(d.referenced_id, ''IsScalarFunction'') = 1')
112+
ELSE N''
113+
END
114+
-- Has table-valued parameters
115+
+ CASE WHEN @IgnoreFunctionsWithTableValuedParameters = 1 THEN CONVERT(nvarchar(max), N'
116+
UNION ALL
117+
SELECT p.object_id
118+
FROM sys.parameters AS p
119+
INNER JOIN sys.types AS t ON p.user_type_id = t.user_type_id AND p.system_type_id = t.system_type_id
120+
WHERE t.is_table_type = 1
121+
')
100122
ELSE N''
101123
END
102124
-- Recursive depdendencies
103-
+ N'
125+
+ CONVERT(nvarchar(max), N'
104126
), ExclusionTree1 AS
105127
(
106128
select d.object_id
@@ -114,10 +136,9 @@ from sys.sql_dependencies AS d
114136
INNER JOIN ExclusionTree1 AS Tree ON d.referenced_major_id = Tree.object_id
115137
WHERE OBJECTPROPERTY(d.referenced_major_id, ''IsScalarFunction'') = 1
116138
AND d.referenced_major_id <> d.object_id
117-
)'
139+
)')
118140
-- Recursive expression-based dependencies
119-
/*
120-
+ N'
141+
+ CONVERT(nvarchar(max), N'
121142
, ExclusionTree2 AS
122143
(
123144
select d.referencing_id AS object_id
@@ -129,8 +150,8 @@ select d.referencing_id
129150
from sys.sql_expression_dependencies AS d
130151
INNER JOIN ExclusionTree2 AS Tree ON d.referenced_id = Tree.object_id
131152
WHERE d.referencing_id <> d.referenced_id
132-
)'*/
133-
+ N'
153+
)')
154+
+ CONVERT(nvarchar(max), N'
134155
SELECT DB_NAME(), OBJECT_SCHEMA_NAME(OB.id), OB.name, MO.[definition]
135156
, HasDependencies = CASE WHEN EXISTS
136157
(
@@ -173,11 +194,17 @@ AND OB.type = ''FN''
173194
AND MO.is_schema_bound = 0
174195
WHERE MO.definition NOT LIKE N''%sp_OACreate%sp_OA%''
175196
AND LOWER(MO.definition) NOT LIKE N''%exec%sp_executesql%''
197+
AND LOWER(MO.definition) NOT LIKE N''%OPENROWSET%''
198+
AND LOWER(MO.definition) NOT LIKE N''%OPENQUERY%''
176199
AND OB.name NOT IN (''fn_diagramobjects'')
177200
AND OBJECT_SCHEMA_NAME(OB.id) NOT IN (''tSQLt'',''sys'')
178201
AND OB.id NOT IN (select object_id FROM Exclusions)
179-
AND OB.id NOT IN (select object_id FROM ExclusionTree1)
180-
OPTION(MAXRECURSION 100)'
202+
AND OB.id NOT IN (select object_id FROM ExclusionTree1)'
203+
+ CASE WHEN @EnableRecursiveCheck = 1 THEN CONVERT(nvarchar(max), N'
204+
AND OB.id NOT IN (select object_id FROM ExclusionTree2)')
205+
ELSE N''
206+
END + N'
207+
OPTION(MAXRECURSION 1000)')
181208

182209
IF CONVERT(int, SERVERPROPERTY('EngineEdition')) = 5 -- Azure SQL DB
183210
BEGIN

0 commit comments

Comments
 (0)