IQDoc
ITIQPro Docs Maintenance Connection Everywhere (MCe) · EAM/CMMS manuals
PM Collation error
A temporary work-a-round

TL;DR

This is NOT a problem if you are on one of our SaaSs.

This is NOT a problem if you are using MCe to generate your automations including PMs.

This is NOT a problem if you have the Accruent REQUIRED SQL_Latin1_General_CP1_CI_AS collation. See also MC 2025 upgrade pre-requisites

Note this is NOT considered a bug, nor is it part of SMA because Accruent REQUIRES that you use the correct collation on your MS SQL Server and MC databases.

You have to have the required collation for the server, ent database(s) and reg database if you are using MC to any great degree.

If you are using/are willing to use MCe for any places you run into problems while running, then we have a fix that customers report works for the current MC 2025.

We may create fixes for other specific collation errors. These fixes may or may not work in future versions. Creating the fix does not make us responsible for a new fix - they are a 'buy time' to switch some users to MCe and/or a version of MC that doesn't have the specific issue.

We provide the following temporary work-a-round with no guarantees. Assistance in using this, installing this or debugging issues around it is Professional Services.

Having said that, we have had customers report 2026.07.23 that it does fix the Accruent MC collation issue for generating PMs when they are are set up with the wrong collation. We don't think it matters, but the collation it has been tested against is

How to install

You need to have admin level access to your Registration database. This is typically done through Microsoft SSMS, but your organization may use a different tool.

The registration database will have whatever name you pick, our default is usually 'registration_sa' or something similar to that. If you are unsure, you can run mcconfig.exe on your MC IIS server to determine the current name of your registration database.

From there you download the attached SQL file 2025 PM Collation Fix 1.sql

It contains 2 primary parts:

The script to install the procedure in your reg database
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
GO
 
CREATE OR ALTER PROCEDURE [dbo].[_MultiDBUpdate]
(
    @isql nvarchar(max),                        -- SQL to execute
    @DatabaseServerName nvarchar(max) = NULL   -- pass NULL to run on all database servers
)
AS
BEGIN
/*
 
Copyright 2026 ITIQPro.com, parts copyright Maintenance Connection Inc.
 
Why:
- PM execution depends on dbo._MultiDBUpdate in Registration DB.
- This patch applies explicit COLLATE handling in the server-name join.
 
- this is NOT covered by any SMA.
- Accrueent requires to have your MS SQL Server, reg database and ent database(s) set to SQL_Latin1_General_CP1_CI_AS to install and run MC properly
- ITIQPro, Maintenance Connection Canada, Asset Pro Solutions Inc. provides this with no warrantee as a TEMPORARY solution for
- customers who are set up with an unsupported (anything other than SQL_Latin1_General_CP1_CI_AS is unsupported) collation.
*/
    SET NOCOUNT ON;
 
    DECLARE @isql_orig nvarchar(max);
    SET @isql_orig = @isql;
 
    IF ISNULL(@isql_orig, '') = ''
    BEGIN
        -- No SQL to process.
        RETURN;
    END
 
    DECLARE DatabaseServerCursor CURSOR STATIC FOR
    SELECT
        cr.dbserver_name
    FROM (
        SELECT 'localhost' AS name
        UNION
        SELECT name
        FROM sys.servers
    ) a
    INNER JOIN (
        SELECT DISTINCT REPLACE(dbserver_name, '.accruentsystems.com', '') AS dbserver_name
        FROM container_resource
    ) cr
        ON a.name COLLATE SQL_Latin1_General_CP1_CI_AS = cr.dbserver_name COLLATE SQL_Latin1_General_CP1_CI_AS
    ORDER BY cr.dbserver_name;
 
    OPEN DatabaseServerCursor;
 
    DECLARE @DatabaseName nvarchar(max);
    DECLARE @CurrentDatabaseServerName nvarchar(max);
    DECLARE @ContainerGUID uniqueidentifier;
    DECLARE @ResourceGUID uniqueidentifier;
    DECLARE @SQLCmd nvarchar(max);
    DECLARE @SysDatabases nvarchar(max);
    DECLARE @DatabaseNameReplacement nvarchar(max);
 
    FETCH NEXT FROM DatabaseServerCursor INTO @CurrentDatabaseServerName;
 
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
        IF @DatabaseServerName IS NOT NULL AND @CurrentDatabaseServerName <> @DatabaseServerName
        BEGIN
            FETCH NEXT FROM DatabaseServerCursor INTO @CurrentDatabaseServerName;
            CONTINUE;
        END
 
        IF OBJECT_ID('tempdb.dbo.#DatabaseInfo') IS NOT NULL
            DROP TABLE #DatabaseInfo;
 
        CREATE TABLE #DatabaseInfo
        (
            ContainerGUID uniqueidentifier NOT NULL,
            ResourceGUID uniqueidentifier NOT NULL,
            DatabaseName nvarchar(max) NOT NULL
        );
 
        IF @CurrentDatabaseServerName = 'localhost'
            SET @SysDatabases = 'master.sys.databases';
        ELSE
            SET @SysDatabases = '[' + @CurrentDatabaseServerName + '].master.sys.databases';
 
        SET @SQLCmd =
            'INSERT #DatabaseInfo (ContainerGUID, ResourceGUID, DatabaseName) ' +
            'SELECT CR.container_guid, CR.resource_guid, TRIM(C.container_type_code) + TRIM(C.container_code) DatabaseName ' +
            'FROM container C ' +
            'JOIN container_resource CR ON (C.container_guid = CR.container_guid) ' +
            'WHERE TRIM(C.container_type_code) + TRIM(C.container_code) IN (SELECT [name] FROM ' + @SysDatabases + ') ' +
            'AND REPLACE(CR.dbserver_name,''.accruentsystems.com'','''') = ''' + @CurrentDatabaseServerName + ''' ' +
            'AND C.is_enabled = 1 AND CR.is_enabled = 1 ' +
            'ORDER BY DatabaseName;';
 
        EXEC (@SQLCmd);
 
        DECLARE DatabaseInfoCurs CURSOR LOCAL FOR
        SELECT ContainerGUID, ResourceGUID, DatabaseName
        FROM #DatabaseInfo
        ORDER BY DatabaseName;
 
        OPEN DatabaseInfoCurs;
        FETCH NEXT FROM DatabaseInfoCurs INTO @ContainerGUID, @ResourceGUID, @DatabaseName;
 
        WHILE (@@FETCH_STATUS = 0)
        BEGIN
            IF @CurrentDatabaseServerName = 'localhost'
                SET @DatabaseNameReplacement = @DatabaseName;
            ELSE
                SET @DatabaseNameReplacement = '[' + @CurrentDatabaseServerName + '].' + @DatabaseName;
 
            SET @isql = REPLACE(@isql_orig, '@dbname', @DatabaseNameReplacement);
            EXEC (@isql);
 
            FETCH NEXT FROM DatabaseInfoCurs INTO @ContainerGUID, @ResourceGUID, @DatabaseName;
        END
 
        CLOSE DatabaseInfoCurs;
        DEALLOCATE DatabaseInfoCurs;
 
        IF OBJECT_ID('tempdb.dbo.#DatabaseInfo') IS NOT NULL
            DROP TABLE #DatabaseInfo;
 
        FETCH NEXT FROM DatabaseServerCursor INTO @CurrentDatabaseServerName;
    END
 
    CLOSE DatabaseServerCursor;
    DEALLOCATE DatabaseServerCursor;
 
    RETURN 0;
END
GO

Then run the verification, this will check that it was installed in case, for example, you didn't have high enough privileges to run it and didn't notice the error message or the tool you used didn't present you with the error message or 'hid' it on another tab.

A verification script
/* Verification: confirm proc text includes explicit COLLATE */
SELECT OBJECT_SCHEMA_NAME(object_id) AS SchemaName,
       OBJECT_NAME(object_id) AS ProcedureName,
       definition
FROM sys.sql_modules
WHERE object_id = OBJECT_ID(N'dbo._MultiDBUpdate')
  AND definition LIKE '%COLLATE SQL_Latin1_General_CP1_CI_AS%';
GO