SQL Server的结构与Oracle不同,SQL Server里边可以包括很多的database,每个database有自己的表,用户等信息。比如目前有一个应用,应用的每个数据集都是一个database,致使在SQL Server中有多达1000+的database。

我们可以通过以下语句查看SQL Server中的所有数据库。

 SELECT Name FROM Master..SysDatabases ORDER BY Name

SQL Server的用户也分为两种,一种是登录SQL Server的用户,一种是SQL Server中每个数据库中的用户。通常情况下,我们会将登录用户与数据库用户取同样的名字,然后通过用户映射赋予登录用户权限。

创建登录SQL Server用户语句如下:

 --创建登录用户“dba”,密码为abcd1234@,默认数据库是mydb
create login dba with password='abcd1234@', default_database=mydb

创建数据库中的用户的语句如下:

 --创建数据库用户“dba”,与登录用户同名
create user dba for login dba with default_schema=dbo

赋予数据库用户相应的权限

 --通过加入数据库角色,赋予数据库用户“db_owner”权限
exec sp_addrolemember 'db_owner', 'dba'

其他相关语句可参考这边博文,点我。

在维护某系统时,需要根据数据库命名规则批量detach一些数据库,比如数据库名已R16开头的,通过以下SQL可以拼出sql语句,然后批量执行。

 select 'EXEC  sp_detach_db ['+[name]+']'+CHAR(10) from master..sysdatabases where substring(name, 1,3) in ('E15','E16','R15','R16') ORDER BY Name

===============================================================================

下面说说我遇到的需求,一个SQL Server数据库有1000多个database。需要建一个用户,使这个用户对每个database具有只读权限,需要写脚本实现。无意中在互联网上发现了一篇博文。与我的需求完全一致,准备在测试环境里边实验一下。

也不是原创,直接把代码贴过来吧。

 Use master
GO DECLARE @dbname VARCHAR(50)
DECLARE @statement NVARCHAR(max) DECLARE db_cursor CURSOR
LOCAL FAST_FORWARD
FOR
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb','distribution')
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN SELECT @statement = 'use '+@dbname +';'+ 'CREATE USER [TipsDemoUser]
FOR LOGIN [TipsDemoUser]; EXEC sp_addrolemember N''db_datareader'',
[TipsDemoUser];EXEC sp_addrolemember N''db_datawriter'', [TipsDemoUser]' exec sp_executesql @statement FETCH NEXT FROM db_cursor INTO @dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor

这篇博文也可参考。

======================================================================

具体执行上述脚本遇到的问题:

1、拼的@statement这个sql中必须给@dbname两边加上"["和"]",要不然汇报语法错误,折腾了好久;

2、实际的数据库中可能有只读的库,执行到只读库的时候脚本就终止了,所以需要将只读的库剔除。

通过互联网,找到两种找到只读库的方法。一是通过databasepropertyex这个函数得到数据库的读写状态,具体说明见微软官方文档。

以下是我写的代码,将所有只读库放到一个中间表里边。但是最终也没有成功,主要是不能把动态SQL的结果传给一个变量,下面用的方法也是网上找到,但是没有成功。

 use master
go
declare @dbname_ro varchar(100)
declare @statement_ro nvarchar(max)
declare @states_ro nvarchar(20)
declare db_cursor_ro cursor
local fast_forward
for
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb','distribution')
open db_cursor_ro
fetch next from db_cursor_ro into @dbname_ro
while @@fetch_status = 0
begin
select @statement_ro = 'select databasepropertyex(' + '''' + @dbname_ro + '''' + ',''updateability'')'
exec sp_executesql @statement_ro, N'@states_ro nvarchar(20) output', @states_ro output
if @states_ro = 'READ_ONLY'
insert into [ProgramUse].dbo.database_ro(db_names, db_state) values ('@dbname_ro', 'READ_ONLY')
fetch next from db_cursor_ro into @dbname_ro
end
close db_cursor_ro
deallocate db_cursor_ro

最后通过系统的一个视图可以方便的查找只读的数据库,sys.databases,其中is_read_only为1的就是只读状态的数据库。

最终完成为所有数据库建立一个只读用户的目的。最终代码如下:

 Use master
GO
DECLARE @dbname VARCHAR(100)
DECLARE @statement NVARCHAR(max)
DECLARE db_cursor CURSOR
LOCAL FAST_FORWARD
FOR
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name NOT IN ('master','model','msdb','tempdb','distribution','IED2008_JPEFEI_CT_JPY_EDM110') and name not in (select name from sys.databases where is_read_only = 1)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @statement = 'use '+ '[' + @dbname + ']' + ';' + 'CREATE USER reapsro FOR LOGIN reapsro; EXEC sp_addrolemember ''db_datareader'',''reapsro'''
exec sp_executesql @statement
FETCH NEXT FROM db_cursor INTO @dbname
END
CLOSE db_cursor
DEALLOCATE db_cursor

SQL Server初探的更多相关文章

  1. C# 调用 SQL server 初探

    相信不少人都和我一样: 1.学过数据库原理接触过SQL Server,做过一套卷子外加一个数据库设计作业: 2.学过C# 但从来还没在程序里用到过数据库(哈哈,新手躺枪) 这也是我第一次在C#里用数据 ...

  2. 引用:初探Sql Server 执行计划及Sql查询优化

    原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之————探索MSSQL执行计划 作者:no_mIss 最近总想 ...

  3. Ubuntu 下安装 SQL Server 2016初探

    安装步骤参官方 https://docs.microsoft.com/zh-cn/sql/linux/sql-server-linux-setup-ubuntu 执行命令如下: .Enter supe ...

  4. Sql Server数据库快照初探

    什么是快照 数据库快照是 SQL Server 数据库(源数据库)的只读静态视图.换句话说,快照可以理解为一个只读的数据库.利用快照,可以提供如下好处: 提供了一个静态的视图来为报表提供服务 可以利用 ...

  5. sql server 内存初探

    一. 前言 对于sql server 这个产品来说,内存这块是最重要的一个资源, 当我们新建一个会话,相同的sql语句查询第二次查询时间往往会比第一次快,特别是在sql统计或大量查询数据输出时,会有这 ...

  6. SQL Server 2008 游标使用实例

    本文使用以下两张数据库表作为演示对象. 1 游标初探--使用游标进行遍历 declare @classAndStudent table( class_id int, --班级ID class_name ...

  7. sql server 性能调优之 资源等待之网络I/O

    一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql server返回数据结果集给客户端的时候,会先将结果集填充到输出缓存里(ouput cache),同时网络层会开 ...

  8. sql server 性能调优之 资源等待内存瓶颈的三种等待类型

    一.概述 这篇介绍Stolen内存相关的主要三种等待类型以及对应的waittype编号,CMEMTHREAD(0x00B9),SOS_RESERVEDMEMBLOCKLIST(0x007B),RESO ...

  9. sql server 性能调优之 资源等待PAGEIOLATCH

    一.概念 在介绍资源等待PAGEIOLATCH之前,先来了解下从实例级别来分析的各种资源等待的dmv视图sys.dm_os_wait_stats.它是返回执行的线程所遇到的所有等待的相关信息,该视图是 ...

随机推荐

  1. 使用飞冰组件关于点击行回填在input内(React)

    import { Table,Grid } from "@icedesign/base"; import { FormBinderWrapper as IceFormBinderW ...

  2. runtime统计页面数据或者统计按钮的点击次数

    一.按钮的点击统计 有的时候我们遇见这样的需求,让我们统计用户点击我们页面的动作的次数给与用户以统计,供以后给客户端推送不同的页面数据,这时候我们就会用到iOS的黑魔法(runtime). 首先我们不 ...

  3. 第2次作业 -- 熟悉 JUnit 测试

    2.1 Mooctest 使用心得 Mooctest很方便,可以即时测评自己写的测试代码,获得覆盖率和报告,不需要自己安装配置环境 而且安装配置插件的环境也很简单,可以专注于测试本身 2.2 Juni ...

  4. 【SoftwareTesting】Homework3

    (a) (b) 数组越界问题 (c) n=0 (d) 点覆盖:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 边覆盖:[(1,2),(2,3),(3,4),(4,5) ...

  5. mac 内置PHP配置多站点

    1.修改/private/etc/hosts 文件,建议用编辑器打开 最后一行加入你的网站名称(自定义),参考如下: 127.0.0.1 www.MyObj.com   2.修改/private/et ...

  6. NLP相似度之tf-idf计算

    当然,在学习过程中也是参考了很多其他的资料,代码都是一行一行敲出来的. 一.将多个文件合并成一个文件,避免频繁的打开和关闭 import sys for line in sys.stdin: ss = ...

  7. web 自定义标签

    Web Components 标准非常重要的一个特性是,它使开发者能够将HTML页面的功能封装为 custom elements(自定义标签).而自定义标签的好处,就是在大型web开发的时候,可以封装 ...

  8. linux 计划任务 访问某个URL

    1.进入crontab文件的编写状态: crontab -e 2.进入编辑器后,按下 “ i ” 键,进入编辑模式,在编辑模式下,我们写上我们这次需要访问执行的脚本: 59 23 * * * /usr ...

  9. C# socket通讯 send方法记录

    由于本人是Java入门的开发,在C#开发中遇到的问题,在此记录一下: 1.client端的send方法不管发送出去没发送出去,总是显示发送出去. 查资料得知,send方法是将数据发送到缓存区,并不是直 ...

  10. Some notes in Stanford CS106A(4)

    1.x++ is a method , the return value is x. (post increment) ++x is also a method , the return value ...