数据库创建存储过程

问题 ( The Problem )

This problem demonstrates a very common scenario. When a backed up database is restored to a different location or server, the restored database users that exist inside of it, lose their association to the new server login objects.

此问题说明了一个非常常见的情况。 将备份的数据库还原到其他位置或服务器时,其中存在的还原的数据库用户将失去与新服务器登录对象的关联。

This problem occurs because the server id in the user data is still the old server and must be changed to the new one.

发生此问题的原因在用户数据中的服务器ID仍然是旧服务器,并且必须更改为新服务器。

The DBA task is then to restore the connection between the login and the database user object and to link them together again.

然后,DBA的任务是恢复登录名和数据库用户对象之间的连接,并将它们再次链接在一起。

为什么会出现此问题? ( Why does this Problem occur? )

This problem occur because of the fact that when we are migrating the database to a new server, by using the BACKUP DATABASE and RESTORE DATABASE statements (or by other methods), the relationship between the login object and database user object can break.

出现此问题的原因是,当我们将数据库迁移到新服务器时,通过使用BACKUP DATABASERESTORE DATABASE语句(或通过其他方法),登录对象和数据库用户对象之间的关系可能会中断。

The login object has a security identifier called SID, which uniquely identifies it on the specific SQL server instance. This SID column is placed, as a foreign key value, at the login’s associated database user, in each database that the login has access and is a member of.

登录对象具有一个称为SID的安全标识符,该标识符在特定SQL Server实例上唯一地对其进行标识。 此SID列作为外键值放置在登录名关联的数据库用户中,该登录名可以访问并且是其成员的每个数据库中。

Creating another SQL login that resides on a different SQL server instance and has the same name, will not, as one might expect, recreate the same SID.

创建另一个驻留在不同SQL Server实例上并具有相同名称的SQL登录名,不会像预期的那样重新创建相同的SID

使用传统TSQL语句的解决方案如何工作? ( How does the solution using traditional TSQL statements work? )

In older versions of SQL server (e.g. 7, 2000, 2005 until SP1), the system stored procedure sp_change_users_login was used to re-associate the user with its original login.

在旧版本的SQL服务器(例如7,2000年,2005年直到SP1),系统存储过程sp_change_users_ 登录 用于将用户与其原始登录名重新关联。

From version SQL server 2008, the official books online help warn us that this stored procedure will be removed in future versions of SQL server and we should avoid using it in our new development work and start modifying applications that currently use this procedure to the ALTER USER statement.

从SQL Server 2008版本开始,在线官方帮助警告我们,该存储过程将在以后的SQL Server版本中删除,我们应避免在新的开发工作中使用它,并开始将当前使用此过程的应用程序修改为ALTER USER。声明。

Nevertheless, the procedure is used and works even on the new SQL server 2016 version.

尽管如此,该过程仍被使用,甚至可以在新SQL Server 2016版本上使用。

The major disadvantages for using the sp_change_users_login procedure are that:

使用sp_change_users_login过程的主要缺点是:

1. The sp_change_users_login procedure cannot be used with SQL server logins that are created from windows (the new syntax with ALTER USER can do it)

1. sp_change_users_login过程不能与从Windows创建的SQL Server登录名一起使用(使用ALTER USER的新语法可以做到这一点)

2. Microsoft constantly announces that this procedure might not appear in future versions of the product so one should not get used to relying on it too much.

2. Microsoft不断宣布该程序可能不会在产品的将来版本中出现,因此不应过度依赖它。

Since of version SQL server 2005 service pack 2, the ALTER USER WITH

SQL Server 2005 Service Pack 2版本开始, 更改用户

LOGIN statement can be used in order to remap login and user associations.

可以使用LOGIN语句来重新映射登录名和用户关联。

This applies to both the SQL and the window accounts which is can become very useful if the underlying windows user or group has been re-created in active directory and now has a security identifier that no longer maps to the SID on the SQL server instance.

这适用于SQL帐户和窗口帐户,如果已在活动目录中重新创建了基础Windows用户或组,并且现在具有不再映射到SQL Server实例上的SID的安全标识符,则这将变得非常有用。

This new syntax solves this problem and also complies with the ANSI-SQL standard for SQL statements. The newer ALTER USER WITH LOGIN clause enables the remapping of the user to a different login.

此新语法可解决此问题,并且还符合SQL语句的ANSI-SQL标准。 较新的 ALTER USER WITH LOGIN子句允许将用户重新映射到其他登录名。

Users without a login, users mapped to a certificate, users mapped to an asymmetric key cannot use this clause. Only SQL users or windows users or group can be remapped. The WITH LOGIN clause cannot change the type of user, for example, changing from SQL user to windows user.

没有登录的用户,映射到证书的用户,映射到非对称密钥的用户不能使用此子句。 仅SQL用户或Windows用户或组可以重新映射。 WITH LOGIN子句无法更改用户类型,例如,从SQL用户更改为Windows用户。

解决方案如何运作? ( How does the solution work? )

I have designed a rather simple stored procedure called OrphanDBUsersAutoFix that finds all the SQL users in a database that do not have an associated server login and reconnects them.

我设计了一个相当简单的存储过程,称为 OrphanDBUsersAutoFix ,用于查找数据库中没有关联服务器登录名的所有SQL用户并重新连接它们。

This is done by using an outer join between the sys.database_principals and the sys.server_principals catalog views on the mutual SID column.

这是通过使用sys之间的外部联接来完成的。 database_principalssys。 相互SID列上的server_principals目录视图。

Alternatively, sp_change_users_login could be used with the REPORT parameter. I preferred not to do it since it will be removed in future.

或者,可以将sp_change_users_login' 报告 ' 参数。 我宁愿不这样做,因为将来会删除它。

For every database SID that does not have a corresponding server SID, an

对于每一个数据库SID不具有相应的服务器SID,一个

ALTER USER statement is done in order to re-create the association.

完成ALTER USER语句是为了重新创建关联。

The procedure will have an input parameter called @mode with two possible values:

该过程将有一个名为@ 模式有两个可能的值的输入参数:

‘REPORT’ – will only report the orphaned database users but without actually associating them to their respective login object.

'REPORT'–仅报告孤立的数据库用户,而没有实际将它们与各自的登录对象相关联。

‘EXECUTE’ – actually do the association between the database user object and login object.

'EXECUTE'–实际上是在数据库用户对象和登录对象之间进行关联。

I want to add that in previous versions like SQL 2000, 2005 or 2008, the method to identify an orphaned database user was to query the sysusers system table inside the application database and verify that the issqluser column equals 1 and also that the SID column is sysusers table is not null but the suser_sname function on that SID equals to NULL.

我想补充一点,在以前的版本(例如SQL 2000、2005或2008)中,标识孤立数据库用户的方法是查询应用程序数据库内的sysusers系统表,并验证issqluser列是否等于1,以及 SID列是sysusers表,不为null,但该SID上的suser_ sname函数等于NULL。

代码示例: ( Code example: )

SELECT name
FROM sysusers
WHERE issqluser = 1 and – The SQL User
  (sid IS NOT NULL AND sid <> 0×0) AND – The SID column in database level is not empty
  suser_sname(sid) IS NULL – The SID column in server level is empty
选择名称
来自系统用户
在哪里issqluser = 1和 – SQL用户
(sid不为NULL并且sid <> 0×0)和 –数据库级别的SID列不为空
suser_sname(sid)为NULL –服务器级别的SID列为空

There are two assumptions that are being made:

有两个假设:

  1. Both the user and login objects should exist prior to the procedure’s execution.在执行过程之前,用户和登录对象都应该存在。
  2. The names of user and login are identical.用户名和登录名相同。

Here is the Procedure TSQL Code:

这是 过程TSQL代码


CREATE PROCEDURE [dbo].[OrphanDBUsersAutoFix] (@mode VARCHAR(10))
AS
BEGINSET NOCOUNT ONDECLARE @tsql VARCHAR(400)DECLARE @username SYSNAMEDECLARE c_orphanedusers CURSORFOR  SELECT a.NAME AS OrphUsrFROM sys.database_principals aLEFT OUTER JOIN sys.server_principals bON a.sid = b.sidWHERE (b.sid IS NULL)      AND (a.principal_id > 4)     AND (a.type_desc = 'SQL_USER')OPEN c_orphanedusersFETCH c_orphanedusersINTO @usernameWHILE @@FETCH_STATUS = 0BEGINSET @tsql = 'ALTER USER ' + @username + ' WITH LOGIN = ' + @username;IF UPPER(@mode) = 'EXECUTE'EXEC (@tsql)ELSEIF UPPER(@mode) = 'REPORT'PRINT (@username)FETCH c_orphanedusers     INTO @usernameENDCLOSE c_orphanedusersDEALLOCATE c_orphanedusersIF (SELECT count(a.NAME) AS OrphUsrFROM sys.database_principals aLEFT OUTER JOIN sys.server_principals bON a.sid = b.sidWHERE (b.sid IS NULL)AND (a.principal_id > 4)AND (a.type_desc = 'SQL_USER')) = 0PRINT 'No Orphaned SQL Users.'SET NOCOUNT OFF
END
GO

以下是上述代码的一些解释: ( Here are some explanations for the above code: )

We iterate through a cursor that holds the entire orphaned database user names.

我们遍历一个游标,该游标包含整个孤立的数据库用户名。

For each orphan user, a dynamic TSQL statement is constructed that does the association to the server login. (This is done only for SQL logins)

对于每个孤立用户,将构造一个动态的TSQL语句,该语句与服务器登录名相关联。 (这仅适用于SQL登录)

At the end of the procedure, a check is done that the count of orphaned users inside the database equals zero.

在该过程结束时,将检查数据库中孤立用户的数量是否为零。

这是过程执行的示例,并带有一些解释: ( Here is an example for the procedure execution with some explanations: )

In order to test the procedure, we will create an orphaned user called “sqluser”.

为了测试该过程,我们将创建一个名为“ sqluser”的孤立用户

We will do it by first creating a login and a user. Afterwards we will drop the login and recreate it, leaving the user with no change, so there will be no association between the user and login objects.

我们将首先创建一个登录名和一个用户来完成它。 之后,我们将删除登录名并重新创建它,使用户保持不变,因此用户和登录对象之间将没有关联。

This will test our procedure and see if it reports the orphaned login in the report mode and afterwards associate it to the appropriate login by using the execute mode.

这将测试我们的过程,并查看它是否以报告模式报告孤立的登录名,然后使用执行模式将其与适当的登录名相关联。

这是示例代码: ( Here is the example’s code: )


USE Northwind;
GO
-- create the login
CREATE LOGIN sqlUserWITH PASSWORD = 'myTestSQL!', DEFAULT_DATABASE = Northwind;
GO
-- create the user
CREATE USER sqlUser
FOR LOGIN sqlUser;
GO
-- Now dropping the login object and re-creating it.
DROP LOGIN sqlUser;
-- re-create the login
CREATE LOGIN sqlUserWITH PASSWORD = 'myTestSQL!', DEFAULT_DATABASE = Northwind;
GO

You can verify it by executing the above procedure in the REPORT mode produces the result:

您可以通过在REPORT模式下执行上述过程来验证它来产生结果:


EXEC OrphanDBUsersAutoFix @mode = 'REPORT'
sqluser

After executing it and running the procedure with Report parameter it will produce the result:

执行它并运行带有Report参数的过程后,将产生结果:


EXEC OrphanDBUsersAutoFix @mode = 'EXECUTE'
No orphaned SQL users
Command(s) completed successfully.

This means that no orphaned users remain, so no user names are printed.

这意味着没有孤立的用户剩余,因此不会打印用户名。

Here are some suggested improvements for the stored procedure:

以下是对存储过程的一些建议改进:

  1. SQL_USERSQL_USER or 或WINDOWS_WINDOWS_ USER values. Change the procedure source accordingly.USER值。 相应地更改过程源。
  2. Check if the login exist and if not, create it according to user name.检查登录名是否存在,如果不存在,请根据用户名创建。

以下是一些相关参考 ( Here are some relevant references )

Here are some suggested references on the article’s subject, recommended for further reading:

以下是有关本文主题的一些建议参考,建议进一步阅读:

  • "Fixing orphaned database users 2005 to 2012"“修复2005至2012年孤立的数据库用户”
  • MSDN article: MSDN文章: "Trouble shooting orphaned users in SQL server"“在SQL Server中射击孤儿问题”
  • sp_change_users_login sp_change_users_login official reference官方参考

翻译自: https://www.sqlshack.com/creating-a-stored-procedure-to-fix-orphaned-database-users/

数据库创建存储过程

数据库创建存储过程_创建存储过程来修复孤立的数据库用户相关推荐

  1. MySQL存储过程_创建-调用

    存储过程:SQL中的"脚本" 创建存储过程 调用存储过程 存储过程体 语句块标签 存储过程的参数 in:向过程里传参 out:过程向外传参值 inout:in and out #S ...

  2. php mysql oracle数据库表结构图_创建数据库表

    数据库的作用:1.有结构的存储大量数据.2.有效保持数据的一致性.3.方便智能的分析,产生新的有用的信息.4.满足应用的共享和安全的要求. 关系型数据库的基本组成:一个数据库是由一组数据表(table ...

  3. python数据库迁移命令_创建和进行数据库迁移,同步数据库

    模型(model)建好后,django可以根据这个模型(model)在数据库中创建一张数据表格. Django自带一个数据库迁移(migration)系统来跟踪对模型(models)的修改,然后同步到 ...

  4. mysql新建数据库关系图_创建数据库关系图失败解决方法

    本文章介绍了关于创建数据库关系图失败解决方法,有需要的同学可以参考一下下. 在新建或附加数据库后,想添加关系表,结果出现下面的错误: 此数据库没有有效所有者,因此无法安装数据库关系图支持对象.若要继续 ...

  5. mysql创建过程_创建MYSQL的储存过程

    创建MYAQL的存储过程 1   创建不带参数的储存过程 CREATE  PROCEDURE  过程名()  过程体 SELECT  VERSION(); 2   调用储存过程 第一种   CALL ...

  6. unity创建纹理_创建带纹理的文本的技术

    unity创建纹理 View demo 查看演示 Download Source 下载源 In this article we're going to explore several techniqu ...

  7. mysql数据库开发经历_六年开发经验,整理Mysql数据库技巧笔记,全网最详细的笔记集合!...

    数据库 表 DML DQL 多表查询 内连接查询 外连接查询 子查询 将一条查询语句作为一张虚拟表 Mysql约束 主键约束 特点:主键约束默认包含非空和唯一两个功能. 一张表只能有一个主键. 主键一 ...

  8. 微服务跨数据库联合查询_微服务架构下,解决数据库跨库查询的一些思路

    加关注,不迷路! 前言 在服务做微服务改造后,原先单库join查询已经不能满足要求,每个拆分的微服务对应一个数据库实例,而且部署在不同的服务器上,那么解决"跨库查询"就势在必行了. ...

  9. 千万级大表如何更快速的创建索引_分享一份生产环境mysql数据库大表归档方案,值得收藏...

    概述 分享下最近做的一个mysql大表归档方案,仅供参考. 整体思路 一.明确哪些大表需做归档 1.数据库表概要信息统计 SELECTt1.table_schema,t1.table_name,`EN ...

最新文章

  1. 小蛮机器人如何联网_国际相对论第三期——机器人与物联网的碰撞
  2. 使用属性升级MyBank
  3. 蓝桥杯练习系统习题-历年真题解析2(完整版)
  4. 图书馆座位预定管理系统前端设计_图书馆座位预约管理信息系统设计设计.doc...
  5. 我的第一个C#版GDI+程序
  6. 今年最惨的交易:做空特斯拉
  7. 消息通信库ZeroMQ 4.0.4安装指南
  8. C#实现人脸识别【SqlHelper】
  9. 单元素枚举类实现单例模式
  10. [转载] Java9发布回顾Java 8的十大新特性
  11. 排序算法——归并排序的相关问题
  12. 1.MAC中MySql的环境配置
  13. Unity3D对象池小案例
  14. python lambda菜鸟教程_Python - lambda函数
  15. 误Ghost后的分区恢复
  16. java上传文件怎么设置成777权限,777权限的改法是怎样的 将文件权限修改为777图文教程...
  17. ag-grid with web api
  18. 我的王姨!YYDS!富婆这套路实在是太深了...
  19. 【仙变3】牧仙记版VM一键端
  20. 【玩计算机才是最好的出路】

热门文章

  1. pom.xml文件引入tools.jar
  2. 64匹马,8个赛道,通过比赛,决出前四名。
  3. Python学习笔记(三)Python安装及设置环境变量
  4. 九度OJ-1112-导弹拦截-最长不增子序列
  5. 如何设置VSCode中文显示
  6. HTML+CSS制作一个动画
  7. 什么是CloudComputing
  8. 真我手机信号好还是苹果三星信号好?
  9. 不好的女人只能消耗你,好的女人不仅可以给你一个家和孩子
  10. 腾讯正式入局中视频领域