When is 'PROD' = 'Prod'? That answer, of course, is in T-SQL. By default, SQL server does not use case sensitivity when executing queries. If you want to perform a case-sensitive query in SQL server you need to do something like:
SELECT Caption FROM Nodes WHERE Caption = 'MYSQL' COLLATE SQL_Latin1_General_CP1_CS_AS
That COLLATE statement tells SQL server to look for MYSQL not MySQL or any other variation of that value. Why is this important? Here's my story.
While playing in my environment a few months ago I noticed that one of our custom properties for nodes (PROD_STATE) included what looked like duplicate entries. At least I knew that they were the same -- PROD and Prod. "Hmm, that's odd!" I thought to myself. I did a query against our DB (SELECT Caption, Prod_State FROM Nodes WHERE Prod_State = 'Prod' COLLATE SQL_Latin1_General_CP1_CS_AS) knowing that our standard was to use the PROD value. I found a few nodes that had used the 'Prod' value and I fixed them up. "No big deal," I thought, "I'll just remove the 'Prod' value from the Prod_State custom property." Then I remembered that ciulei told me that SQL was case insensitive. That was a problem. Would the delete function delete just the 'Prod' value or, because almost everything under the covers of Orion is a SQL query, would is delete both 'Prod' and 'PROD'? To the test lab!
The first thing we have to know is that where a custom property has a list value (you've made is a drop-down selection) that those values appear in the dbo.CustomPropertyValues table in your DB. The second thing you have to know is that the dbo.CustomPropertyValues.Value is set to SQL_Latin1_General_CP1_CI_AS. That would be CI (case-insensitive) and AS (accent sensitive). Third, the dbo.CustomPropertyValues table has no primary key. The TargetTable column tells you where the custom property is going to apply, the Name column tells you the name of the custom property and the Value column tells you the discrete values for the custom property. It is because of this that you can have both PROD and Prod in the same list.
(This screenshot is from a system running NPM 11.5 and Orion 2015.1.2 but the same condition existed in NPM 11.0.x and Orion 2014.x)
To test whether or not deleting the value from the Prod_State custom property via the UI would cause a problem I jumped into the Database Manager on our primary poller and ran this query:
SELECT TOP 1000 * FROM [dbo].[CustomPropertyValues]
WHERE Name = 'Prod_State'
AND Value = 'Prod'
Both rows (PROD and Prod) were returned. OK. Time to delete this via the UI. I flipped back to the Orion UI and went to Edit Custom Property for Prod_State and clicked next to the 'Prod' value. Uh-oh!
(For posterity purposes, in NPM 11.0.x and Orion 2014.x you do not get a prompt -- you just can't delete the value. This prompt is part of the Orion 2015.1.2 framework -- a welcome addition!)
I know that I don't have any nodes using the 'Prod' value but I do have 2 test nodes using the 'PROD' value. This confirms that the query being used to delete the values is not using the COLLATE SQL_Latin1_General_CP1_CS_AS. I confirmed that by jumping back to the Database Manager and running
DELETE FROM [dbo].[CustomPropertyValues]
WHERE Name = 'Prod_State'
AND Value = 'Prod'
It returns '2 row(s) affected'
So how do you delete the extraneous 'Prod' from the custom property list if you can't run a SQL query or use the UI? Well, you CAN use the UI but you have to know the secret. Remember when I said that the CustomPropertyValues table only contains values when the custom property is set to drop-down list? That is the key!
First, make sure that there are no nodes that are using the Prod_State = 'Prod' value by running the first query in this article:
SELECT Caption, Prod_State FROM Nodes WHERE Prod_State = 'Prod' COLLATE SQL_Latin1_General_CP1_CS_AS
If you find any, change them. This *very* important. You cannot have any nodes using the custom property value that you want to eliminate.
Second, go to Manage Custom Properties, select your custom property and click edit. You should see the offending duplicate values. Uncheck the 'Create a drop-down list of value for this property' check box and click submit.
This is a non-destructive change. You are not modifying the assigned values in the Nodes (Orion 2014) or NodesCustomProperties (Orion 2015) table at all you are simply removing the reference to CustomPropertyValues table. You can confirm that by running a query similar to the one below.
SELECT * FROM CustomPropertyValues WHERE Name = 'Prod_State'
Third, since we want to have a drop-down list to control the values in this custom property we need to go back to the Manage Custom Properties page, select our 'Prod_State' custom property, click edit, re-check the 'Create a drop-down list of values for this property' check box and click submit.
As this point you can either re-run the query above or edit the custom property again. Not only will the 'Prod' value be gone but so will any other 'Prod_State' value that was not assigned to node.
Here's what happened behind the scenes. When you check the 'Create a drop-down list...' checkbox Orion executes one of two queries (depending on the version of the Orion UI you are running):
SELECT DISTINCT(Prod_State) FROM Nodes
SELECT DISTINCT(Prod_State) FROM NodeCustomProperties
That query produces a list of unique values that are currently assigned to nodes. Now that you understand how the drop-down list works you can see it can be both extremely useful (clean up extraneous entries with "duplicate" names!) and a little dangerous too. (Did you pre-populate your list with 1000 assignment group names for incident routing then uncheck the box by accident? Bye-bye values.)
Hopefully our experience will help you understand more about how SQL works (by default), how Orion works and how you can leverage some of those idiosyncrasies to help you in your administrative duties.
Good luck and query safely!