SQL Server 2017 – How to Modify System Catalogs Directly

catalogslinuxsql serversql-server-2017system-tables

NOTE: I understand the risks involved, and the possibility of destroying a production system by doing this. I'm interested in doing it anyway.

Whenever I try to play with system catalogs, I gets these weird errors,

UPDATE sys.sql_logins
SET password_hash = PWDENCRYPT('pass')
WHERE name = 'sa';

Error produced,

Msg 259 […] Ad hoc updates to system catalogs are not allowed.

I've tried numerious ways to take the training wheels off,

sp_configure 'allow updates',`
go
reconfigure
go

But, I can't figure out the right option…

It even says in this answer:

this is no longer possible (at least not without jumping through a ton of additional hoops beyond just an sp_configure option – it's not something you ever want to do on a production system), and all of the system catalog is now exposed through read-only views like sys.objects.

Well, what if I want to jump through those hoops. How can I do it?

Best Answer

!!   BE SURE TO READ THE WARNING, IN BOLD, AT THE BOTTOM   !!

The server configuration option of allow updates was rendered non-functional starting in SQL Server 2005. The documentation states that it does not error, but won't actually allow for any direct updates to system catalog tables.

The only way to achieve this now, BEING FULLY AWARE THAT THIS IS DANGEROUS AND IS NOT RECOMMENDED, is to use a Dedicated Admin Console (DAC) connection.

First you will need the actual Table name that you want to update. The name that you SELECT from is just a system catalog View, not the real Table. I usually use the following:

EXEC sp_helptext N'sys.{some name here}';

Then, do the following:

  1. Restart the instance in Single-User mode with

    sudo systemctl stop mssql-server
    sudo -u mssql /opt/mssql/bin/sqlservr -m
    

    Just to be clear: this step is to allow for system catalog updates. Connecting to the DAC itself for doing other operations does not require Single-User mode.

  2. Connect via Dedicated Admin Console connection with sa or some other sysadmin Login. You can do this in a SQLCMD interactive session by running the following in a Command Prompt window:

    sqlcmd -S admin:localhost -U sa
    

    If the Linux SQLCMD doesn't support this for some reason, you can enable remote DAC connections and then later use a Windows machine to dug that DAC is working. You can enable DAC on Linux with,:

    EXEC sp_configure 'remote admin connections', 1;  
    RECONFIGURE;  
    
  3. In that DB, try something like the following:

    UPDATE sys.{whatever_name_you_found} {enter}
    SET [some_column] = {some_value} {enter}
    WHERE [some_other_column] = {the_better_be_correct_or_else_ID}; {enter}
    GO {enter}
    

    It won't execute the statement until you put in the GO {enter}.

DANGER WILL ROBINSON!!

Please be cautious when directly editing system catalog tables, and do not get too comfortable with the idea of doing it. This is something that should be done only if there is absolutely no other way of fixing a problem (such as the case here). There are probably several reasons to avoid making direct edits, but the two that initially come to mind are:

  • Much like the data-models that we create, there are likely rules and workflows for how things work that we are unaware of (e.g. denormalization, "business" rules governing the state of data across various tables, etc)
  • Quite likely making direct edits voids Microsoft's responsibility to assist you if you run into problems and have a support contract (I have not seen the terms of the Support agreement(s), but I have a hard time believing that such language would not be in there).

    @Paul Randal confirmed in a comment: "manually editing a system table irrevocably sets a flag in the boot page of the database that marks your database as having been edited in this way, and CSS might decide to not help you if you subsequently have problems with that database."