|
1 | | --- Compile Date: 04/24/2026 18:36:07 UTC |
| 1 | +-- Compile Date: 04/27/2026 23:04:36 UTC |
2 | 2 | SET ANSI_NULLS ON; |
3 | 3 | SET ANSI_PADDING ON; |
4 | 4 | SET ANSI_WARNINGS ON; |
@@ -17304,49 +17304,60 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
17304 | 17304 | column_name = c.name, |
17305 | 17305 | definition = cc.definition, |
17306 | 17306 | /* |
17307 | | - UDF detection: Looks for schema-qualified object references like [schema].[function] |
17308 | | - Note: This is a heuristic check and may have rare false positives if ].[ appears |
17309 | | - in string literals or comments within the computed column definition |
| 17307 | + UDF detection: Uses sys.sql_expression_dependencies, filtered to user-defined |
| 17308 | + function object types (FN, IF, TF, FS, FT). This avoids the false positives |
| 17309 | + the previous string-heuristic produced for schema-qualified type names, |
| 17310 | + system functions called as [sys].[fn_xxx](), and ].[ embedded in string |
| 17311 | + literals or comments. |
17310 | 17312 | */ |
17311 | 17313 | contains_udf = |
17312 | 17314 | CASE |
17313 | | - WHEN cc.definition LIKE ''%|].|[%'' ESCAPE ''|'' |
17314 | | - AND cc.definition LIKE ''%|].|[%(%'' ESCAPE ''|'' |
| 17315 | + WHEN refs.udf_names IS NOT NULL |
17315 | 17316 | THEN 1 |
17316 | 17317 | ELSE 0 |
17317 | 17318 | END, |
17318 | | - udf_names = |
17319 | | - CASE |
17320 | | - WHEN cc.definition LIKE ''%|].|[%'' ESCAPE ''|'' |
17321 | | - AND cc.definition LIKE ''%|].|[%(%'' ESCAPE ''|'' |
17322 | | - AND CHARINDEX(N''['', cc.definition) > 0 |
17323 | | - AND CHARINDEX(N''].['', cc.definition) > 0 |
17324 | | - AND CHARINDEX(N'']'', cc.definition, CHARINDEX(N''].['', cc.definition) + 3) > 0 |
17325 | | - THEN |
17326 | | - SUBSTRING |
17327 | | - ( |
17328 | | - cc.definition, |
17329 | | - CHARINDEX(N''['', cc.definition), |
17330 | | - CHARINDEX |
17331 | | - ( |
17332 | | - N'']'', |
17333 | | - cc.definition, |
17334 | | - CHARINDEX |
17335 | | - ( |
17336 | | - N''].['', |
17337 | | - cc.definition |
17338 | | - ) + 3 |
17339 | | - ) - |
17340 | | - CHARINDEX(N''['', cc.definition) + 1 |
17341 | | - ) |
17342 | | - ELSE NULL |
17343 | | - END |
| 17319 | + udf_names = refs.udf_names |
17344 | 17320 | FROM #filtered_objects AS fo |
17345 | 17321 | JOIN ' + QUOTENAME(@current_database_name) + N'.sys.columns AS c |
17346 | 17322 | ON fo.object_id = c.object_id |
17347 | 17323 | JOIN ' + QUOTENAME(@current_database_name) + N'.sys.computed_columns AS cc |
17348 | 17324 | ON c.object_id = cc.object_id |
17349 | 17325 | AND c.column_id = cc.column_id |
| 17326 | + OUTER APPLY |
| 17327 | + ( |
| 17328 | + SELECT |
| 17329 | + udf_names = |
| 17330 | + STUFF |
| 17331 | + ( |
| 17332 | + ( |
| 17333 | + SELECT |
| 17334 | + N'', '' + |
| 17335 | + QUOTENAME(s.name) + |
| 17336 | + N''.'' + |
| 17337 | + QUOTENAME(o.name) |
| 17338 | + FROM ' + QUOTENAME(@current_database_name) + N'.sys.sql_expression_dependencies AS sed |
| 17339 | + JOIN ' + QUOTENAME(@current_database_name) + N'.sys.objects AS o |
| 17340 | + ON o.object_id = sed.referenced_id |
| 17341 | + JOIN ' + QUOTENAME(@current_database_name) + N'.sys.schemas AS s |
| 17342 | + ON s.schema_id = o.schema_id |
| 17343 | + WHERE sed.referencing_id = cc.object_id |
| 17344 | + AND sed.referencing_minor_id = cc.column_id |
| 17345 | + AND sed.referencing_class = 1 |
| 17346 | + AND sed.referenced_class = 1 |
| 17347 | + AND o.type IN (N''FN'', N''IF'', N''TF'', N''FS'', N''FT'') |
| 17348 | + ORDER BY |
| 17349 | + s.name, |
| 17350 | + o.name |
| 17351 | + FOR |
| 17352 | + XML |
| 17353 | + PATH(N''''), |
| 17354 | + TYPE |
| 17355 | + ).value(''.'', ''nvarchar(max)''), |
| 17356 | + 1, |
| 17357 | + 2, |
| 17358 | + N'''' |
| 17359 | + ) |
| 17360 | + ) AS refs |
17350 | 17361 | OPTION(RECOMPILE);'; |
17351 | 17362 |
|
17352 | 17363 | IF @debug = 1 |
@@ -17401,46 +17412,56 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
17401 | 17412 | constraint_name = cc.name, |
17402 | 17413 | definition = cc.definition, |
17403 | 17414 | /* |
17404 | | - UDF detection: Looks for schema-qualified object references like [schema].[function] |
17405 | | - Note: This is a heuristic check and may have rare false positives if ].[ appears |
17406 | | - in string literals or comments within the computed column definition |
| 17415 | + UDF detection: Uses sys.sql_expression_dependencies, filtered to user-defined |
| 17416 | + function object types (FN, IF, TF, FS, FT). This avoids the false positives |
| 17417 | + the previous string-heuristic produced for schema-qualified type names, |
| 17418 | + system functions called as [sys].[fn_xxx](), and ].[ embedded in string |
| 17419 | + literals or comments. |
17407 | 17420 | */ |
17408 | 17421 | contains_udf = |
17409 | 17422 | CASE |
17410 | | - WHEN cc.definition LIKE ''%|].|[%'' ESCAPE ''|'' |
17411 | | - AND cc.definition LIKE ''%|].|[%(%'' ESCAPE ''|'' |
| 17423 | + WHEN refs.udf_names IS NOT NULL |
17412 | 17424 | THEN 1 |
17413 | 17425 | ELSE 0 |
17414 | 17426 | END, |
17415 | | - udf_names = |
17416 | | - CASE |
17417 | | - WHEN cc.definition LIKE ''%|].|[%'' ESCAPE ''|'' |
17418 | | - AND cc.definition LIKE ''%|].|[%(%'' ESCAPE ''|'' |
17419 | | - AND CHARINDEX(N''['', cc.definition) > 0 |
17420 | | - AND CHARINDEX(N''].['', cc.definition) > 0 |
17421 | | - AND CHARINDEX(N'']'', cc.definition, CHARINDEX(N''].['', cc.definition) + 3) > 0 |
17422 | | - THEN |
17423 | | - SUBSTRING |
17424 | | - ( |
17425 | | - cc.definition, |
17426 | | - CHARINDEX(N''['', cc.definition), |
17427 | | - CHARINDEX |
17428 | | - ( |
17429 | | - N'']'', |
17430 | | - cc.definition, |
17431 | | - CHARINDEX |
17432 | | - ( |
17433 | | - N''].['', |
17434 | | - cc.definition |
17435 | | - ) + 3 |
17436 | | - ) - |
17437 | | - CHARINDEX(N''['', cc.definition) + 1 |
17438 | | - ) |
17439 | | - ELSE NULL |
17440 | | - END |
| 17427 | + udf_names = refs.udf_names |
17441 | 17428 | FROM #filtered_objects AS fo |
17442 | 17429 | JOIN ' + QUOTENAME(@current_database_name) + N'.sys.check_constraints AS cc |
17443 | 17430 | ON fo.object_id = cc.parent_object_id |
| 17431 | + OUTER APPLY |
| 17432 | + ( |
| 17433 | + SELECT |
| 17434 | + udf_names = |
| 17435 | + STUFF |
| 17436 | + ( |
| 17437 | + ( |
| 17438 | + SELECT |
| 17439 | + N'', '' + |
| 17440 | + QUOTENAME(s.name) + |
| 17441 | + N''.'' + |
| 17442 | + QUOTENAME(o.name) |
| 17443 | + FROM ' + QUOTENAME(@current_database_name) + N'.sys.sql_expression_dependencies AS sed |
| 17444 | + JOIN ' + QUOTENAME(@current_database_name) + N'.sys.objects AS o |
| 17445 | + ON o.object_id = sed.referenced_id |
| 17446 | + JOIN ' + QUOTENAME(@current_database_name) + N'.sys.schemas AS s |
| 17447 | + ON s.schema_id = o.schema_id |
| 17448 | + WHERE sed.referencing_id = cc.object_id |
| 17449 | + AND sed.referencing_class = 1 |
| 17450 | + AND sed.referenced_class = 1 |
| 17451 | + AND o.type IN (N''FN'', N''IF'', N''TF'', N''FS'', N''FT'') |
| 17452 | + ORDER BY |
| 17453 | + s.name, |
| 17454 | + o.name |
| 17455 | + FOR |
| 17456 | + XML |
| 17457 | + PATH(N''''), |
| 17458 | + TYPE |
| 17459 | + ).value(''.'', ''nvarchar(max)''), |
| 17460 | + 1, |
| 17461 | + 2, |
| 17462 | + N'''' |
| 17463 | + ) |
| 17464 | + ) AS refs |
17444 | 17465 | OPTION(RECOMPILE);'; |
17445 | 17466 |
|
17446 | 17467 | IF @debug = 1 |
@@ -19645,7 +19666,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
19645 | 19666 | ), |
19646 | 19667 | table_name = N'brought to you by erikdarling.com', |
19647 | 19668 | index_name = N'for support: https://code.erikdarling.com/', |
19648 | | - consolidation_rule = N'run date: ' + CONVERT(nvarchar(30), SYSDATETIME(), 120), |
| 19669 | + consolidation_rule = |
| 19670 | + N'run date: ' + |
| 19671 | + CONVERT(nvarchar(30), SYSDATETIME(), 120) + |
| 19672 | + N' | ' + |
| 19673 | + CASE |
| 19674 | + WHEN @uptime_warning = 1 |
| 19675 | + THEN N'WARNING: Server uptime only ' + |
| 19676 | + @uptime_days + |
| 19677 | + N' days - usage data may be incomplete!' |
| 19678 | + ELSE N'Server uptime: ' + |
| 19679 | + @uptime_days + |
| 19680 | + N' days' |
| 19681 | + END, |
19649 | 19682 | script_type = N'Index Cleanup Scripts', |
19650 | 19683 | additional_info = N'A detailed index analysis report appears after these scripts', |
19651 | 19684 | target_index_name = N'ALWAYS TEST THESE RECOMMENDATIONS', |
|
0 commit comments