I think it's safe to say the or @parameters IS NOT NULL in SQL Server 2012 is a bug.
- SQL Server 2012 v11.0.6260.1 also has the erroneous code.
- SQL Server 2016 v13.0.4446.0 does not have that piece.
- SQL Server 2017 v14.0.3025.34 does not have that piece.
Furthermore, the code prevents sp_syscollector_validate_xml from being called for non-system collection sets.
Since the stored procedure appears to be a system-stored-procedure, you'll likely need to use sp_MS_marksystemobject to mark the stored procedure as a system-stored-procedure after you modify it to remove the or @parameters IS NOT NULL code.
Be aware that changing procedures that have been shipped by Microsoft may make support more difficult. I would recommend against making this change on production-critical instances.
For reference, the code as seen in my SQL Server 2012 instance is:
CREATE PROCEDURE [dbo].[sp_syscollector_update_collection_item]
@collection_item_id int = NULL,
@name sysname = NULL,
@new_name sysname = NULL,
@frequency int = NULL,
@parameters xml = NULL
AS
BEGIN
-- Security check (role membership)
IF (NOT (ISNULL(IS_MEMBER(N'dc_operator'), 0) = 1) AND NOT (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1))
BEGIN
RAISERROR(14677, -1, -1, 'dc_operator')
RETURN(1) -- Failure
END
-- Security checks (restrict functionality for non-dc_admin-s)
IF ((NOT (ISNULL(IS_MEMBER(N'dc_admin'), 0) = 1) AND NOT (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1))
AND (@new_name IS NOT NULL))
BEGIN
RAISERROR(14676, -1, -1, '@new_name', 'dc_admin')
RETURN (1) -- Failure
END
IF ((NOT (ISNULL(IS_MEMBER(N'dc_admin'), 0) = 1) AND NOT (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1))
AND (@parameters IS NOT NULL))
BEGIN
RAISERROR(14676, -1, -1, '@parameters', 'dc_admin')
RETURN (1) -- Failure
END
DECLARE @retVal int
EXEC @retVal = dbo.sp_syscollector_verify_collection_item @collection_item_id OUTPUT, @name OUTPUT
IF (@retVal <> 0)
RETURN (@retVal)
IF (@frequency < 5)
BEGIN
DECLARE @frequency_as_char VARCHAR(36)
SELECT @frequency_as_char = CONVERT(VARCHAR(36), @frequency)
RAISERROR(21405, 16, -1, @frequency_as_char, '@frequency', 5)
RETURN (1)
END
IF (LEN(@new_name) = 0) -- can't rename to an empty string
BEGIN
RAISERROR(21263, -1, -1, '@new_name')
RETURN(1) -- Failure
END
-- Remove any leading/trailing spaces from parameters
SET @new_name = LTRIM(RTRIM(@new_name))
DECLARE @collection_set_name sysname
DECLARE @is_system bit
DECLARE @is_running bit
DECLARE @collector_type_uid uniqueidentifier
DECLARE @collection_set_id int
SELECT @is_running = s.is_running,
@is_system = s.is_system,
@collection_set_name = s.name,
@collector_type_uid = i.collector_type_uid,
@collection_set_id = s.collection_set_id
FROM dbo.syscollector_collection_sets s,
dbo.syscollector_collection_items i
WHERE s.collection_set_id = i.collection_set_id
AND i.collection_item_id = @collection_item_id
IF (@is_system = 1 AND (@new_name IS NOT NULL OR @parameters IS NOT NULL))
BEGIN
-- cannot update, delete, or add new collection items to a system collection set
RAISERROR(14696, -1, -1);
RETURN (1)
END
IF (@parameters IS NOT NULL)
BEGIN
EXEC @retVal = dbo.sp_syscollector_validate_xml @collector_type_uid = @collector_type_uid, @parameters = @parameters
IF (@retVal <> 0)
RETURN (@retVal)
END
-- if the collection item is running, stop it before update
IF (@is_running = 1)
BEGIN
EXEC @retVal = sp_syscollector_stop_collection_set @collection_set_id = @collection_set_id
IF (@retVal <> 0)
RETURN(1)
END
-- all conditions go, perform the update
EXEC @retVal = sp_syscollector_update_collection_item_internal
@collection_item_id = @collection_item_id,
@name = @name,
@new_name = @new_name,
@frequency = @frequency,
@parameters = @parameters
-- if you stopped the collection set, restart it
IF (@is_running = 1)
BEGIN
EXEC @retVal = sp_syscollector_start_collection_set @collection_set_id = @collection_set_id
IF (@retVal <> 0)
RETURN (1)
END
RETURN (0)
END
The code in SQL Server 2016 is:
CREATE PROCEDURE [dbo].[sp_syscollector_update_collection_item]
@collection_item_id int = NULL,
@name sysname = NULL,
@new_name sysname = NULL,
@frequency int = NULL,
@parameters xml = NULL
AS
BEGIN
-- Security check (role membership)
IF (NOT (ISNULL(IS_MEMBER(N'dc_operator'), 0) = 1) AND NOT (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1))
BEGIN
RAISERROR(14677, -1, -1, 'dc_operator')
RETURN(1) -- Failure
END
-- Security checks (restrict functionality for non-dc_admin-s)
IF ((NOT (ISNULL(IS_MEMBER(N'dc_admin'), 0) = 1) AND NOT (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1))
AND (@new_name IS NOT NULL))
BEGIN
RAISERROR(14676, -1, -1, '@new_name', 'dc_admin')
RETURN (1) -- Failure
END
IF ((NOT (ISNULL(IS_MEMBER(N'dc_admin'), 0) = 1) AND NOT (ISNULL(IS_MEMBER(N'db_owner'), 0) = 1))
AND (@parameters IS NOT NULL))
BEGIN
RAISERROR(14676, -1, -1, '@parameters', 'dc_admin')
RETURN (1) -- Failure
END
DECLARE @retVal int
EXEC @retVal = dbo.sp_syscollector_verify_collection_item @collection_item_id OUTPUT, @name OUTPUT
IF (@retVal <> 0)
RETURN (@retVal)
IF (@frequency < 5)
BEGIN
DECLARE @frequency_as_char VARCHAR(36)
SELECT @frequency_as_char = CONVERT(VARCHAR(36), @frequency)
RAISERROR(21405, 16, -1, @frequency_as_char, '@frequency', 5)
RETURN (1)
END
IF (LEN(@new_name) = 0) -- can't rename to an empty string
BEGIN
RAISERROR(21263, -1, -1, '@new_name')
RETURN(1) -- Failure
END
-- Remove any leading/trailing spaces from parameters
SET @new_name = LTRIM(RTRIM(@new_name))
DECLARE @collection_set_name sysname
DECLARE @is_system bit
DECLARE @is_running bit
DECLARE @collector_type_uid uniqueidentifier
DECLARE @collection_set_id int
SELECT @is_running = s.is_running,
@is_system = s.is_system,
@collection_set_name = s.name,
@collector_type_uid = i.collector_type_uid,
@collection_set_id = s.collection_set_id
FROM dbo.syscollector_collection_sets s,
dbo.syscollector_collection_items i
WHERE s.collection_set_id = i.collection_set_id
AND i.collection_item_id = @collection_item_id
IF (@is_system = 1 AND (@new_name IS NOT NULL))
BEGIN
-- cannot update, delete, or add new collection items to a system collection set
RAISERROR(14696, -1, -1);
RETURN (1)
END
IF (@parameters IS NOT NULL)
BEGIN
EXEC @retVal = dbo.sp_syscollector_validate_xml @collector_type_uid = @collector_type_uid, @parameters = @parameters
IF (@retVal <> 0)
RETURN (@retVal)
END
-- if the collection item is running, stop it before update
IF (@is_running = 1)
BEGIN
EXEC @retVal = sp_syscollector_stop_collection_set @collection_set_id = @collection_set_id
IF (@retVal <> 0)
RETURN(1)
END
-- all conditions go, perform the update
EXEC @retVal = sp_syscollector_update_collection_item_internal
@collection_item_id = @collection_item_id,
@name = @name,
@new_name = @new_name,
@frequency = @frequency,
@parameters = @parameters
-- if you stopped the collection set, restart it
IF (@is_running = 1)
BEGIN
EXEC @retVal = sp_syscollector_start_collection_set @collection_set_id = @collection_set_id
IF (@retVal <> 0)
RETURN (1)
END
RETURN (0)
END