如何将默认数据库更改为所有登录名?

Ric*_*rno 6 sql-server t-sql logins

我对 SQL Server 有点陌生,我正在尝试编写 Microsoft SQL Server (2005-2014) 安装后活动的脚本,但我在更改登录时遇到了一些困难。公司政策规定没有登录应该默认使用 master 数据库,因此我的计划是识别所有默认使用 master 的登录并将 master 更改为 tempdb。

可以使用这样的查询更改单次登录:

ALTER LOGIN [sa] WITH DEFAULT_DATABASE = tempdb
Run Code Online (Sandbox Code Playgroud)

试图在所有登录中实现这一点(不知道它们的数量和名称),我知道我很天真,希望这样的事情会起作用(但不得不尝试):

UPDATE master..syslogins
SET dbname = 'tempdb'
WHERE dbname = 'master'
Run Code Online (Sandbox Code Playgroud)

显然输出是一个错误(逻辑上):

Ad hoc updates to system catalogs are not allowed.

SQL Server 处于 MIX 身份验证模式,因此几乎所有内容都可以登录 - SQL 登录、Windows 本地或域用户或组(不确定这是否会对解决方案产生任何影响)。解决方案应该与版本无关,但是假设从 SQL Server 2005 向前启动(...是的,仍然有一些古老的版本...)

任何人都可以帮我找到合适的查询来实现这一目标吗?

小智 5

您永远不应该尝试直接更新系统表,在大多数情况下,它不会像您发现的那样让您这样做。

在您的情况下,您将需要为ALTER LOGIN不知道实例上有多少个的动态语句构建。但是,您在执行此操作时需要谨慎,以确保不会触碰您不应该触碰的登录信息。此查询应该为您提供那些“非默认”或通过安装过程安装的登录名:

SELECT name
FROM sys.server_principals
WHERE type <> 'R'
    AND name NOT LIKE '##%' --Exclude policy based accounts
    AND name NOT LIKE 'NT%' --Exclude system accounts
    AND sid <> 0x01 --exclude the sa
Run Code Online (Sandbox Code Playgroud)

由此,您只需要构建您的语句以通过sp_executesql. 您可以根据自己的喜好使用简单的游标或 while 循环,下面是我随身携带的仅用于基本游标的模板:

DECLARE @v1 VARCHAR(50)

DECLARE v_cursor CURSOR FOR  
/* Query of data to iterate through */ 

OPEN v_cursor  
FETCH NEXT FROM v_cursor INTO @v1   

WHILE @@FETCH_STATUS = 0   
BEGIN   
    /* build your dynamic statement */
    /* Use @v1 within query to perform action on each row */
    FETCH NEXT FROM v_cursor INTO @v1   
END   

CLOSE v_cursor   
DEALLOCATE v_cursor;
Run Code Online (Sandbox Code Playgroud)