关于sqlserver:SQL-Server数据库恢复SQL-Server数据恢复SQL-Server数据误删除恢复工具SQLRescue

专一于SQL Server数据库的复原。专一于各种勒索病毒加密数据库的修复。 SQLRescue可用于从损坏的 MS SQL Server 数据库数据文件(.mdf .ndf 文件)中复原数据。它能够保留要害数据,防止其失落。 一、SQLRescue次要性能有: 零碎解体只剩下数据文件的状况下的复原,即无日志文件或者日志文件损坏状况下的复原;断电导致数据库文件损坏状况下的复原;硬盘坏道造成数据库损坏状况下的复原;数据文件外部存在坏页状况下的复原;企业管理器误删除数据表记录,管理软件误删除数据表记录的复原;并闩锁谬误、格式化、误删除后导致软件不能应用的状况;无奈读取并闩锁页sysindexes失败状况下的修复;数据文件被误删除状况下的碎片提取复原;零碎表损坏、索引谬误、误删除数据库表、删除记录的数据找回;master数据库损坏而无奈失常运行状况下的复原;数据文件无奈附加状况下的数据恢复;数据库被标记为可疑,质疑,不可用等状况的复原;数据库sysobjects等零碎表损坏状况下的复原;数据被误(drop、delete、truncate)删除表数据的复原,误update后的数据恢复等;还原时报一致性谬误,谬误823等状况下的数据恢复,各种谬误提醒的数据库文件修复;数据库被误格式化等状况下的数据库复原;日志膨胀造成数据库损坏状况下的复原;仅剩损坏的备份文件状况下的复原。二、SQLRescue次要技术特点: 只有SQL Server数据库的数据文件存在,咱们就有方法帮您从数据文件中找回重要数据。 从数据文件中间接复原数据不能附加时间接复原数据并生成新的数据库零碎表损坏的数据库修复疾速修复SQL 823谬误、连贯中断谬误三、SQLRescue反对的版本: Microsoft SQL Server 6.5, 7.0, 2000, 2005, 2008, 2008R2, 2012, 2014, 2016, 2017,2019。

February 20, 2023 · 1 min · jiezi

关于sqlserver:无法分离数据库解决方案

use master go create proc killspid (@dbname varchar(20)) as begin declare @sql nvarchar(500),@temp varchar(1000) declare @spid int set @sql='declare getspid cursor for select spid from sysprocesses where dbid=db_id('''+@dbname+''')' exec (@sql) open getspid fetch next from getspid into @spid while @@fetch_status<>-1 begin set @temp='kill '+rtrim(@spid) exec(@temp) fetch next from getspid into @spid end close getspid deallocate getspid end ...

June 2, 2021 · 1 min · jiezi

关于sqlserver:该账户当前被锁定所以用户sa登录失败

ALTER LOGIN sa ENABLE ;GOALTER LOGIN sa WITH PASSWORD = '数据库明码' unlock, check_policy = off,check_expiration = off ;GO

June 2, 2021 · 1 min · jiezi

关于sqlserver:PostgreSQL安全最佳实践

数据库是黑客眼中的“圣杯”,须要咱们像看待“花朵”一样精心呵护它。本文次要介绍数据库爱护的最佳实际。首先,从最罕用的开源数据库PostgreSQL开始,咱们将一一介绍诸位须要思考的几个平安层级: PostgreSQL中网络层的平安防火墙现实状况下,PostgreSQL服务器该当是齐全隔离,不容许任何入站申请、SSH或psql的。然而,PostgreSQL没有对这类网闸设置提供开箱即用的反对。咱们最多也只能通过设置防火墙,锁定数据库所在节点的端口级拜访来晋升数据库服务器的安全性。默认状况下,PostgreSQL监听TCP端口5432。而依据操作系统的不同,锁定其余端口的形式也会有所不同。以Linux最罕用的防火墙为例,上面这几行代码就可轻松实现工作: 确保已有连贯不被dropiptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 容许SSH.iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT 容许PostgreSQL.iptables -A INPUT -p tcp -m state --state NEW --dport 5432 -j ACCEPT 容许所有出站,drop所有入站iptables -A OUTPUT -j ACCEPTiptables -A INPUT -j DROPiptables -A FORWARD -j DROP在更新iptables的规定时,倡议应用工具。这样,哪怕你不小心把本人也锁在里面了,它也能主动回滚更改。这条PostgreSQL规定会容许所有人连贯到端口5432上。当然,你也能够将其批改为只承受特定IP地址或子网让限度更加严格: 仅容许本地子网拜访PostgreSQL端口iptables -A INPUT -p tcp -m state --state NEW --dport 5432 -s 192.168.1.0/24 -j ACCEPT持续探讨咱们的现实状况。想要齐全限度到5432端口的所有入站连贯须要一个某种类型的本地代理,由它维持一个到客户端节点的长久出站连贯,并且能将流量代理到本地PostgreSQL实例。这种代理被称作是“反向通道”。具体应用办法能够通过SSH近程端口转发的性能进行演示。运行下列指令能够在PostgreSQL数据库运行的节点上关上一个反向通道:ssh -f -N -T -R 5432:localhost:5432 user@<client-host>PostgreSQL的节点须要能拜访<client-host>,其上的SSH守护过程(daemon)也要处于运行状态。下列指令会将数据库服务器上端口5432转发到客户端机器的端口5432上,这样你就能够通过这个通道连贯数据库了:psql "host=localhost port=5432 user=postgres dbname=postgres"PostgreSQL监听地址通过配置文件指令来限度服务器监听客户端连贯的地址是个好习惯。如果运行PostgreSQL的节点上有多个网络接口,能够确保服务器只会监听客户端所连贯的一个或多个接口:listen_addresses = 'localhost, 192.168.0.1'如果连贯到数据库的客户端总是驻留在同一节点上,或是与数据库独特驻留在同一个Kubernetes pod上,PostgreSQL作为 sidecar 容器运行,禁用套接字监听(socket)能够齐全打消网络的影响。将监听地址设置为空字符串能够使服务器只承受Unix域的套接字连贯:listen_addresses = ''PostgreSQL中传输层级的平安当世界上大部分的网络都转投向HTTP的怀抱时,为数据库连贯抉择强传输加密也变成了一个必备我的项目。PostgreSQL自身即反对TLS(因为历史遗留问题,在文档、配置文件,以及CLI中仍被称作是SSL),咱们也能够应用它进行服务器端和客户端认证。服务器端TLS对于服务器的认证,咱们首先须要为服务器筹备一份用于和相连接的客户端认证的证书。在Let's Encrypt上,咱们能够找到收费提供的X.509证书,具体应用办法以的命令行工具为例:certbot certonly --standalone -d postgres.example.com须要留神的是,certbot默认应用ACME标准的HTTP-01挑战来验证证书申请,这里咱们就须要确保申请域指向节点的DNS无效,并且端口80处于凋谢状态。除了Let's Encrypt之外,如果想在本地生成所有的信息,咱们还能够抉择openssl命令行工具: ...

May 21, 2021 · 2 min · jiezi

关于sqlserver:SqlServer数据库损坏后修复过程记录

一.SqlServer数据库损坏的起因客户的一块容量为1.2TB的硬盘,外面存储的是SqlServer数据库,客户形容说硬盘因为误操作导致分区损坏,须要对硬盘里的数据库进行数据恢复。 二.硬盘故障初检通过工程师对客户硬盘的初步检测,确认了客户的SqlServer数据库根底信息如下:客户环境:windows操作系统磁盘容量:1.2T硬盘文件系统类型:NTFS数据库类型:sqlserver数据库数据库个数:12个故障状况:分区损坏,数据失落 三.复原数据库数据1、扫描1T磁盘空间首先应用自研发的SqlServer数据库工具对硬盘进行全盘扫描,依据数据库的页构造,扫描磁盘空间,获取数据库页偏移地位,对象id,页号等信息 2、拼接数据库(1)、Sqlserver的每个数据库页都是从0号页开始编号,客户共12个数据库,导致有大量反复页,因而无奈间接按页号从小到大拼接。(2)、依据客户提供的数据库名和数据记录中guid,来判断数据库页属于哪个数据库。(3)、依据数据库名字、页号拼接出数据库。(4)、因为缺失数据库页,拼接的数据库大小存在差别,须要批改数据库大小属性信息,之后进行挂载。(5)、挂载数据库、胜利挂载 四.数据验证数据库可能胜利挂载后,工程师将客户的数据库数据进行了查看,确认根本复原残缺后,分割客户亲自对SqlServer数据库记录进行完整性验证。通过验证,共12个数据库根本复原,数据库记录也比拟残缺,通过评估数据确认100%复原,本次数据库数据恢复胜利。

May 20, 2021 · 1 min · jiezi

关于sqlserver:SQLServer设置客户端使用IP地址登录

一、设置SQLServer身份验证1、按下windows+R,弹出运行框2、在弹出框中输出cmd,按下enter键。3、在dos命令窗口输出compmgmt.msc命令,按下enter键。4、在计算机管理窗口-》开展服务和应用程序-》开展SQLServer配置管理器-》开展SQLServer网络配置-》点击MSSQLSERVER的协定。5、右键点击TCP/IP-》点击启用-》点击弹出框中的确定。6、在TCP/IP弹出框-》找到IP2-》已启用由否改为是-》点击下方利用按钮-》点击确定按钮。7、在计算机管理页面-》鼠标左键点击SQLServer服务。8、找到SQLServer(MSSQLSERVER)服务-》右键点击-》抉择重启-》期待重启实现。9、在dos命令窗口中输出ipconfig命令查看本机ip。10、关上SSMS数据库管理工具-》在服务器名称中输出IP地址-》身份验证抉择SQLServer身份验证-》输出登录名和明码-》点击连贯。11、登录胜利示例图片。 二、设置Windows身份验证1、在计算机管理-》开展SQLServer配置管理器-》开展SQLServer网络配置-》鼠标左键点击MSSQLSERVER的协定-》抉择Named Pipes-》右键点击-》点击启用。2、在SQLServer配置管理器-》鼠标左键点击MSSQLSERVER服务-》抉择SQLSERVER(MSSQLSERVER),右键点击-》抉择重启。3、在SSMS数据库管理工具中抉择Windows身份验证。 注意事项1、留神不同网络段造成的的不可拜访数据库。 2、留神防火墙等设置造成的不可拜访数据库。

December 8, 2020 · 1 min · jiezi

关于sqlserver:练习SQL之汇总机构下面的医生总数

背景:练习sql.机构表和医生表.汇总每个机构上面的医生总数.去除机构下为0的医生行,倒序展现. sql语句select DISTINCT b.InstitutionID,InstitutionName,COUNT(ClientID) ClientSum from b_Institution bleft join b_Client c on c.InstitutionID = b.InstitutionID group by b.InstitutionID , InstitutionNamehaving COUNT(ClientID) != 0order by ClientSum desc记录一下每一句sql的意思:(1): select DISTINCT b.InstitutionID,InstitutionName,COUNT(ClientID) ClientSum 查问进去的后果列为三列.第一列为去重后的InstitutionID第二列为InstitutionName第三列为客户总数列名为ClientSum(2):from b_Institution b 查问主表为机构表 并取别名为b(3):left join b_Client c on c.InstitutionID = b.InstitutionID 左联医生表(取别名为c)外面的机构ID和机构表的机构ID相等的数据(4):group by b.InstitutionID , InstitutionName 对机构表的ID和Name进行分组(分组后就能够计算医生数量)(5):having COUNT(ClientID) != 0 去除医生数量为0的数据(6):order by ClientSum desc 对医生数量进行倒序排序最初附上后果图:

October 21, 2020 · 1 min · jiezi

关于sqlserver:sql-serve2016

sql serve 2016 装置教程1.电脑系统 windows 10 专业版 2.在开发的过程中咱们会应用到数据库,这里我抉择的是 sql serve2016,上面我来说以下 sql serve 2016 的装置教程!3.4.解压之后你会看到5.双击进入6.7.点击下一步 8.点击【更改】更改软件装置门路,我这里装置到D盘,所以间接把字母C更改为D即可,而后复制更改后的装置门路(复制的时候用快捷键Ctrl+C),能够把复制后的装置门路保留到记事本外面,前面环境变量配置的时候须要。复制后的装置门路为D:\Program Files\Java\jdk1.8.0_131\9.期待装置。(请不要敞开此界面) 10..倡议在D:\Program Files\Java文件夹下新建一个【jre1.8】文件夹(因为我之前抉择装置到D盘的),如果你之前装置到其它盘,你可在其它盘的Program Files\Java文件夹下新建一个【jre1.8】文件夹。而后点击【更改】抉择方才新建的【jre1.8】文件夹,再点击【下一步】。11.期待装置。12.点击【敞开】。13.鼠标右击【此电脑】抉择【属性】。14.点击【高级零碎设置】。15.点击【高级】,而后点击【环境变量】。16.在零碎变量下点击【新建】,变量名输出【JAVA_HOME】,变量值输出【D:\Program Files\Java\jdk1.8.0_131】,而后点击【确定】。(变量值为第6步复制的装置门路)17.关上软件装置门路下的【bin】文件夹,软件装置门路为第6步设置的门路,我这里为D:\Program Files\Java\jdk1.8.0_131\bin,而后复制此门路。 而后 配置环境,同下面的操作!18.【WIN】键+【R】键,而后输出【cmd】,而后点击【确定】。19.输出命令:java -version(java 和 -version 之间有空格),java,javac 这三个命令(都要试一下,只有有一个呈现失败状况,就阐明JDK环境配置失败)。都显示失常,阐明配置胜利! 输出java -version时,胜利图示如下: 输出java时, 胜利图示如下: 输出javac 时, 胜利图示如下: 19.装置SQL Server 201620.鼠标双击【cn_sql_server_2016_x64.iso】。 21.鼠标右击【setup.exe】抉择【以管理员身份运行】。22.点击【装置】,而后点击【全新SQL Server独立装置或向现有装置增加性能】。23.产品密钥是主动填写的,如果没有主动填写那就须要手动输出【MDCJV-3YX8N-WG89M-KV443-G8249】,而后点击【下一步】。24.抉择【我承受许可条款】而后点击【下一步】。25.点击【下一步】。26.点击【下一步】。27.点击【全选】,而后勾销勾选【R服务(数据库内)】和【R Server(独立)】,倡议将Microsoft SQL Server软件装置到除C盘以外的磁盘,我这里装置到D盘,可间接将【C】改为【D】,而后点击【下一步】。28.点击【下一步】。29.点击【下一步】。30.点击【下一步】。31.点击【增加以后用户】,而后点击【下一步】。32.点击【增加以后用户】,而后点击【下一步】。33.点击【下一步】。34.点击【增加以后用户】,而后点击【下一步】。35.点击【下一步】。36.点击【承受】。37.点击【下一步】。38.点击【装置】。39.软件装置中。工夫有点长,请急躁期待!40.装置胜利,点击【敞开】。41.点击右上角的【×】敞开页面。42.双击关上压缩包解压后的【SQL Server 2016】文件夹,鼠标右击【SSMS-Setup-CHS.exe】抉择【以管理员身份运行】。43..点击【更改】更改软件装置门路,倡议装置在除C盘之外的其它磁盘,可在D盘或其它磁盘新建一个【SSMS】文件夹,而后点击【装置】。44.正在装置中。45.点击【重新启动】。46..电脑重新启动后,点击左下角的【开始菜单】,找到【Microsoft SQL Server Management Studio 18】并用鼠标往桌面拖动即可创立桌面快捷方式。47.双击关上【Microsoft SQL Server Management Studio 18】。48.点击【连贯】。49.装置实现,软件运行界面如下。50.本期的教程到了这里就完结啦!是不是很简略!让咱们一起致力走向巅峰!

August 6, 2020 · 1 min · jiezi

使用sql获取各数据库MySQLPostgreSQLOracleMsSQL的表结构

通常我们提到数据库表结构的时候,比较关心的几个属性:字段名称、类型、长度、是否主键、是否自增、是否为空、默认值、备注。那么,使用SQL语句获取这些属性,在各主流数据库下是什么样的呢?MySQL数据库作为时下最流行的数据库,MySQL的获取SQL是最简单的。一般我们用下面一行语句就能搞定: SHOW FULL COLUMNS FROM xxx;当然,也可以用MySQL自带的数据库information_schema中的表,例如:columns等查询更全的信息。 PostgreSQL数据库使用其两个最重要的Schema(information_schema、pg_catalog)下表,进行关联查询,获取常用属性。 SELECT d.column_name AS "Field", d.udt_name AS "Type", COALESCE(d.character_maximum_length, d.numeric_precision, d.datetime_precision) AS "Length", CASE WHEN t.conname IS NOT NULL THEN 'PRI' ELSE '' END AS "Key", CASE WHEN s.extra IS NOT NULL THEN 'auto_increment' ELSE '' END "Extra", d.is_nullable AS "Null", f.adsrc AS "Default", col_description(a.attrelid, a.attnum) AS "Comment" FROM information_schema.columns d, pg_class c, pg_attribute a LEFT JOIN pg_constraint t ON (a.attrelid = t.conrelid AND t.contype = 'p' AND a.attnum = t.conkey[1]) LEFT JOIN pg_attrdef f ON (a.attrelid = f.adrelid AND a.attnum = f.adnum) LEFT JOIN (SELECT 'nextval(''' || c.relname || '''::regclass)' AS extra FROM pg_class c WHERE c.relkind = 'S') s ON f.adsrc = s.extraWHERE a.attrelid = c.oidAND a.attnum > 0AND c.relname = d.table_nameAND d.column_name = a.attnameAND c.relname = 'xxx'ORDER BY a.attnum;Oracle数据库系统表:user_col_comments能提供大部分信息,只有:备注(Comment)、主键(Key)需要关联其他表进行获取。 ...

August 28, 2019 · 2 min · jiezi

SQLServerMySQLOracle三种数据库的优缺点总结

一、SQLServer优点易用性、适合分布式组织的可伸缩性;用于决策支持的数据仓库功能、与许多其他服务器软件紧密关联的集成性、良好的性价比等;为数据管理与分析带来了灵活性,允许单位在快速变化的环境中从容响应,从而获得竞争优势。从数据管理和分析角度看,将原始数据转化为商业智能和充分利用Web带来的机会非常重要。作为一个完备的数据库和数据分析包,SQLServer为快速开发新一代企业级商业应用程序、为企业赢得核心竞争优势打开了胜利之门;作为重要的基准测试可伸缩性和速度奖的记录保持者,SQLServer是一个具备完全Web支持的数据库产品,提供了对可扩展标记语言 (XML)的核心支持以及在Internet上和防火墙外进行查询的能力;缺点开放性 :SQL Server 只能windows上运行没有丝毫开放性操作系统系统稳定对数据库十分重要Windows9X系列产品偏重于桌面应用NT server只适合小型企业而且windows平台靠性安全性和伸缩性非常有限象unix样久经考验尤其处理大数据库;伸缩性并行性 :SQL server 并行实施和共存模型并成熟难处理日益增多用户数和数据卷伸缩性有限;安全性:没有获得任何安全证书。性能 :SQL Server 多用户时性能佳 ;客户端支持及应用模式:客户端支持及应用模式。只支持C/S模式,SQL Server C/S结构只支持windows客户用ADO、DAO、OLEDB、ODBC连接;使用风险:SQL server 完全重写代码经历了长期测试断延迟许多功能需要时间来证明并十分兼容;二、MySQL优点体积小、速度快、总体拥有成本低,开源;支持多种操作系统;是开源数据库,提供的接口支持多种语言连接操作;MySQL的核心程序采用完全的多线程编程。线程是轻量级的进程,它可以灵活地为用户提供服务,而不过多的系统资源。用多线程和C语言实现的mysql能很容易充分利用CPU;MySql有一个非常灵活而且安全的权限和口令系统。当客户与MySql服务器连接时,他们之间所有的口令传送被加密,而且MySql支持主机认证;支持ODBC for Windows, 支持所有的ODBC 2.5函数和其他许多函数, 可以用Access连接MySql服务器, 使得应用被扩展;支持大型的数据库, 可以方便地支持上千万条记录的数据库。作为一个开放源代码的数据库,可以针对不同的应用进行相应的修改。拥有一个非常快速而且稳定的基于线程的内存分配系统,可以持续使用面不必担心其稳定性;MySQL同时提供高度多样性,能够提供很多不同的使用者介面,包括命令行客户端操作,网页浏览器,以及各式各样的程序语言介面,例如C+,Perl,Java,PHP,以及Python。你可以使用事先包装好的客户端,或者干脆自己写一个合适的应用程序。MySQL可用于Unix,Windows,以及OS/2等平台,因此它可以用在个人电脑或者是服务器上;缺点不支持热备份;MySQL最大的缺点是其安全系统,主要是复杂而非标准,另外只有到调用mysqladmin来重读用户权限时才发生改变;没有一种存储过程(Stored Procedure)语言,这是对习惯于企业级数据库的程序员的最大限制;MySQL的价格随平台和安装方式变化。Linux的MySQL如果由用户自己或系统管理员而不是第三方安装则是免费的,第三方案则必须付许可费。Unix或linux 自行安装 免费 、Unix或Linux 第三方安装 收费;三、Oracle优点开放性:Oracle 能所有主流平台上运行(包括 windows)完全支持所有工业标准采用完全开放策略使客户选择适合解决方案对开发商全力支持;可伸缩性,并行性:oracle 并行服务器通过使组结点共享同簇工作来扩展windownt能力提供高用性和高伸缩性簇解决方案windowsNT能满足需要用户把数据库移UNIXOracle并行服务器对各种UNIX平台集群机制都有着相当高集成度;安全性:获得最高认证级别的ISO标准认证;性能:Oracle 性能高 保持开放平台下TPC-D和TPC-C世界记录;客户端支持及应用模式:Oracle 多层次网络计算支持多种工业标准用ODBC、JDBC、OCI等网络客户连接;使用风险:Oracle 长时间开发经验完全向下兼容得广泛应用地风险低缺点对硬件的要求很高;价格比较昂贵;管理维护麻烦一些;操作比较复杂,需要技术含量较高;推荐阅读1、今天,一周年,感谢有你 2、Linux下MySQL基本操作 3、我必须得告诉大家的MySQL优化原理 4、千行 MySQL 详细学习笔记,你收藏了吗? 5、记住,永远不要在 Mysql 中使用 “utf8” 6、一次超有意思的 SQL 优化经历! 7、Oracle SQL 性能优化40条,必看! 8、Oracle数据库环境搭建 9、Oracle客户端PLSQL的使用说明 10、Linux环境下Oracle数据库常用命令 欢迎关注微信公众号杰哥的IT之旅

August 20, 2019 · 1 min · jiezi

程序员过关斩将你为什么还在用存储过程

存储过程存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。优势可以减少程序在调用DB时候的信息传输量(其实减少的只有Request的时候)存储过程是预先优化和预编译的,节省每次运行编译的时间,所以一般情况下认为存储过程的性能是优于sql语句的。对调用者可以隐藏数据库的复杂性,将数据组装的过程封装。参数化的存储过程可以防止SQL注入式攻击,而且可以将Grant、Deny以及Revoke权限应用于存储过程。如果业务开发中,数据人员和业务代码人员是分离的,业务人员可以不用关心数据,直接调用存储过程,更加面向分层开发设计理念。劣势存储过程这种“一次优化,多次使用”的策略节省了每次执行时候编译的时间,但也是该策略导致了一个致命的缺点:可能会使用错误的执行计划。存储过程难以调试,虽然有些DB提供了调试功能,但是一般的账号根本就没有那种权限,更何况线上的数据库不可能会给你调试权限的,再进一步就算能调试效果也比程序的调试效果要差很多。可移植性差,当碰到切换数据种类的时候,存储过程基本就会歇菜。如果业务数据模型有变动,存储过程必须跟着业务代码一起更改,如果是大型项目,这种改动是空前的,是要命的。不推荐存储过程以上存储过程的优缺点,你随便一下网络就可能查到,表面看来存储过程的优势还是不少的,这也说明为什么老一辈程序员有很多喜欢写存储过程。但是随着软件行业业务日益复杂化,存储过程现在在复杂业务面前其实有点有心无力。 菜菜在业务中并不推荐使用存储过程,辩驳请留言采用存储过程操作数据在网络数据量传输上确实比直接使用sql语句要少很多,但这通常并不是操作数据系统性能的瓶颈,在一次操作数据的过程中,假设用时100毫秒,采用存储过程节省数据传输时间0.5毫秒(就算是5毫秒),我觉得这点时间基本可以忽略。存储过程是只优化一次的,这有时候恰恰是个缺陷。有的时候随着数据量的增加或者数据结构的变化,原来存储过程选择的执行计划也许并不是最优的了,所以这个时候需要手动干预或者重新编译了,而什么时候执行计划不是最优的了这个平衡点,预先无法知晓,这就导致了有些应用突然会变慢,程序员处于懵逼的状态。存储过程确实可以对调用方隐藏数据库的细节,但是这种业务代码人员和数据库设计人员是两个团队的情况又有多少呢,如果真是两个团队,那业务就需要两个团队来理解和沟通,我想沟通的成本也一定很高,而且分歧更容易产生。菜菜认为数据库就应该做它最擅长的事情:存储相关。我不止一次的看过把业务写在存储过程的情况,程序代码层面真是薄薄的贫血层,就是一个数据的透传。我不赞同这种写法,因为我就接手过这样的程序,令我头疼的不是业务,而是看着好几千行的存储过程熟悉业务,关键还没有调试的权限(线上更不能调试)。 一个业务系统的设计往往需要你从数据库的层面抽离出来,把主要精力放在业务模型的设计上,在程序层面体现业务逻辑,而不是把业务逻辑都交给数据层面的管理者。前几天我排查过一个“Bug”:存储过程是输入参数是一个主键id的列表字符串,长度居然是 nvarchar(max),主要功能是根据id列表查询数据。我想说的是就算你是max的长度,也有超长的可能性发生,因为业务方传输什么参数,参数什么长度是你DB无法控制的,所以这类的业务一定要放在程序中做处理,而不是怀着侥幸心里丢给DB。 如果是抱着存储过程性能高的心态的话,我到时觉你这是误入歧途,菜菜认为存储过程从来都不是提高性能的关键,反而系统的架构,缓存的设计,数据一致性更是系统关键问题。 存储过程通常是一种解决方案,但是通常情况下不是唯一的解决方案,在选择存储过程作为方案前,请确保他们是正确的选择。最后秀一波存储过程吧 添加关注,查看更精美版本,收获更多精彩

July 16, 2019 · 1 min · jiezi

Linux下使用URLOS安装SqlServer2017

SqlServer能在Linux上安装吗?答案是可以!网络上也能找到很多Linux系统下安装SqlServer的相关文章,也许经过一些折腾,你也能成功在linux中安装sqlserver,但是其中可能会遇到非常多的坑。 今天我们介绍一种更高效的安装方法,那就是通过urlos一键安装SqlServer。urlos是什么? URLOS是一个云主机管理软件,基于Docker容器技术打包和运行应用,包含负载均衡和故障转移等高级功能,可自动识别机器和云应用的故障并将云应用转移至可用的机器上,单机故障并不影响业务开展。 你可以使用以下命令安装URLOS: curl -LO www.urlos.com/iu && sh iu在此不讨论URLOS的使用方法,感兴趣的朋友请自行搜索,我们直接来看URLOS如何快速安装SqlServer: 登录URLOS系统后台,在应用市场中搜索“mssql”,找到之后,直接点击安装按钮:在基本信息中填写服务名称等相关信息,端口号默认即可在数据库设置里我们填写SA用户的密码,模式暂且选择开发模式,然后点击提交即可提交后,系统立即开始部署应用了,因为sqlsever程序体积比较大,部署过程可能时间需要长一些,我们需要耐心等待一下。 部署完成后,我们可以使用windows中的mssql客户端进行连接,默认使用的用户名是sa账户,密码就是自己设置的密码。这里我们使用SqlDbx进行简单的连接测试:连接成功,我们的安装的SqlServer正常运行中。 通过以上几个步骤可以看到,在Linux下通过URLOS安装SqlServer简直太容易了。

July 6, 2019 · 1 min · jiezi

SQLServer之Case用法

定义计算条件列表,并返回多个可能的结果表达式之一。 表达式类型case具有两种格式: 简单case表达式,它通过将表达式与一组简单的表达式进行比较来确定结果。case搜索表达式,它通过计算一组布尔表达式来确定结果。这两种方式,都支持可选的 else参数,大部分情况下是可以实现相同的功能。case可用于允许使用有效表达式的任意语句或子句, 例如,可以在 select、update、delete和 set等语句以及 select_list、in、where、order by和 having等子句中使用 Case。 语法简单case表达式select case input_expression when when_expression then result_expression when when_expression then result_expression ...... else else_result_expressionend from databasename.dbo.tablename 示例 case搜索表达式select case when boolean_expression then result_expression when boolean_expression then result_expression ...... else else_result_expressionend end from databasename.dbo.tablename 示例 语法解析input_expression 使用简单 case格式时计算的表达式。 input_expression 是任何有效的表达式 。 when when_expression 使用简单 case格式时要与 input_expression 进行比较的简单表达式 。 when_expression 是任何有效的表达式 。input_expression 及每个 when_expression 的数据类型必须相同或必须是隐式转换的数据类型 。 then result_expression 当 input_expression = when_expression 的计算结果为 true时,或 boolean_expression 的计算结果为 true时返回的表达式 。 result expression 是任何有效的表达式 。 ...

July 2, 2019 · 1 min · jiezi

C-三个Timer

在C#中存在3种常用的 Timer : System.Windows.Forms.TimerSystem.Timers.TimerSystem.Threading.Timer零、System.Windows.Forms.Timer这个 Timer 是单线程的,也就是说只要它运行,其他线程就要等着。 这个 Timer 有如下特点: 完全基于UI线程,定时器触发时,操作系统把定时器消息插入线程消息队列中,调用线程执行一个消息泵提取消息,然后发送到回调方法Tick中;使用 Start 和 Stop 启动和停止 Timer;UI操作过长会导致 Tick 丢失;可以使用委托Hook Tick事件;精确度不高;通过将 Enabled 设置为 True,使 Timer 自动运行从上面的第一个特点可以得知,该 Timer 会造成 WinForm UI 假死,因此如果需要定时处理大量计算或者大量IO操作的任务,不建议使用该 Timer ,接下来我们看一个例子体会一下在IO操作的情况下出现的假死情况: 我们在Form中放入两个Button 一个Lable和一个Timer private void Button_Click(object sender, EventArgs e){ timer.Interval = 1000; timer.Tick += Timer_Tick; timer.Start();}private void Timer_Tick(object sender, EventArgs e){ for (int i = 0; i < 10000; i++) { File.AppendAllText(Directory.GetCurrentDirectory()+"test.txt", i.ToString()); this.label_output.Text = "当前操作:插入数字" + i; }}我们单击计算按钮,我们会发现WinForm出现了假死(无法移动窗口、按钮无法点击等) ...

July 1, 2019 · 2 min · jiezi

Entity-Framework-一对多关系映射

EF中关系映射也是一个很关键的内容,关系映射和属性映射一样,也是在 OnModelCreating 中配置映射。EF中的关系映射有如下三种: One-to-Many Relationship(一对多)Many-to-Many Relationship(多对多)One-to-One Relationship(一对一)我们今天先讲解 One-to-Many Relationship(一对一关系) 零、创建所需类所有实体类公用的抽象基类public abstract class Base{ public int Id { get; set; } public DateTime CreateTime { get; set; } public DateTime ModifiedTime { get; set; }}客户类和订单类public class Customer : Base{ public string Name { get; set; } public string Email { get; set; } public virtual ICollection<Order> Orders { get; set; }}public class Order : Base{ public byte Quanatity { get; set; } public int Price { get; set; } public int CoustomerId { get; set; } public virtual Customer Customer { get; set; }}一、One-to-Many Relationship创建Map映射类在编写代码之前,我们先分析一下客户和订单的关系。一个客户可以有多个订单,但一个订单只能属于一个客户,所以我们用到了EF中的 HasRequired,一个客户又存在多个订单,因此也使用到了 WithMany ,同时 Order 表中有 CustomerId 作为外键,因此我们用到了 HasForeignKey 。根据我们的分析,编写代码如下: ...

July 1, 2019 · 2 min · jiezi

控制反转依赖注入简明教程

在面向对象中IOC是一个重要的设计思想。这篇文章将带领大家快速掌握控制反转和依赖注入。 注:代码基于c#零、IocIoc 英文是 Inversion of Control,中文是控制反转。所谓控制反转,就是A类中有对B类方法的调用,我们调用之前一般都会先new,这样就增加了类和类之间的耦合度。为了降低耦合度,将A类对B类的的控制权交给Ioc容器,让双方都依赖Ioc容器。 一、DIDI 的英文是 Dependency Injection,中文是依赖注入。依赖注入是实现Ioc的一种方式,也是常用的方式。依赖注入的方式主要有三种:构造函数注入、接口注入 和 属性注入。(因为这篇文章知识一个简单的入门,因此我们不讲解这三种注入)我们来通过一个例子,来看一下依赖注入的好处: 故事:小吴是一个公司的CEO,每天都需要司机开车送他上下班,开始他只有一个司机,每次司机生病,他就只能自己开车上下班。因此小吴设立了一个司机部门,部门中有多名司机,由司机部门给小吴指派司机。 分析:从上面的故事可以分析得出,刚开始小吴是依赖者,司机是被依赖者,小吴依赖于小刚。后来通过增加司机部门这个Ioc容器,小吴和小刚之间的关系变为了,小吴依赖于司机部门。 我们通过代码看一下(这里使用到了 .NET 依赖注入容器 AutoFac): static void Main(string[] args){ //接小吴 IContainer driverCont = DriverDepartment(); //司机部门分配一个司机给CEO小吴 CE0_Wu wu = driverCont.Resolve<CE0_Wu>(); wu.Car(); Console.Read();}/// <summary>/// 司机部门/// </summary>/// <returns></returns>private static IContainer DriverDepartment(){ ContainerBuilder builder = new ContainerBuilder(); builder.RegisterType<CE0_Wu>(); builder.RegisterType<Driver>().As<IDriver>(); return builder.Build();}}/// <summary>/// 抽象以来/// </summary>public class Driver : IDriver{/// <summary>/// 开车/// </summary>public void Drive(){ Console.WriteLine("开车送老板");}}public interface IDriver{void Drive();}/// <summary>/// 小吴/// </summary>public class CE0_Wu{private IDriver driver;public CE0_Wu(IDriver driver){ this.driver = driver;}public void Car(){ driver.Drive();}}

July 1, 2019 · 1 min · jiezi

墨天轮DBASK技术专家邀请函

各位数据库管理员、工程师们: 大家好,感谢大家一直以来对墨天轮DBASK的支持。DBASK 是一个开放、互助、便捷的数据库问答社区。在遇到任何数据库疑难杂症都可在DBASK上提问,平台认证的技术专家免费在线解答,最后归档沉淀为一个开放的知识库。 最近注意到Oracle官方文档中部分视图已经没有了说明,MOS上很多文档也隐藏了起来,开源公司不断被资本收购,但是我们始终向往构建一个开放开源、互帮互助的社区环境。 现在诚挚邀请您成为DBASK的技术专家,与我们一起讨论交流回复数据库相关问题,创建一个开放互助的数据库技术社区。 另外,近几年来,TiDB、达梦、巨杉等国产数据库也在不断成长,砥砺前行,还有阿里、华为等云上数据库作为新兴力量的加入,相信未来国产数据库一定会大有作为。另外,我们也会陆续在DBASK中开放国产数据库的专区,特别欢迎国产数据库相关的专家入驻DBASK,为国产数据库添砖加瓦! 专家权利:a.可以看到平台上所有的问题,参与讨论或者学习b.身份象征:平台标注技术专家的标识c.定期邀请您参加我们的线下专家交流会d.赠送技术嘉年华等大会门票、文化衫、书籍e.在 DBASK上回答问题、上传技术文档等可以获得墨值,墨值可用于兑换话费、京东卡等等 (PS:成为专家后自动赠送50墨值)。 DBASK小程序: 随着用户的不断增多,为了用户使用更方便,DBASK发布了微信小程序。小程序的发布可以让大家随时随地提问,专家也可在小程序内即时回复,减少了提问的门槛,加快问题交互的流程。另外可以在微信小程序中浏览知识库,方便查找学习相关问题。 DBASK常驻专家团下面是墨天轮DBASK常驻专家团队(其中囊括了国内IT服务商中绝大部分的Oracle ACE和Oracle ACE总监级别的技术专家)。我们特别欢迎数据库管理员、工程师们入驻DBASK,为墨天轮DBASK专家团队注入新鲜的血液。 如何成为DBASK技术专家?网页登录DBASK:https://cs.enmotech.com/issue,点击右上角【申请成为专家】。即可加入墨天轮DBASK专家团队!(PS:审核通过后须重新登录)

June 18, 2019 · 1 min · jiezi

Entity-Framework-小知识四

在EF中并没有提供包含索引和过滤索引的创建方法,那么我们就么发创建了吗?答案是否定的,我们可以通过迁移类进行创建包含索引和过滤索引。首先我们通过 Add-Migration 命令创建一个空的迁移类,然后在 Up方法中输入如下代码: Sql($"CREATE NONCLUSTERED INDEX [{IndexName}] ON [dbo].[User]([Name] INCLUDE ([IdNumber]))");在 Down 方法中输入如下代码: DropIndex("dbo.User","IndexName")

June 18, 2019 · 1 min · jiezi

Entity-Framework-索引

Entity Framwework 6 设置和使用索引,是一个比较 egg 疼的事情,为什么这么说呢?因为Entity Framwework 6的不同版本有不同的设置和使用方法,按照版本来划分,有三种方法: EF6 方法EF6.1.x方法EF6.2.x方法EF6EF6中设置索引比较麻烦,我们需要先进行code first 迁移,然后在迁移类中的 Up 方法中输入如下代码: //创建索引且值唯一CreateIndex("dbo.User","Name",unique:true);//创建复合索引,索引名称为 **NameAndIdNumber**CreateIndex("dbo.User",new []{"Name","IdNumber"},name:"NameAndIdNumber");在 Down 方法中输入如下代码: DropIndex("dbo.User","Name");DropIndex("dbo.User",new []{"Name","IdNumber"});注:EF6中通过迁移类创建的索引无法重命名EF6.1.x该版本定义索引的方法如下: public virtual void OnModelCreating(DbModelBuilder modelBuilder){ modelBuilder.Entity<User>().Property(p => p.Name).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique=true }));}上面这段代码的意思是,给User表创建一个唯一索引Name。同样上面的代码也可以单独定义在一个类中: public class UserMap : EntityTypeConfiguration<User>{ public UserMap() { Property(p => p.Name).HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute() { IsUnique=true })); }}我们前面知道在EF6中创建的索引无法重命名,那么在EF6.1.x中创建的索引是否可以重命名吗?答案是当然可以,我们只需在前一类中的 Up 和 Down 方法写入如下代码即可: public override void Up(){ RenameIndex(table:"db.User",name:"Name",newName:"NameIndex");}public override void Down(){ RenameIndex(table:"db.User",name:"NameIndex",newName:"Name");}EF6.2.x在EF6.2.X中创建索引比较简单,只需要调用 HasIndex 方法即可。 ...

June 17, 2019 · 1 min · jiezi

Entity-Framework-小知识三

零、乐观并发在单服务器上运行的站点,为了防止出现脏读现象,我们一般使用Lock语句关键字,但是如果在分布式站点上使用Lock语句关键字是不起作用的,因为程序锁住了服务器1数据库实例,但服务器2并不知道服务器1已被锁住,这样依然会出现脏读现象。这时我们就用到了EF的乐观并发。 EF中解决并发有两种方式: 利用并发Token;利用行版本的方式代码如下: public class EfDbContext : DbContext{ public EfDbContext() { Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EfDbContext>()); } public virtual void OnModelCreating(DbModelBuilder modelBuilder) { // 利用并发Token modelBuilder.Entity<Users>().Property(t=>t.Name).IsConcurrencyToken(); // 利用行版本 modelBuilder.Entity<Users>().Property(t=>t.Name).IsRowVersion(); }}注:在并发量不是很大的时候可以使用EF的乐观并发,在访问量很大的时候应该使用其他技术处理并发问题。

June 14, 2019 · 1 min · jiezi

Entity-Framework-小知识二

零、基于代码配置基于代码配置是EF6新增的一个特性,操作步骤如下: 创建DbConfig派生类;配置默认连接工厂;设置Database Provider;设置数据库初始化器;1. 创建DbConfig派生类public class EF6Config:DbConfiguration{ public EF6Config(){}}接下来使用 DbConfigurationType 属性在上下文类中设置基于代码的配置类: [DbConfigurationType(typeof(EF6Config))]public partial class EF6DbContext:DbContext{ public EF6DbContext():base("name=EF6DbContext"){} }2. 配置默认连接工厂使用 SetDefaultConnectionFactory 方法设置默认连接工厂(以SQL SERVER 数据库为例): public class EF6Config:DbConfiguration{ public EF6Config() { this.SetDefaultConnectionFactory(new System.Data.Entity,Infrastructure.SqlConnectionFactory()); }}3. 设置Database Provider使用 SetProviderServices() 方法配置数据库提供程序: public class EF6Config:DbConfiguration{ public EF6Config() { this.SetDefaultConnectionFactory(new System.Data.Entity,Infrastructure.SqlConnectionFactory()); this.SetProviderServices("System.Data.SqlClient",System.Data.Entity.SqlServer.SqlProviderServices.Instance); }}4. 设置数据库初始化器在使用 code first 的情况下,可以使用基于代码的配置数据库的初始值: public class EF6Config:DbConfiguration{ public EF6Config() { this.SetDefaultConnectionFactory(new System.Data.Entity,Infrastructure.SqlConnectionFactory()); this.SetProviderServices("System.Data.SqlClient",System.Data.Entity.SqlServer.SqlProviderServices.Instance); this.SetDatabaseInitializer<EF6DbContext>(new CustomDBInitializer(EF6DbContext)()); }}注:.config 中 <entityframework> 的配置优于代码配置,也就是说,如果同时在 .config 中和代码中都设置了配置选项,则优先使用 .config 中的设置。

June 13, 2019 · 1 min · jiezi

Entity-Framework-约定

约定,类似于接口,是一个规范和规则,使用Code First 定义约定来配置模型和规则。在这里约定只是记本规则,我们可以通过Data Annotaion或者Fluent API来进一步配置模型。约定的形式有如下几种: 类型发现约定主键约定关系约定复杂类型约定自定义约定零、类型发现约定在Code First 中。我们定义完模型,还需要让EF上下文你知道应该映射那些模型,此时我们需要通过 DbSet 属性来暴露模型的。如果我们定义的模型由继承层次,只需要为基类定义一个DbSet属性即可(如果派生类与基类在同一个程序集,派生类将会被自动包含),代码如下: public class Department{ public int DepartmentId { get; set; } public string Name { get; set; } public virtual ICollection<Blog> Blogs { get; set; }}public class EfDbContext : DbContext{ public EfDbContext() { } public DbSet<Department> Departments { get; set; }}当然,有时候我们不希望模型映射到数据库中,这时我们可以通过Fluent API 来忽略指定的模型映射到数据库中,代码写在EF上下文中: protected override void OnModelCreating(DbModelBuilder modelBuilder){ modelBuilder.Ignore<Department>();}一、主键约定Code First 会根据模型中定义的id,推断属性为主键(如果类中没有id属性,会查找定义成类名称+id的属性,将这个属性作为主键)。如果主键类型是int 或者 guid 类型,主键将会被映射为自增长标识列。例如我们上一小节中定义的类 Department,类中没有名称为id的属性,但是存在名称为类名称+id的属性DepartmentId,因此DepartmentId属性,将会被映射为自增长的主键。如果一个类中既没有id属性,也没有类名+id的属性,那么代码在运行时将会报错,因为EF没有找到符合要求的字段创建主键。 二、关系约定在数据库中,我们可以通过多张表的关联查询出数据,这多张表之间的关联,就是他们的关系。同样,也可以在模型中定义这样的关系。EF中定义关系要使用到导航属性,通过导航属性可以定义多个模型之间的关系。大部分情况下我们会将导航属性和外键属性结合在一起使用。导航属性的命名规则如下:导航属性名称+主体主键名称 或者 主体类名+主键属性名称 或者 主体主键属性名。当EF检测出外键属性后,会根据外键属性是否为空来判断关系,如果外键可以为空,那么模型之间的关系将会配置成可选的,Code First 不会再关系上配置级联删除。看一个简单的代码: ...

June 13, 2019 · 2 min · jiezi

Entity-Framework复杂类型属性映射

零、创建项目必须代码public class BaseModel{ public int Id { get; set; } public DateTime CreateDateTime { get; set; }}public class Address{ public string Street { get; set; } public string City { get; set; } public string ZipCode { get; set; }}public class User:BaseModel{ public string Name {get;set;} public string Birthdate {get;set;} public string IdNumber {get;set;} public Address Address {get;set;}}以上代码在ORM中称为组合类,EF会将这两个类映射在一张表中。当Code First发现不能推断出类的主键,并且没有通过Data Annotations或Fluent API注册主键,那么该类型将被自动注册为复杂类型。 注意:复杂类型检测要求该类型不具有引用实体类型的属性,还要求不可引用另一类型的集合属性复杂类型的在数据库中映射的列名称为:负载类型类名_属性名我们接下来创建 DbContext 类 public class EfDbContext : DbContext{ public EfDbContext() { Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EfDbContext>()); } public DbSet<User> Users { get; set; }}创建完DbContext类后,我们编写将数据存入数据库的方法: ...

June 13, 2019 · 2 min · jiezi

Entity-Framewor简单属性映射

本节我们只介绍在EF中比较常见的映射 零、表名映射默认情况下可以不配置表名,我们的模型名称将会作为数据库的表名。但是大部分项目会要求数据库表名称的规范,例如我们要将模型 User 在数据库中映射为 Users,那么我们可以这么做,在派生类上下文中的 OnModelCreating 中进行如下定义: modelBuilder.Entity<User>().ToTbale("Users");一、主键映射表的主键我们一般习惯使用 Id 或者以 Id 结尾的方式来命名,EF默认情况下会将 Id 或以 Id 结尾的属性作为主键,如果两者都存在的话,默认会以 Id 作为主键。但是,还存在如下几种情况: 设置联合主键;主键为 int 类型,但是不是自增长的,而是手动分配的。针对上面两种情况,我们分别进行如下配置: //设置联合主键modelBuilder.Entity<User>().HasKey(k => new{ Id=k.Id, UserId=k.UserId});//手动分配主键值modelBuilder.Entity<User>().HasKey(k => k.Id).Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);DatabaseGeneratedOption 是枚举类型,值如下: 值说明Identity标识列Computed计算列None手动分配值二、数值映射数据库中的数值类型有很多种,C#中也有很多数值类型,但是我们无法直接将C#中的数值类型转换为数据库中的数值类型。那么怎么将C#数值类型映射为数据库数值类型呢?这里我们以 C# float 为例,来看一下代码: modelBuilder.Entity<User>().Property(p=>p.Float);通过上面的代码,我们将 C# float 类型映射为了数据库的 real 类型。下表是C#数值类型对应的数据库的数值类型: C#数值类型数据库数值类型intintdoublefloatfloatrealdecimaldecimal(18,2)Int64bigint我们看到上表中有一个C#数值类型 decimal 对应的数据库数值类型是 decimal(18,2) ,括号中的2代表小数点后保留2位,但是在一些情况下我们需要保留小数点后面N位,这时我们可以这么做: modelBuilder.Entity<User>().Property(p=>p.Money).HasPrecision(18,4);三、字符串映射当我们未对string类型的属性配置映射时,默认的数据库类型是 nvarchar(max),但是大部分情况下不会使用这个默认的映射。举几个例子来讲解一下怎么来改变这个默认映射。 字段不可为空//设置Name属性在数据库映射不可为空modelBuilder.Entity<User>().Property(p=>p.Name).IsRequired();字段可为空//设置Birthday属性在数据库映射可为空modelBuilder.Entity<User>().Property(p=>p.Birthday).IsOptional();四、日期映射EF中的日期类型在数据库中默认映射为Date,但是数据库中的日期类型还有很多,并且有时候我们需要将日期类型映射为数据库其他类型,那么我们该怎么做呢?这里我们以映射为 DateTime 为例: modelBuilder.Entity<User>().Property(p=>p.CreateDateTime).HasColumnType("DATETIME");注:数值类型和日期类型属于值类型,因此我们不需要通过 IsRequired 来配置映射字段不可为空,因为默认就是不为空的。但是可以通过 IsOptional 设置可为空。

June 13, 2019 · 1 min · jiezi

工作过程遇到数据库相关的知识点汇总

工作过程遇到的,或者平时学习的数据库相关的知识点汇总。 Home Oracle1 大数据量加载方法汇总2 大数据量更新方法3 去掉回车换行空格的方法4 系统参数详解5 dbms_application_info包6 FORALL与BULK COLLECT语句8 With As 的用法9 like运算符和转义操作符10 抛出自定义错误SQLServer1 SqlServer列与逗号分隔字符串互相转换2 查看sqlserver被锁的表以及如何解锁Mysql1 centos 7.2 mysql5.7 不区分表名大小写2 mysql5.7.x:this is incompatible with DISTINCT

May 30, 2019 · 1 min · jiezi

从零入门系列2Sprint-Boot-之-数据库实体类

文章系列【从零入门系列-0】Sprint Boot 之 Hello World【从零入门系列-1】Sprint Boot 之 程序结构设计说明前言本篇文章开始代码实践,系统设计从底向上展开,因此本篇先介绍如何实现数据库表实体类的设计实现。 SpringBoot数据库的持久层框架主要分为两种架构模式,即以JDBC Template为代表的SQL类和以Spring Data JPA为代表的ORM对象类。其中: Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!spring data jpa让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,自己写个仓储接口后继承JpaRepository即可实现最基本的增删改查功能!在使用@Entity进行实体类的持久化操作,当JPA检测到我们的实体类当中有@Entity 注解的时候,会在数据库中生成关联映射对应的表结构信息,因此针对本项目情况最底层的设计实现一个@Entity注解的书籍对象定义即可。 项目开始前,先按上一篇文章【从零入门系列-1】Sprint Boot 之 程序结构设计说明后台程序结构建立相对应的目录: 控制层:前端路由和后端处理关系处理,目录:Controller数据服务层:自定义对数据库的访问操作方法,目录:Service数据访问层:实现通用的数据库访问功能,SpringData的JPA方案,目录:Dao数据实体层:定义数据库表的属性方法,目录:Domain根据结构,我们需要在Domain目录下编写项目表实体类,右键Domain文件夹,New->Java Class。 编写实体类1.新建Book类 package com.arbboter.demolibrary.Domain; import javax.persistence.Entity; import javax.persistence.Table; /** * @Entity 注解该类为数据库表实体类,JPA可自动扫描识别到 * @Table 注解数据表信息,其中name指定表名 */ @Entity @Table(name = "library_book") public class Book{ }注意添加的类需要使用@Entity注解,其中@Table是可选的,默认不配置生成的表名和类名相同,如果上述类中不使用@Table,那么本类对应的表名为book。 2.添加表字段信息 public class Book{ /** * ID,唯一主键,按Alt+Enter可以快速导入引入 */ @Id @GeneratedValue private Integer id; /** * 书名 */ private String name; /** * 作者 */ private String author; /** * 封面 */ private String image; }@Id注解用于声明一个实体类的属性映射为数据库的主键列,该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。 ...

May 14, 2019 · 2 min · jiezi

Entity-Framework初体验

零、初体验新建控制台程序,名称为:MyFirstEF在NuGet中搜索 Entity Framework,如下图: 创建 Blog 类:public class Blog{ public int Id { get; set; } public string Name { get; set; } public string Url { get; set; } public DateTime? CreatedTime { get; set; } public double Double { get; set; } public float Float { get; set; }}创建一个继承自EF上下文的类,此上下文是与数据库交互的一个中间桥梁,我们可以称之为会话,并且为每一个模型公开一个DbSet:public class EfDbContext : DbContext{ public EfDbContext() { } public DbSet<Blog> Blogs { get; set; }}注:上下文派生类中定义DbSet有如下三种方式: //用DbSet属性public class EfDbContext : DbContext{ public EfDbContext() { } public DbSet<Blog> Blogs { get; set; }}//用IDbSet属性public class EfDbContext : DbContext{ public IDbSet<Blog> Blogs { get; set; }}//只读属性public class EfDbContext : DbContext{ public DbSet<Blog> Blogs { get {return Set<Blog>();} }}在主函数上添加如下代码:static void Main(string[] args){ using (var efDbContext = new EfDbContext()) { efDbContext.Blogs.Add(new Blog() { Name = "张三", Url = "http://www.baidu.com" }); efDbContext.SaveChanges(); }}运行控制台程序,如果未出现任何报错,则会在VS对应的本地数据库中看到新创建的 Blogs 表和一条新数据。 ...

May 14, 2019 · 1 min · jiezi

Entity-Framework简介

零、什么是Entity FrameworkEntity Framework (简称EF),是.NET的 Object/Relational Mapping 实体框架(简称ORM),可以在 SQL Server、MySQL、Oracle、等数据库上使用。可以将数据作为业务对象和实体进行操作,使用LINQ进行查询,使用C#进行操作和检索。 一、领域建模方式Entity Framework 有三种领域建模方式:Code First、Model First和Data First Code First Code First 可以通过类来描述模型,然后通过类来创建数据库,这种类简称为POCO(Plain Old CLR Object)。POCO中的C是指 .NET Framework公共语言运行时(Common Language Runtime,CLR)中的一个简单对象。POCO对域对象使用尽可能简单的类,可以包含属性、方法等,但是方法不能实现持久化逻辑,也就是说POCO也可以包含业务逻辑。Code First 优点如下: 可以创建一个更富有逻辑、更灵活的应用程序;因为没有自动生成难以修改的代码,所以我们可以对代码完全控制;只需要定义映射,其余一切交给Entity Framework来处理;可以用修改代码的方式来修改数据库;可以使用它来映射表结构到一个已存在的数据库。Model First Model First 允许我们使用实体设计器在空模型中创建模型实体,及其关系和继承层次结构,然后创建数据库。优缺点如下: 无法控制实体和数据库,因为自动生成的代码难以修改,但是对于小型且简单的项目,它仍行之有效;在实体中添加额外的功能,不得不修改T4模板或者使用部分类来完成;数据库模型的更改不是最佳选择,因为是由模型定义了数据库。Data First Data First 使我们能够从现有数据库创建模型,减少了自动生成代码所需编写的代码量,也限制了我们使用生成代码的结构。优缺点如下: 如果已有DBA设计的数据来单独开发或已存在数据库,将作为首选通过EDM向导为我们创建实体、关系和继承层次结构,修改映射后还可以生成实体;要在实体中添加额外的功能,必须通过T4修改模板或者使用部分类;数据库的手动更改变为可能,如果要修改数据库表结构,只需要从数据库更新实体模型即可。

May 11, 2019 · 1 min · jiezi

SQLServer之集合

集合的定义集合是由一个或多个元素构成的整体,在SQLServer中的表就代表着事实集合,而其中的查询就是在集合的基础上生成的结果集。SQL Server的集合包括交集(INTERSECT)、并集(UNION)、差集(EXCEPT)。交集(INTERSECT)可以对两个多个结果集进行连接,形成"交集"。返回左边结果集和右边结果集中都有的记录,且结果不重复(这也是集合的主要特性)交集限制条件子结果集要有相同的结构。 子结果集的列数必须相同。 子结果集对应的数据类型必须可以兼容。 每个子结果集不能包含order by和compute子句。交集语法select * from 结果集intersectselect * from 结果集交集示例select name from [testss].[dbo].[schema_table1]intersectselect name from [testss].[dbo].[test1]并集(UNION and UNION ALL)可以对两个或多个结果集进行连接,形成并集。子结果集所有的记录组合在一起形成新的结果集,其中使用UNION可以得到不重复(去重复)的结果集,使用UNION ALL会得到重复(不去重的结果集)。并集限制条件子结果集要具有相同的结构。子结果集的列数必须相同。子结果集对应的数据类型必须可以兼容。每个子结果集不能包含order by 和compute子句并集(UNION)语法select * from 结果集unionselect * from 结果集并集(UNION)示例select name from [testss].[dbo].[schema_table1]unionselect name from [testss].[dbo].[test1] 并集(UNION ALL)语法select * from 结果集union allselect * from 结果集并集(UNION ALL)示例select name from [testss].[dbo].[schema_table1]union allselect name from [testss].[dbo].[test1] 差集(EXCEPT)可以对两个或多个结果集进行连接,形成差集。返回左边结果集中已经有的记录,而右边结果集中没有的记录。差集限制条件子结果集要具有相同的结构。子结果集的列数必须相同。子结果集对应的数据类型必须可以兼容。每个子结果集不能包含Order by和compute子句。差集(EXCEPT)语法select * from 结果集exceptselect * from 结果集差集(EXCEPT)示例select name from [testss].[dbo].[schema_table1]exceptselect name from [testss].[dbo].[test1] 提示集合是我们数据处理过程中的理论基础,可以通过集合的观点去很好的理解不同的查询语句。每一个物理表就是一个集合,当我们要对表进行操作的时候,将它们看成对集合的操作就很好理解了。

April 3, 2019 · 1 min · jiezi

SQLServer之创建链接服务器

创建链接服务器注意事项当我们要跨本地数据库,访问另外一个数据库表中的数据时,本地数据库中就必须要创建远程数据库的DBLINK,通过DBLINNK数据库可以像访问本地数据库一样访问远程数据库表中的数据。链接服务器允许访问针对OLE DB数据源的分布式异构查询。创建链接服务器后,可以针对此服务器运行分布式查询,并且查询可以连接来自多个数据源的表。如果链接服务器被定义为SQL Server的实例,则可以执行远程存储过程。链接服务器的功能和必需参数可能会有很大差异。使用SSMS数据库管理工具创建DBLINK1、连接服务器-》展开服务器-》展开服务器对象-》展开链接服务器-》右键点击链接服务器-》点击新建链接服务器。2、在新建链接服务器弹出框-》点击常规-》输入链接服务器名称-》选择服务器类型。3、在新建链接服务器窗口-》点击安全性-》选择链接服务器的登陆类型-》添加或者删除登陆远程服务器的映射。4、在新建连接服务器弹出框-》点击服务器选项-》选择服务器选项的属性。5、在新建链接服务器弹窗框-》点击确定-》在对象资源管理器查看结果。使用SSMS数据库管理工具创建DBLINK语法–声明数据库引用use master;go –创建DbLink语法–第一步:定义DBLINK类型exec master.dbo.sp_addlinkedserver @server=‘链接服务器名称’,@srvproduct=‘SQL Server’;go–第二步:定义DBLINK连接属性–第一种安全性:不建立连接(删除下边的登陆)–第二种安全性:不使用安全上下文建立连接–exec master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N’链接服务器名称’, @locallogin = NULL , @useself = N’False’–go–第三种安全性:使用登录名的当前安全上下文建立连接–exec master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N’链接服务器名称’, @locallogin = NULL , @useself = N’True’–go–第四种安全性:使用此安全上下文建立连接–exec master.dbo.sp_addlinkedsrvlogin @rmtsrvname=‘链接服务器名称’,@locallogin=NULL,@useself=‘False’,@rmtuser=‘登录名’,@rmtpassword=‘密码’;–go–排序规则兼容exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’collation compatible’, @optvalue=N’true’ | N’false’go–数据访问exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’data access’, @optvalue=N’true’ | N’false’go–订阅服务器exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’dist’, @optvalue=N’true’ | N’false’go–发布服务器exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’pub’, @optvalue=N’true’ | N’false’go–RPCexec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’rpc’, @optvalue=N’true’ | N’false’go–RPC 超时exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’rpc out’, @optvalue=N’true’ | N’false’go–分发服务器exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’sub’, @optvalue=N’true’ | N’false’go–连接超时值exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’connect timeout’, @optvalue=N'0’go–排序规则名称exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’collation name’, @optvalue=nullgo–惰性架构验证exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’lazy schema validation’, @optvalue=N’true’ | N’false’go–查询超时值exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’query timeout’, @optvalue=N'0’go–使用远程排序规则exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’use remote collation’, @optvalue=N’true’ | N’false’go–为RPC启用针对分布式事务的升级exec master.dbo.sp_serveroption @server=N’链接服务器名称’, @optname=N’remote proc transaction promotion’, @optvalue=N’true’ | N’false’go语法解析第一步和第二步必须同时执行,后面DBLINK属性可以不写使用系统默认。示例:以我自己本机为例–声明数据库引用use master;go –创建DbLink语法–第一步:定义DBLINK类型exec master.dbo.sp_addlinkedserver @server=‘TANG\SQLEXPRESS’,@srvproduct=‘SQL Server’;go —-排序规则兼容–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’collation compatible’, @optvalue=N’false’–go—-数据访问–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’data access’, @optvalue=N’true’–go—-订阅服务器–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’dist’, @optvalue=N’false’–go—-发布服务器–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’pub’, @optvalue=N’false’–go—-RPC–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’rpc’, @optvalue=N’false’–go—-RPC 超时–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’rpc out’, @optvalue=N’false’–go—-分发服务器–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’sub’, @optvalue=N’false’–go—-连接超时值–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’connect timeout’, @optvalue=N'0’–go—-排序规则名称–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’collation name’, @optvalue=null–go—-惰性架构验证–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’lazy schema validation’, @optvalue=N’false’–go—-查询超时值–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’query timeout’, @optvalue=N'0’–go—-使用远程排序规则–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’use remote collation’, @optvalue=N’true’–go—-为RPC启用针对分布式事务的升级–exec master.dbo.sp_serveroption @server=N’TEST’, @optname=N’remote proc transaction promotion’, @optvalue=N’true’–go –第二步:定义DBLINK连接属性–第一种安全性:不建立连接(删除下边的登陆)–第二种安全性:不使用安全上下文建立连接–exec master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N’TANG\SQLEXPRESS’, @locallogin = NULL , @useself = N’False’–go–第三种安全性:使用登录名的当前安全上下文建立连接exec master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N’TANG\SQLEXPRESS’, @locallogin = NULL , @useself = N’True’go–第四种安全性:使用此安全上下文建立连接–exec master.dbo.sp_addlinkedsrvlogin @rmtsrvname=‘TANG\SQLEXPRESS’,@locallogin=NULL,@useself=‘False’,@rmtuser=‘tests’,@rmtpassword=‘1234’;–go示例结果:显示创建结果DBLINK使用示例SELECT * FROM [testss].[dbo].[test1] AS AINNER JOIN [TANG\SQLEXPRESS].[testss].[dbo].[test3] AS B ON A.classid=B.id结果DBLINK链接优缺点优点1、允许跨服务器访问。2、数据量少的情况下用dblink比较简单,迅速。3、可以执行远程存储过程等。缺点1、远程查询时易受网络等影响。2、链接稳定性较差。3、大量消耗数据库资源。4、可扩展性较差。5、维护性差、安全性较低。 ...

March 28, 2019 · 2 min · jiezi

MSSQL - 最佳实践 - 如何打码隐私数据列

摘要在SQL Server安全系列专题月报分享中,我们已经分享了:如何使用对称密钥实现SQL Server列加密技术、使用非对称密钥加密方式实现SQL Server列加密、使用混合密钥实现SQL Server列加密技术、列加密技术带来的查询性能问题以及相应解决方案和行级别安全解决方案这五篇文章,文章详情可以参见往期月报。本期月报我们分享使用SQL Server 2016 dynamic data masking实现隐私数据列的打码技术最佳实践。问题引入在平日的生活中,我们或多或少都经历过广告推销、电话诈骗,不厌其烦,甚至更为严重到银行卡号泄漏、身份证号泄漏等更为严重的情况。这个时候,于是我们就在想有没有技术手段来尽量或最大限度的保护我们隐私数据安全呢?答案是肯定的,SQL Server 2016版本首次引入了dynamic data masking来实现隐私数据列的打码技术,让我们一起来看看如何实现类似于手机号、身份证号、驾照号等隐私数据打码技术。原理分析数据列打码技术的本身我们并不陌生,就是将一些比较私密的数据信息隐藏起来,仅开放给有较高权限的用户查看完整数据。打码技术本身并不会对数据做任何的加密、解密等操作。严格意义上讲,数据打码不是一个完整的数据安全解决方案,但是它可以作为安全策略中重要的一环来有效避免用户隐私数据列的泄漏。让我们一起来看看在SQL Server 2016 dynamic data masking是如何实现的。实现方法创建测试数据库为了测试方便,我们专门创建了测试数据库TestDb。–Step 1 - Create MSSQL sample databaseUSE masterGOIF DB_ID(‘TestDb’) IS NULL CREATE DATABASE [TestDb];GO创建测试表首先,我们创建一张常规表CustomerInfo,来存放客户信息,其中,CustomerPhone列为用户隐私数据,存放了用户的手机号码。–Step 2 - Create Test Table, init recordsUSE [TestDb]GOIF OBJECT_ID(‘dbo.CustomerInfo’, ‘U’) IS NOT NULL DROP TABLE dbo.CustomerInfoCREATE TABLE dbo.CustomerInfo(CustomerId INT IDENTITY(10000,1) NOT NULL PRIMARY KEY,CustomerName VARCHAR(100) NOT NULL,CustomerPhone CHAR(11) NOT NULL);– Init TableINSERT INTO dbo.CustomerInfo VALUES (‘CustomerA’,‘13402872514’),(‘CustomerB’,‘13880674722’),(‘CustomerC’,‘13487759293’)GO创建测试用户为了方便观察和检查测试效果,我们创建一个测试账号DemoUser。– Step3: Create a DemoUser to testUSE [TestDb]GOCREATE USER DemoUser WITHOUT LOGIN;GRANT SELECT ON dbo.CustomerInfo TO DemoUser;GOEXECUTE AS USER = ‘DemoUser’;– Verify dataSELECT * FROM dbo.CustomerInfoREVERT常规情况下,测试账号,可以清清楚楚,明明白白看到用户所有数据,包含客户手机号这种关键的隐私数据。如果,这个用户有不轨之心是非常容易将这些信息泄漏、导出的,安全风险较大。客户手机号打码于是,我们想,如果能够将客户隐私数据,比如,电话号码(身份证号码、银行卡号等)打码的话,那么测试账号就无法查看到用户完整的数据信息了。打码方法如下:– Step4: Alter phone column add data maskUSE [TestDb]GOALTER TABLE dbo.CustomerInfoALTER COLUMN CustomerPhone ADD MASKED WITH(FUNCTION=‘partial(3, “****”, 4)’);由于CustomerPhone是11位数字,我们使用partial方法打码隐藏中间四位,打码符号使用星号,保留前三位和后四位数数字即可。查询打码列打码完毕,我们使用系统试图查看打码列和打码函数:– Step5. Query system view to check data maskSELECT db_name() as database_name, SCHEMA_NAME(schema_id) AS schema_name, tbl.name as table_name, c.name as column_name, c.is_masked, c.masking_function FROM sys.masked_columns AS c WITH (NOLOCK) INNER JOIN sys.tables AS tbl WITH(NOLOCK) ON c.[object_id] = tbl.[object_id] WHERE c.is_masked = 1 AND tbl.name = ‘CustomerInfo’;从结果可以看到我们已经将表TestDb.dbo.CustomerInfo中字段CustomerPhone打码,打码函数为partial(3, “**”, 4),结果展示如下所示:测试用户查看数据打码完毕后,再次使用DemoUser测试账号查看打码后的数据:– Step6: Demo user to query and verify dataUSE [TestDb]GOEXECUTE AS USER = ‘DemoUser’;– Verify dataSELECT * FROM dbo.CustomerInfoREVERT从查询结果展示来看,客户手机号码列中间四位已经成功打码了,测试账号已经无法获取到完整的客户电话号码了。修改打码符号有时候,有的人会说,我不喜欢星号,能否换个打码姿势,我更喜欢使用字母X。只要你喜欢,随便切换,方法如下:– Step7: What if I want to change the mask sign from * to XUSE [TestDb]GOALTER TABLE dbo.CustomerInfoALTER COLUMN CustomerPhone CHAR(11) MASKED WITH(FUNCTION=‘partial(3, “XXXX”, 4)’);现在打码符号变成了X,展示如下:新增隐私打码列现在我们需要增加一个新的列,用来存放用户email地址,也请同时打码。非常简单,新增列的时候使用email打码函数即可,如下所示:– Step8: and I want to add a new email mask columnALTER TABLE dbo.CustomerInfoADD Email varchar(100) MASKED WITH (FUNCTION = ’email()’) NOT NULL DEFAULT(‘demo.user@test.com’)查询打码列特定值有的人可能会问,手机号码被打码了,这个列会影响我的WHERE语句查询吗?当然不会,因为data mask技术本身并没有对数据做任何修改,只是在展示的时候,打码隐藏掉部分信息而已。– Step9: Demo user to query the specified phone customer infoUSE [TestDb]GOEXECUTE AS USER = ‘DemoUser’;– Verify dataSELECT * FROM dbo.CustomerInfoWHERE CustomerPhone = ‘13880674722’REVERT查询结果展示,手机号码和email地址始终被打码。拷贝存在打码列的表我们说data mask技术并没有加密、修改数据本身。到目前为止,测试账号DemoUser已经无法获取到客人的关键隐私数据了,那么他能够将用户数据Copy、导出吗?让我们做一个简单的测试,DemoUser将表CustomerInfo复制到一个新表CustomerInfo_copied中:– Step10: Ops, if I copy a new table from the data masked table, I can’t get the unmasked data now.USE [TestDb]GOGRANT CREATE TABLE TO DemoUser;GRANT ALTER ON SCHEMA::dbo TO DemoUser;EXECUTE AS USER = ‘DemoUser’;– Verify dataSELECT * INTO dbo.CustomerInfo_copiedFROM dbo.CustomerInfoREVERTGRANT SELECT ON dbo.CustomerInfo_copied TO DemoUser;EXECUTE AS USER = ‘DemoUser’;SELECT * FROM dbo.CustomerInfo_copiedREVERTDemoUser复制了客户信息数据到新表后,查看新表中的数据,依然是被打码的,测试用户无法导出、复制客人的隐私数据。达到了安全策略保护客户隐私数据的目的,展示结果如下:我想要在无码的世界如果有一天DemoUser成了高权限用户,确实需要查看客户隐私数据列,这个时候,我们可以给予测试账号unmask的权限,他就可以看到完整的客户数据了。方法如下:– Step 11: But, how can demo user to query the unmasked data?USE TestDBGOGRANT UNMASK TO DemoUser; EXECUTE AS USER = ‘DemoUser’; SELECT * FROM dbo.CustomerInfo; REVERT; – Removing the UNMASK permission REVOKE UNMASK TO DemoUser;此时,DemoUser查询到的数据,是非常完整的客人数据。删掉打码删除打码,让所有用户回归无码的世界。– Step 12: all the demos have been done, it’s time to drop the mask.USE TestDBGOALTER TABLE dbo.CustomerInfo ALTER COLUMN CustomerPhone DROP MASKED; 最后总结本期月报我们分享了使用SQL Server 2016引入的新特性dynamic data masking实现客户数据打码技术,防止未授权用户查看、导出用户关键隐私数据,最大限度保证用户数据安全性。本文作者:风移阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

March 27, 2019 · 2 min · jiezi

视图是什么?游标是什么?

答:视图是一种虚拟表,虚拟表具有和物理表相同的功能,可以对虚拟表进行增该查操作;视图通常是一个或多个表的行或列的子集;视图的结果更容易理解(修改视图对基表不影响),获取数据更容易(相比多表查询更方便),限制数据检索(比如需要隐藏某些行或列),维护更方便。游标对查询出来的结果集作为一个单元来有效的处理,游标可以定位在结果集的特定行、从结果集的当前位置检索一行或多行、可以对结果集中当前位置进行修改、视图的基础知识视图是从一个或多个表中查询数据的另外一种方式。利用试图,用户可以集中、简化、定制数据库,同时还可以提供安全保证。如果我们经常需要从多个表中获取特定列的数据,并需要将这些数据组织在一起使用,就需要使用到视图。视图简介视图是一个虚拟表。也就是说,对于用户来说,视图在外观和行为上都类似于表,但他不需要实际的物理存储。试图实际上是由预定义查询形式的表组成的。举例来说,从表EMPLOYEE里创建一个视图,它只包含雇员的姓名和地址,而不是表里的全部字段。试图可以包含表的全部或部分记录,可以由一个表或多个表创建。视图是从一个或多个表中导出的表,其结构和数据是建立在对标的查询基础上的。和表一样,视图也是包括几个被定义个数据列和多个数据行,但就本质而言,这些数据列和数据行来源于它所引用的表。所以视图不是真实存在的基础表,而是一张虚表。通过视图看到的数据只是存放在基本表中的数据。对视图的操作与对表的操作一样,我们可以对其进行查询、修改(有一定的限制)和删除。当我们对视图中国的数据进行修改时,相应的基本表数据也要发生变化;同时,如果基本表的数据发生变化,那么这种变化也可以自动地反应到视图中。视图是一种数据库对象,它是从一个或多个表或视图中导出的虚表,即它可以从一个或多个表中的一个或多个列中提取器数据,并按照表的组成行和列来显示这些信息。视图在数据库中存储的是视图的定义,而不是查询的数据。通过这个视图的定义,对视图的查询最后转化对基本表的查询。视图的数据并不是实际地以视图结构存储在数据中的,而是在试图所引用的表中。试图被定义后,便存储在数据库中,通过试图看到的数据只是存放在数据库表中的数据,其结构和数据都是建立在对表的查询的基础上的。视图的优缺点视图有很多优点,主要体现在简化操作、定制数据、合并分割数据、安全性等方面。简化操作。试图大大地简化了用户对数据的操作。在帝国一视图时,试图本身就可以是一个复杂的结果集。因此,在每一次执行相同的查询时,不必重新写这些复杂的查询语句,只要一条简单的查询语句即可。定制数据。试图能够让不同的用户,以不同的方式看到不同或相同的数据集。因此,当许多不同水平的用户共用同一数据库时,这显得极为重要。比如,我们想让公司的用户访问某些职员记录,但不想让这些用户获得诸如医疗卡号或工资之类的信息,那么就可以创建一个视图,只为他们提供应该看到的信息。合并分割数据。在有些情况下,由于表中数据量太大,在表的设计时,常将表进行水平分割,但表的结构的变化却会对应用程序产生不良的影响。使用视图就可以重新保持原有的结构关系,从而使外模式保持不变,原有的应用程序仍可以通过视图来重载数据。安全性。试图可以作为一种安全机制。通过视图,用户只能查看和修改他们所能看到的数据。其他数据库或表及不可见,也不可访问。如果某一用户想要访问视图的结果集,必须授予其访问权限。视图所引用表的访问权限与视图权限的设置互不影响。使用视图主要有两个缺点:性能。由于视图是虚拟的表,在使用包括视图引用的SQL语句时,数据库除了执行所键入的SQL语句中的查询或更新之外,还要告诉DBMS执行定义视图的查询,这就影响了查询效率。更新限制。不是所有的视图都是可更新的。目前,SQL将可更新的视图限制为基于单个表的,并且没有GROUP BY 或者HAVING子句的查询。除此之外,为了使视图时可更新的,试图不能使用聚集函数,计算的列或SELECT DISTINCE子句。由于SQL对更新视图的限制,用户不能总是用视图来代替表。另外,在使用视图的情况下,我们要综合考虑使用视图的优势和DBMS每次执行创建视图的SQL语句引起的性能损失。注意:必须是sysadmin、db_owner、db_ddladmin角色的成员,或拥有创建视图的权限。只能在当前数据库中创建视图,在视图中最多只能引用1024列。如果视图引用的基表或者视图被删除,则该视图将不能再被使用。如果视图中的某一列是函数、数学表达式、常量或者与来自多个表的列名相同,则必须为列定义名称。不能在规则、默认、触发器的定义中使用视图。当通过视图图查询数据时,SQL Server要检查以确保语句中涉及的所有数据库对象存在视图的名称必须遵循标识符的规则,是唯一的。视图的创建和销毁CREATE VIEW/DROP VIEW基本创建语法视图的创建主要由CREATE VIEW关键字实现,其数据则由SELECT语句定义。视图创建后,在数据字典中只存放视图的定义,而其中的SELECT语句并不执行。只有当用户对视图进行操作时,才按照视图的定义将数据从基本表中取出。创建简单的视图创建与表具有相同信息的视图CREATE VIEW StudentInfo_View AS SELECT * FROM StudentInfo–查看视图的数据SELECT * FROM StudentInfo_View为试图创建视图实际上,我们也可以把试图看成是一个表,还可以为视图创建视图。CREATE VIEW Boy_View AS SELECT * FROM StudentInfo_View WHERE sex=’男’查看视图的数据SELECT * FROM Boy_View由于视图是一个虚表,当表被删除时,由该表创建的视图,或视图的视图都不可用。为表中的一列或者几列信息创建视图CREATE VIEW NameAddress_View AS SELECT sname,address FROM StudentInfo–查看视图的数据SELECT * FROM NameAddress_View用户可以通过创建视图进行数据查询。例如,一个表有5列,有成千上万行,而用户需要使用表中的两行数据,这时,我们可以为这两列创建一个试图,在视图中查询需要的数据,这样会大大提高查询效率。创建与表具有不同字段名的视图前面实例创建的视图,并没有指明视图的字段名,系统就默认为表相同的字段名。实际上,创建视图时,我们也可以为表中的数据定义新的字段名。实际应用时,我们要注意新定义的字段名与表中数据的对应关系。使用视图简化表的复杂连接视图的一个重要用途就是进行复杂的SQL数据处理。通过创建视图,我们可以实现多表之间的复杂连接。将频繁使用的连接定义成视图后,用户就不必每次使用时都要指定复杂的连接条件了。CREATE VIEW Join_View AS SELECT sname,dname,score FROM StudentInfo,Department,RecruitInfo WHERE StudentInfo.address=RecruitInfo.address AND StudentInfo.dno=Department.dno–查看使徒的数据SELECT * FROM Join_ViewCREATE VIEW Boys_View AS SELECT * FROM StudentInfo WHERE sex=‘男’SELECT * FROM Boys_ViewCREATE VIEW Score_View(sno,sname,sex,address,dno) AS SELECT StudentInfo.* FROM StudentInfo,RecruitInfo WHERE StudentInfo.address=RecruitInfo.address AND RecruitInfo.score>550SELECT * FROM Score_ViewCREATE VIEW BoyScore_ViewAS SELECT * FROM Score_View WHERE sno IN (SELECT sno FROM Boy_View)SELECT * FROM BoyScore_ViewCREATE VIEW Result_View(sname,dname) AS SELECT BoyScore_View.sname,Department.dname FROM BoyScore_View,Department WHERE BoyScore_View.dno=Department.dnoSELECT * FROM Result_View由此可见,通过创建视图层层分解,多表的复杂查询变得简洁、清楚视图的销毁DROP VIEW view_name强调一点,视图在物理上是不存在的,它实际上只是一个查询结果,是一个被存储的查询。与创建表CREATE TABLE语句不同,CREATE TABLE语句在系统目录中保存表,而CREATE VIEW语句只保存视图的定义。所以DROP VIEW语句删除试图时,删除的也只是视图的定义,对实际表中的数据并没有任何影响。原则和表一样,视图必须有唯一的的名字。不仅视图之间不允许有相同的名字,并且视图和表也不允许拥有相同的名字。视图的创建个数不受限制,用户可以创建任意多个视图。用户要创建视图,必须从数据库管理员那里得到创建权限试图可以嵌套,即可以创建视图的视图一些数据库管理系统禁止用户在查询语句中使用ORDER BY子句。WITH CHECK OPTION这是CREATE VIEW语句里的一个选项,其目的是确保全部的UPDATE和INSERT语句满足视图定义里的条件。如果他们不满足条件,UPDATE或INSERT语句就会返回错误。WITH CHECK OPTION本身具有两个选项:CASCADED和LOCAL。其中,CASCADED是默认选项。在基于视图创建另一个视图时,在对基表进行更新时,CASCADED选项会检查所有底层视图、所有完整性约束,以及新视图的定义条件。LOCAL选项只检查两个试图的完整性约束和新视图的定义条件,不检查底层的表。WITH CHECK OPTION实际上通过查看视图定义是否被破坏来确保引用完整性。CREATE VIEW Stu_sname_View AS SELECT * StudentInfo WHERE sname IS NOT NULL WITH CHECK OPTION在这个范例中,WITH CHECK OPTION 会确保视图的sname字段里不包含NULL值,因为视图定义所依赖的数据里不允许在sname字段里包含NULL。从视图创建表CREATE TABLE TABLE_NAME AS SELECT COLUMN1,COLUMN2 FROM VIEW_TABLE视图与ORDER BY子句CREATE VIEW语句里不能包含ORDER BY子句,但是GROUP BY子句用于CREATE VIEW语句时,可以起到类似ORDER BY子句的作用。CREATE VIEW NAME2 AS SELECT LAST_NAME ….FROM EM_TABLE GROUP BY LAST_NAME什么是异名异名就是表或视图的另一个名称。我们创建别名通常是为在访问其他用户的表或视图时不必使用完整限制名。异名可以创建为PUBLIC或PARIVATE,PUBLIC的异名可以被数据库里的其他用户使用,而PRIVATE异名只能被所有者和拥有权限的用户使用。异名由数据库管理员(或某个指定的人员)或个人用户管理。一般来说,全部不拥护都可以创建PRIVATE异名,而只有数据库管理员(DBA)或被授权的用户可以创建PUBLIC异名。创建异名|删除异名CREATE PUBLIC|PRIVATE SYSNONYM S_NAME FOR TABLE|VIEWDROP PUBLIC|PRIVATE SYSNONYM S_NAME理解SQL游标SQL中的一个定义特征时SQL数据库中的数据十一级和的方式来进行管理的。实际上SELECT语句的查询结果就是结果集。它由从一个或多个数据表中提取的一行或多行组成。应用程序语言一般来说并不能够处理以集合形式返回的数据,这样在SQL和程序设计语言之间聚会存在阻抗失配。阻抗失配是指SQL和其他的程序设计语言之间的差别。SQL解决这类阻抗失配的方法就是使用游标。游标充当指针的作用,使应用程序语言一次只能处理查询结果中的一行。尽管游标能遍历查询结果中的所有行。但它一次只指一行。游标返回一个完整的结果集,但允许程序设计语言只调用集合中的一行。 ...

March 27, 2019 · 1 min · jiezi

什么是事务?什么是锁?

答:事务是指一个工作单元,它包含了一组数据操作命令,并且所有的命令作为一个整体一起向系统提交或撤消请求操作,即这组命令要么都执行,要么都不执行。锁是在多用户环境中对数据的访问的限制。SqlServer自动锁定特定记录、字段或文件,防止用户访问,以维护数据安全或防止并发数据操作问题,锁可以保证事务的完整性和并发性。事务事务的概念:数据库中的事务是数据库并发控制的基本单位,一条或者一组语句要么全部成功,对数据库中的某些数据成功修改; 要么全部不成功,数据库中的数据还原到这些语句执行。事务必须具备以下四个属性,简称ACID 属性:原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行一致性(Consistency):当事务完成时,数据必须处于一致状态隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性事务被分为3类常见的事务:自动提交事务:是SQL Server默认的一种事务模式,每条Sql语句都被看成一个事务进行处理,你应该没有见过,一条Update 修改2个字段的语句,只修该了1个字段而另外一个字段没有修改。。显式事务:T-sql标明,由Begin Transaction开启事务开始,由Commit Transaction 提交事务、Rollback Transaction 回滚事务结束。隐式事务:使用Set IMPLICIT_TRANSACTIONS ON 将将隐式事务模式打开,不用Begin Transaction开启事务,当一个事务结束,这个模式会自动启用下一个事务,只用Commit Transaction 提交事务、Rollback Transaction 回滚事务即可。事务中常用的语句:Begin Transaction:标记事务开始。Commit Transaction:事务已经成功执行,数据已经处理妥当。Rollback Transaction:数据处理过程中出错,回滚到没有处理之前的数据状态,或回滚到事务内部的保存点。Save Transaction:事务内部设置的保存点,就是事务可以不全部回滚,只回滚到这里,保证事务内部不出错的前提下。同时增加三个城市示例:begin tran tran_R_City –开始事务declare @tran_error int;set @tran_error=0;begin try insert into R_City values(‘新疆’,‘xinjiang’,1,0,‘2019-03-21’,1,‘XJ’) insert into R_City values(‘深圳’,‘shenzhen’,1,0,‘2019-03-21’,1,‘SZ’) insert into R_City values(‘广西’,‘guangxi’,1,0,‘2019-03-21’,1,‘GX’)end trybegin catchset @tran_error=@tran_error+1;–加分号或不加都能正常执行end catchif(@tran_error>0)begin rollback tran ;–执行出错,回滚事务(不指定事务名称) print @tran_error;endelsebegin commit tran ;–没有异常,提交事务(不指定事务名称) print @tran_error;End结果:银行卡转账示例:create table bank(customer varchar(20), –客户姓名currentMoney money –当前余额)–银行规定:每个卡上必须要有元钱alter table bankadd constraint CK_BANK_CURRENTMONEY check(currentMoney>=1); –模拟两个用户insert into bank values(‘张三’,1000);insert into bank values(‘李四’,1);select * from bank; –李四找张三借元钱–(1)将张三的余额减少update bank set currentMoney =currentMoney-1000 where customer=‘张三’;select @@error; –返回如果不为,表示上面的SQL语句执行有问题。–(2)将李四的余额要增加update bank set currentMoney =currentMoney + 1000 where customer=‘李四’;select @@error; –返回如果不为,表示上面的SQL语句执行没有问题。–事务:将需要做一件事情的所有步骤当做一个整体执行,要么所有步骤都执行,要么一个步骤都不执行。–显示事务(常用):–(1)开始事务:begin transaction;–(2)提交事务:commit transaction;–(3)回滚事务:rollback transaction; –隐性事务:SET IMPLICIT_TRANSACTIONS ONSET IMPLICIT_TRANSACTIONS OFFdelete from bank where customer=‘李四’;select * from bank;delete from bank; –自动提交事务:这是SQL Server 的默认模式,它将每条单独的T-SQL 语句视为一个事务,如果成功执行,则自动提交;如果错误,则自动回滚–转账出现了问题,如果解决?要使用事务–决定什么时候提交事务?什么时候回滚事务?需要根据@@error的值来决定。—@@error 只记录上一条SQL语句的执行状态如果成功,返回,如果不成功,返回非的值–第一步:开启事务begin transaction;declare @myerror int –声明一个变量,用来记录所有SQL语句执行完成后的状态值set @myerror=0 –默认为表示无错误–(1)将张三的余额减少update bank set currentMoney =currentMoney-1000 where customer=‘张三’;set @myerror=@myerror+@@error;–(2)将李四的余额要增加update bank set currentMoney =currentMoney + 1000 where customer=‘李四’;set @myerror=@myerror+@@error;if(@myerror<>0)beginprint ‘对不起,转账未成功!’ –第二步:回滚事务rollback transaction;end;elsebeginprint ‘恭喜您,转账成功’ –提交事务commit transaction ;end;goprint ‘转账后的状态为:’ goselect * from bank;使用set xact_abort设置 xact_abort on/off , 指定是否回滚当前事务,为on时如果当前sql出错,回滚整个事务,为off时如果sql出错回滚当前sql语句,其它语句照常运行读写数据库。 需要注意的时:xact_abort只对运行时出现的错误有用,如果sql语句存在编译时错误,那么他就失灵啦。delete tran_R_City –清空数据set xact_abort offbegin tran –语句正确 insert into R_City values(‘新疆’,‘xinjiang’,1,0,‘2019-03-21’,1,‘XJ’) –IsShow为int类型,出错,如果1..那个数据换成'132dsaf’ xact_abort将失效 insert into R_City values(‘深圳’,‘shenzhen’,1,0,‘2019-03-21’,1,‘SZ’) –语句正确 insert into R_City values(‘广西’,‘guangxi’,1,0,‘2019-03-21’,1,‘GX’)commit transelect * from tran_R_City锁在多用户都用事务同时访问同一个数据资源的情况下,就会造成以下几种数据错误。更新丢失:多个用户同时对一个数据资源进行更新,必定会产生被覆盖的数据,造成数据读写异常。不可重复读:如果一个用户在一个事务中多次读取一条数据,而另外一个用户则同时更新啦这条数据,造成第一个用户多次读取数据不一致。脏读:第一个事务读取第二个事务正在更新的数据表,如果第二个事务还没有更新完成,那么第一个事务读取的数据将是一半为更新过的,一半还没更新过的数据,这样的数据毫无意义。幻读:第一个事务读取一个结果集后,第二个事务,对这个结果集经行增删操作,然而第一个事务中再次对这个结果集进行查询时,数据发现丢失或新增。锁定,就是为解决这些问题所生的,他的存在使得一个事务对他自己的数据块进行操作的时候,而另外一个事务则不能插足这些数据块。这就是所谓的锁定。锁定从数据库系统的角度大致可以分为6种:共享锁(S):还可以叫他读锁。可以并发读取数据,但不能修改数据。也就是说当数据资源上存在共享锁的时候,所有的事务都不能对这个资源进行修改,直到数据读取完成,共享锁释放。排它锁(X):还可以叫他独占锁、写锁。就是如果你对数据资源进行增删改操作时,不允许其它任何事务操作这块资源,直到排它锁被释放,防止同时对同一资源进行多重操作。更新锁(U):防止出现死锁的锁模式,两个事务对一个数据资源进行先读取在修改的情况下,使用共享锁和排它锁有时会出现死锁现象,而使用更新锁则可以避免死锁的出现。资源的更新锁一次只能分配给一个事务,如果需要对资源进行修改,更新锁会变成排他锁,否则变为共享锁。意向锁:SQL Server需要在层次结构中的底层资源上(如行,列)获取共享锁,排它锁,更新锁。例如表级放置了意向共享锁,就表示事务要对表的页或行上使用共享锁。在表的某一行上上放置意向锁,可以防止其它事务获取其它不兼容的的锁。意向锁可以提高性能,因为数据引擎不需要检测资源的每一列每一行,就能判断是否可以获取到该资源的兼容锁。意向锁包括三种类型:意向共享锁(IS),意向排他锁(IX),意向排他共享锁(SIX)。架构锁:防止修改表结构时,并发访问的锁。大容量更新锁:允许多个线程将大容量数据并发的插入到同一个表中,在加载的同时,不允许其它进程访问该表。然而数据库并没有出现无限等待的情况,是因为数据库搜索引擎会定期检测这种状况,一旦发现有情况,立马选择一个事务作为牺牲品。牺牲的事务,将会回滚数据。有点像两个人在过独木桥,两个无脑的人都走在啦独木桥中间,如果不落水,必定要有一个人给退回来。这种相互等待的过程,是一种耗时耗资源的现象,所以能避则避。哪个人会被退回来,作为牺牲品,这个我们是可以控制的。控制语法:set deadlock_priority <级别>死锁处理的优先级别为 low<normal<high,不指定的情况下默认为normal,牺牲品为随机。如果指定,牺牲品为级别低的。还可以使用数字来处理标识级别:-10到-5为low,-5为normal,-5到10为high。减少死锁的发生,提高数据库性能死锁耗时耗资源,然而在大型数据库中,高并发带来的死锁是不可避免的,所以我们只能让其变的更少。1.按照同一顺序访问数据库资源,上述例子就不会发生死锁啦2.保持是事务的简短,尽量不要让一个事务处理过于复杂的读写操作。事务过于复杂,占用资源会增多,处理时间增长,容易与其它事务冲突,提升死锁概率。3.尽量不要在事务中要求用户响应,比如修改新增数据之后在完成整个事务的提交,这样延长事务占用资源的时间,也会提升死锁概率。4.尽量减少数据库的并发量。5.尽可能使用分区表,分区视图,把数据放置在不同的磁盘和文件组中,分散访问保存在不同分区的数据,减少因为表中放置锁而造成的其它事务长时间等待。6.避免占用时间很长并且关系表复杂的数据操作。7.使用较低的隔离级别,使用较低的隔离级别比使用较高的隔离级别持有共享锁的时间更短。这样就减少了锁争用。参考资料:浅谈SQL SERVER中事务的ACIDSQL Server中的事务与锁T-SQL查询进阶—理解SQL Server中的锁 ...

March 25, 2019 · 1 min · jiezi

引用两个或多个数据库里的数据,项目数据库的配置方法

1、首先配置两个数据源(数据库)以及一个动态数据库: <!– 数据源1 spring自带的 –> <bean id=“dataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”> <!– 这里的driverClassName指的是数据库驱动这里要根据使用的数据库进行更改这里使用的SQLServer数据库 –> <property name=“driverClassName” value=“com.microsoft.sqlserver.jdbc.SQLServerDriver”></property> <!– 这里url主要说明的数据库的位置和调用那个数据库其中jdbc后面是位置而DatebaseName所说的是数据库的名称 –> <property name=“url” value=“jdbc:sqlserver://数据库ip地址:端口号;DatabaseName=数据库1名称;?useUnicode=true&amp;characterEncoding=UTF-8” /> <!– 下面的2行username和password主要是说明的登录的用户名和密码这里根据项目的不同进行修改 –> <property name=“username” value=“数据库连接账号”></property> <property name=“password” value=“数据库连接密码”></property> </bean> <!– 数据源2–> <bean id=“dataSource2” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”> <!– 这里的driverClassName指的是数据库驱动这里要根据使用的数据库进行更改这里使用的SQLServer数据库 –> <property name=“driverClassName” value=“com.microsoft.sqlserver.jdbc.SQLServerDriver”></property> <!– 这里url主要说明的数据库的位置和调用那个数据库其中jdbc后面是位置而DatebaseName所说的是数据库的名称 –> <property name=“url” value=“jdbc:sqlserver://数据库ip地址:端口号;DatabaseName=数据库2名称;?useUnicode=true&amp;characterEncoding=UTF-8” /> <!– 下面的2行username和password主要是说明的登录的用户名和密码这里根据项目的不同进行修改 –> <property name=“username” value=“数据库连接账号”></property> <property name=“password” value=“数据库连接密码”></property> </bean> <!–配置动态数据库–> <bean id=“dynamicDataSource” class=“com.datasource.DynamicDataSource” > <property name=“targetDataSources”> <map key-type=“java.lang.String”> <entry value-ref=“dataSource” key=“dataSource”></entry> <entry value-ref=“dataSource2” key=“dataSource2”></entry> </map> </property> <property name=“defaultTargetDataSource” ref=“dataSource” > </property> </bean>2、sqlSessionFactory引用的数据库是动态数据库dynamicDataSource:<!– 扫描mybatis的配置结合上面的DataSource,会生成一个sqlFactory。这里一般来说不用改 –> <bean id=“sqlSessionFactory” class=“org.mybatis.spring.SqlSessionFactoryBean”> <property name=“dataSource” ref=“dynamicDataSource” /> <!– 将mybatis的配置文件引入 –> <property name=“configLocation” value=“classpath:myBatisConfig.xml”></property> </bean>4、事务管理这里要管理的也是上面配置的dynamicDataSource动态数据库:<!– 配置了事务的管理。一般来说不用改 –> <bean id=“txManager” class=“org.springframework.jdbc.datasource.DataSourceTransactionManager”> <property name=“dataSource” ref=“dynamicDataSource”></property> </bean>5、写两个数据源配置类DataSourceContextHolder.java和DynamicDataSource.java来配置数据源,利用ThreadLocal解决线程安全问题。DataSourceContextHolder 类:package com.datasource;public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); }}DynamicDataSource 类继承 AbstractRoutingDataSource,并实现determineCurrentLookupKey方法:package com.datasource;import java.sql.SQLFeatureNotSupportedException;import java.util.logging.Logger;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource { @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { // TODO 自动生成的方法存根 return null; } @Override protected Object determineCurrentLookupKey() { // TODO 自动生成的方法存根 return DataSourceContextHolder.getCustomerType(); }}6、最后就可以在需要切换数据库的地方使用以下方法来切换数据库了,要切换的数据库名字即之前在配置动态数据库时给引用的数据库赋的名字:DataSourceContextHolder.setCustomerType(“要切换的数据库名字”);7、下面附上我的目录结构:注:每次使用完切换数据库的方法后,系统会自动切换回默认数据库,不过这之间存在一点小延迟,会出现在调用完切换数据库的方法后,立刻去跳转到引用另外一个数据库数据的页面,系统还是使用着切换后的数据库。解决办法:可以在使用完切换数据库的方法拿到需要的数据后,再次调用 DataSourceContextHolder.setCustomerType() 方法切换回接下来需要用到的数据库。 ...

March 18, 2019 · 1 min · jiezi

无法启动Sql Server服务

本文首发地址为hilsion的博客 今天遇到一个无法启动SQL Server服务的问题,具体报错如下: 根据错误提示,去到WINDOWS的事件查看器。在WIN10上,右击右下角的菜单图标: 然后依次点击Windows日志=>应用程序,根据来源找到MSSQLSERVER,再根据错误提示上的错误码找到17051: 双击后可查看日志信息,如下: 至此,原因已经很明显了。在安装SQL Server时,如果不指定密钥而选择使用Evaluation版本时,是有180天的评估期限。这时候,需要填写密钥进行升级,即可。 具体操作是,打开SQL Server安装中心: 然后选择维护,再依次填写密钥,一步一步执行升级即可。在升级过程中,笔者遇到一个错误: 提示无法启动服务,这是因为笔者禁用了一些SQL Server的服务,在服务里面设置这些禁用的服务为自动重试即可。

March 12, 2019 · 1 min · jiezi

对话 CTO〡和 PingCAP CTO 黄东旭聊开源数据库新蓝海

专栏介绍「对话 CTO」是极客公园的一档最新专栏,以技术人的视角聊聊研发管理者的发展和成长。本专栏由ONES 的创始人&CEO 王颖奇作为特邀访谈者。王颖奇曾参与金山软件 WPS、金山毒霸等大型软件的核心开发工作;2011 年创立了正点科技,旗下产品正点闹钟、正点日历在全球用户过亿;2014 年,王颖奇在知名美元基金晨兴资本任 EIR,并以个人身份参与十余家公司的管理咨询工作;2015 年,王颖奇创立 ONES,致力于提供企业级研发管理解决方案。摘要有像甲骨文这样的统治级巨头在,数据库市场还是个好的创业领域吗?在 PingCAP 联合创始人&CTO 黄东旭眼中,答案是肯定的,数据库行业的转折点已经到了。黄东旭曾在豌豆荚从事 infrastructure 相关工作,在分布式存储领域有着多年的积累和实战经验。在他看来,伴随着分布式数据库理念和技术的成熟,对传统数据库理念和技术的依赖正在走向瓦解。开源理念的普及也在加速数据库行业走向下一个阶段,「像数据库、操作系统、云技术,或者云内部的基础软件,未来只有开源一条路,如果不开源,或者说内核不开源的话,产品的生命力是很差的。」一切正在 PingCAP 中顺利落地。作为开源新型分布式数据库公司,PingCAP 研发了分布式关系型数据库 TiDB 项目,具备「分布式强一致性事务、在线弹性水平扩展、故障自恢复的高可用、跨数据中心多活」等核心特性。目前公司准生产测试用户 1400 余家,涉及互联网、游戏、银行、保险、证券、航空、制造业、电信、新零售、政府等多个行业。本期对话 CTO,我们请到了 PingCAP CTO 黄东旭来谈一谈他对于数据库行业的技术和行业演进的理解,以及商业公司究竟需要什么样的数据库。分布式数据库、开源数据库的蓝海机遇在哪?颖奇:PingCAP做的事情,我认为在中国工业领域上具有很大意义。因为几乎没有其他公司做过,你们是怎么想到做这件事的?黄东旭:中国过去也不是没有做数据库的公司,我们和他们不太一样在于,一是我们是类似于互联网公司,或者说创业公司的路径,是走融资发展的;二是技术上,我们公司是基于分布式数据库的理论成立的。过去三四十年,数据库市场都是依赖像 Oracle、IBM 所建立的理论基础运行。但在 21 世纪,Google 提出分布式系统技术后,随着硬件条件的成熟,像 SSD、万兆的网卡,带来的改变就是处理的数据量在持续地变大。数据库市场到了需要去做修订或者说要有个转折的地方了。数据库行业最根基的东西在发生变化,而这一块还没人做,所以说一定要找到正确的切入点。颖奇:你们找到的切入点是什么?黄东旭:就是分布式理论怎么跟传统关系数据库理论融合的点。最近这些硬件的革新,使得原来很多的假设都不成立了。比如过去大家可能觉得数据库的瓶颈是磁盘,想怎么设计一个更好的 B-Tree 能够让磁盘磁头转得少一点。但现在全是 SSD,甚至未来可能持久化内存的东西都出现了。过去分布式系统的网络这么慢,带宽这么小,所以尽可能都是在单机或者本地上去做。但现在基本上单机访问远程数据库和访问本地数据库在吞吐量上表现差不多了。还有就是选择「开源」。中国传统软件数据库的技术软件商业模式,跟传统的软件很像,就是做一个产品,招一堆销售挨家敲门。我们觉得这样效率太低。就现在而言,基础软件好不好关键是在于怎么在最短的时间找到最多人来去用这个产品,能够让它变得更好,变成一个正向循环。但传统软件招销售并不是一个特别好的选择,因为扩张速度取决于销售敲门的速度。颖奇:靠销售肯定来不及。黄东旭:所以我们喜欢「开源」。「开源」相当于用一些 to C 的方法论,在工程师的社区里通过病毒式传播让产品 adoption,别人用得不爽一定会 feedback 提 issue。用的人越多,它的质量就越好,质量越好,会变成一传十,十传百的这种效应,让产品正向循环下去。对于基础软件,我的观点是像数据库、操作系统、云技术,或者云内部的基础软件,未来只有开源一条路,如果不开源,或者说内核不开源的话,产品的生命力是很差的。不像其他的商业软件,基础软件就像在水管、水电煤这样的基础设施的层面上,你不开源的话别人也不敢用。颖奇:我们看到在中国实际上有两件事情之前没怎么做好。第一是特别基础的软件,第二是做一个特别好的开源公司,你们算是把两种结合起来的「鼻祖」。请问你们具体是怎么做的呢?黄东旭:我觉得有一点是因为 PingCAP 或者 TiDB 选的这个坑特别好。过去大家都知道 MySQL 数量大了以后只能 sharding,现在 TiDB 就是解决这个坑。大家都非常清楚这是个痛点,你不用去跟别人解释这就是一个非常厉害的内核代码。有需求有痛点,然后问题足够清晰,也足够大。颖奇:那你觉得开源这个事情会把PingCAP带到一个什么样的位置上?黄东旭:从数据库的角度上来看,大家会发现,最早的关系数据库 SQL、TSQL,在互联网或者移动互联网开始爆发的时候,数量开始膨胀,单机系统怎么样都搞不定的时候,互联网公司没有办法,只能去做了一套 NoSQL,但 NoSQL 又有点过了,就把原来的传统管理模型全都扔掉,但至少能把数据存下来。所以我觉得历史是螺旋式发展。其实这两年已经开始有这个趋势,就是新一代的数据库又开始回归 SQL 模型,可能未来持续十年会有一个关系型数据库的复兴吧。过去是因为分布式理论,以及硬件环境没有办法去跟这个模型很好地结合在一起。但至少以我们的经验来说,现在分布式基本上能满足很多需求。颖奇:所以传统数据库公司是在单机上解决这种数据的问题?黄东旭:对,我觉得未来数据一定是更大的状态,单机肯定是有问题的。硬件成本持续在下降,一定会到达一个临界点,就是数据本身的价值都比硬件成本要高,这样一来,我肯定是保护数据,怎么样把我的数据能无限存下来,并且能快速通过好用的接口来访问它。我觉得这个市场会很大,所以我从来都不跟别人说这个事情的天花板在哪里,因为我自己也不知道。颖奇:早期还是在数据价值比较大的行业里来应用会更好一些?黄东旭:我们早期策略上分两块,一块就是互联网公司,workload 数量很大,然后有很强的研发团队,开源社区的主力就是这帮人,随便用,而且我会很鼓励你们投人投精力去用它。还有一部分是一些高净值客户,比如银行,业务已经倒逼他们要去用一些互联网的技术去解决问题。比如说即使 Oracle 用得不好,迁到 TiDB 上其实也是很平滑的过程,同时可以保证多数据中心高可用、强一致等这些特性,用起来很省心。我觉得我们就是拿互联网最先进的技术给到传统公司,给他们赋能,而且让对方的迁移成本降得很低。「商业公司」如何管理「开源社区」颖奇:可以跟大家讲一下PingCAP对人才的要求和你们的管理方法吗?黄东旭:我一直信奉一句话,「Hire for attitude, train for skill」。首先你要打心底里认可这个事情,是一切往后谈的基础。这对我们来说不难,很多工程师他们还是有共同理想的。第二点就是研发人才的 skill set,我可能会更倾向于是在互联网,或者说在做这种大规模分布式系统。互联网人有个优势在于他们对新技术的接受度特别高,思想特别开放,没有一些条条框框的东西。第三点就是特别喜欢年轻人,我们会刻意地让团队里面有一些非常新鲜的血液。第四点的话我们并不强求,就是人的责任心和主人公意识,这其实跟我们的晋升体系有关。我们的晋升体系跟 Facebook 很像,团队在实际工作的时候,让员工的特点会慢慢浮现出来。比如说小明,每件事情交给他都特别靠谱。大家都公认觉得他是个靠谱的人,慢慢形成这样的效果。对于小公司来说,没办法把每个人每天的工作,每个任务都亲自去帮你规划好。所以我们的管理风格还算是比较粗放吧。颖奇:你们公司现在是有一些外籍工程师?黄东旭:对,我们也有一些外籍人士,大概七八个人吧。我们比较国际化。因为我们这个项目是开源的,用户用出问题了一般会去上面提一个 issue,很多国内用户直接用中文写 issue 上去,我们还有一个团队专门把中文 issue 翻译成英文,因为这个东西要同步嘛,在别人遇到同样问题去搜索的时候也能看到。颖奇:你们的TiDB或者TiKV里,我看到有几百个contributors,那里面有多少是外籍的?黄东旭:一半。包括我们的文档都是中英文一对一的比例。我觉得在哪做这个事情,这个问题已经不重要了。包括现在我们很多人才,在加入之前就已经是项目的粉丝,有些人甚至都不用面试,都不用看 GitHub,因为这个人天天就在 commit code。我们在国内的招聘方式也是挺特殊的,我们不太关心你到底在哪个城市工作。我们重度依赖像 Google Docs、Slack、GitHub、Jira、Confluence 这种生产力工具,基本上能够摆脱面对面的会议,这个是很重要的。我们不鼓励开长会,如果要开会,就开半个小时、15 分钟的短会。远程有个好处就是它会迫使工程师把所有想做的东西进行文档化,任何东西都可以被检索。我觉得这样更符合现代化的管理模式,有充足的时间,更加灵活地安排自己的生活,是一个更好的工作方式。颖奇:开源社区可能有一套管理模式,商业公司也有自己的管理模式,现在你们在这两边的管理模式是一样的还是说会有一些区别?黄东旭:我们是一样的。你可以认为我们自己的员工跟社区小伙伴的区别,就 TiDB 内核部分的开源来说,唯一区别就是我们给他们工资。颖奇:你觉得未来中国会有很多这样的工作出现吗?黄东旭:我觉得在技术软件行业会越来越多。颖奇:早期美国的很多开源软件没有太多资本介入,所以发展周期会很长。你觉得资本介入会使得开源软件发展周期变短吗?黄东旭:没有资本介入,或者说没有商业公司在后面支持的话,开源软件都不会有太强的生命力。开源我认为是分成两个阶段,一个是 1.0,一个是 2.0。1.0 是当年像 Glue、 GCC、Linux 内核这些项目;2.0 是就最近的这几年像 Eclipse、MongoDB、Databricks 这些开源软件公司,这些模式其实是更先进的,或者更加符合现在时代的做法。中国其实过去没有这样的东西,我们算是第一波。颖奇:早期的开源公司商业化诉求没那么快,所以贡献者相对平等,也没有经济回报。现在您这边的项目里有两种方式,可能一百个工程师是拿回报的,另外一百个可能是不拿回报的。那现在一个项目里混杂了两种组合方式,你们的解决方案是什么?黄东旭:我觉得其实这个问题的本质是:为什么要来(社区)。两种情况,一种就是我实际就在用这个东西,发现这个东西不好,某些地方有 bug 或者说某些地方的功能不是我想要的,我想要去改进它。大多数机构都是出于这种思路来贡献的。第二种人就是纯粹为了做出成就感。觉得这事情很不错,我能参与到这个项目来了,「I want to help」,我想去帮助别人,同时我能够得到证明,我是这个项目的 heavy contributor、committer,得到尊敬或者认同感。对每一个 contributor,哪怕提交一行代码或者修改一个文档,我们都会给他一个大礼包,包括贴纸、杯子等等周边产品。如果贡献比较多的话,我会亲手给你写一封明信片表达感谢,包括我们每年办的这些大会,只要是 contributor 都是免费的。颖奇:我觉得这个挺棒的。再问最后一个问题,你可以推荐几本书,给已经是CTO或准备想当CTO的人学习和借鉴。黄东旭:我有几本书是很喜欢的,《Unix 编程艺术》是到目前来说对我影响最大的跟编程和计算机相关的书。更技术一点的是《Unix 环境高级编程 (APUE) 》。很多人想学编程可能看这本书够了,其他什么书都不用买,就这个。还有《大教堂与集市》,这个介绍 open source 的原始出发点。然后我最近在读《毛选》,还有王小波的小说。颖奇:《Unix编程艺术》这本我也会推荐给年轻人看。这本书对我的影响非常大,读完使得我对整个计算机的软件体系结构有了非常深刻的认识。第一次读是在13年前了,至今对我的工作和创业都有很大的帮助。非常感谢东旭今天的分享。本文作者:王颖奇,联系方式:wangyingqi@gmail.com ...

February 21, 2019 · 1 min · jiezi

sql server(常用)

//生成 uuid 并转为小写select LOWER(SUBSTRING(uuid,1,8)+’-’+SUBSTRING(uuid,10,4)+’-’+SUBSTRING(uuid,15,4)+’-’+SUBSTRING(uuid,20,4)+’-’+SUBSTRING(uuid,25,12)) from (select cast(NEWID() as varchar(36)) as uuid) s //ea52a7bb-a2aa-44b8-be28-5ebc64defcf9//获取时分秒select DateName(hour,GetDate())+ DateName(minute,GetDate())+DateName(second,GetDate()) //143054//1000-9999随机数select floor(9000*RAND()+1000)//日期格式化select GETDATE() //2019-02-12 14:30:16.763Select CONVERT(varchar(100), GETDATE(), 8) //10:57:46Select CONVERT(varchar(100), GETDATE(), 12) //060516Select CONVERT(varchar(100), GETDATE(), 20) //2006-05-16 10:57:47Select CONVERT(varchar(100), GETDATE(), 21) //2006-05-16 10:57:47.157 Select CONVERT(varchar(100), GETDATE(), 23) //2006-05-16Select CONVERT(varchar(100), GETDATE(), 24) //10:57:47Select CONVERT(varchar(100), GETDATE(), 25) //2006-05-16 10:57:47.250Select CONVERT(varchar(100), GETDATE(), 102)//2006.05.16Select CONVERT(varchar(100), GETDATE(), 111)//2006/05/16Select CONVERT(varchar(100), GETDATE(), 112)//20060516

February 12, 2019 · 1 min · jiezi

SQLServer之删除数据库架构

删除数据库架构注意事项要删除的架构不能包含任何对象。 如果架构包含对象,则 DROP 语句将失败。可以在 sys.schemas 目录视图中查看有关架构的信息。要求对架构具有 CONTROL 权限,或者对数据库具有 ALTER ANY SCHEMA 权限。使用SSMS数据库管理工具删除数据库架构1、连接服务器-》展开数据库文件夹-》选择数据库并展开-》展开安全性文件夹-》展开架构文件夹-》选择要删除的数据库架构右键点击-》选择删除。2、在删除对象弹出框-》点击确定。3、查看删除结果(不需要刷新架构文件夹)。使用T-SQL脚本删除数据库架构语法–声明数据库引用use database_name;go if exists(select * from sys.schemas where name=schema_name)begin –删除数据库架构注释exec sys.sp_dropextendedproperty @name=N’architecturename’,@level0type=N’schema’,@level0name=N’schema_name’; –删除架构下的所有表 if exists(select * from sys.tables where name=schema_tablename) drop table schema_name.schema_tablename; –删除数据库架构drop schema schema_name; endgo语法解析–语法解析–database_name–当前架构所在数据库名称。–schema_name–架构在数据库中所使用的名称。–architecturename–架构扩展属性名称。–schema_tablename–架构下存在的类型(本例以数据表为例)。–schema_tablename–要删除的架构下的表名–if exists–适用范围:SQL Server(SQL Server 2016 (13.x)到当前版本)。–只有在架构已存在时才对其进行有条件地删除。示例–声明数据库引用use [testss];go if exists(select * from sys.schemas where name=‘testarchitecture’)begin –删除数据库架构注释exec sys.sp_dropextendedproperty @name=N’testcrituer’ , @level0type=N’schema’,@level0name=N’testarchitecture’; –删除架构下的所有表 if exists(select * from sys.tables where name=‘schema_table1’) drop table [testarchitecture].[schema_table1]; –删除数据库架构drop schema testarchitecture; endgo示例结果:使用T-SQL脚本删除数据库架构需要刷新数据库架构文件夹查看删除结果。 ...

January 26, 2019 · 1 min · jiezi

SQLServer之修改数据库架构

修改数据库架构注意事项用户与架构完全分离。ALTER SCHEMA 仅可用于在同一数据库中的架构之间移动安全对象。 若要更改或删除架构中的安全对象,请使用特定于该安全对象的 ALTER 或 DROP 语句。如果对 securable_name 使用了由一部分组成的名称,则将使用当前生效的名称解析规则查找该安全对象。将安全对象移入新架构时,将删除与该安全对象关联的全部权限。 如果已显式设置安全对象的所有者,则该所有者保持不变。 如果安全对象的所有者已设置为 SCHEMA OWNER,则该所有者将保持为 SCHEMA OWNER;但移动之后,SCHEMA OWNER 将解析为新架构的所有者。 新所有者的 principal_id 将为 NULL。无论是 sys.sql_modules 目录视图的 definition 列中的相应对象,还是使用 OBJECT_DEFINITION 内置函数获取的相应对象,移动存储过程、函数、视图或触发器都不会更改其架构名称(如有)。 因此,我们建议不要使用 ALTER SCHEMA 移动这些对象类型。 而是删除对象,然后在新架构中重新创建该对象。移动表或同义词不会自动更新对该对象的引用。 必须手动修改引用已移动对象的任何对象。 例如,如果移动了某个表,并且触发器中引用了该表,则必须修改触发器以反映新的架构名称。 请使用 sys.sql_expression_dependencies 列出该对象上的依赖关系,然后再进行移动。若要通过使用 SQL Server Management Studio 更改表的架构,请在对象资源管理器中右键单击该表,然后单击“设计”。 按 F4 以打开“属性”窗口。 在“架构”框中,选择新架构。若要从另一个架构中传输安全对象,当前用户必须拥有对该安全对象(非架构)的 CONTROL 权限,并拥有对目标架构的 ALTER 权限。如果已为安全对象指定 EXECUTE AS OWNER,且所有者已设置为 SCHEMA OWNER,则用户还必须拥有对目标架构所有者的 IMPERSONATE 权限。在移动安全对象后,将删除与所传输的安全对象相关联的所有权限。使用SSMS数据库管理工具修改架构1、连接服务器-》展开数据库文件夹-》选择数据库并展开-》展开安全性文件夹-》展开架构文件夹-》选择要修改的架构右键点击属性。2、在架构属性弹出框-》点击常规-》点击搜索修改架构所有者。3、在架构属性弹出框-》点击权限-》点击搜索选择用户或角色-》选择用户或角色权限。4、在架构属性弹出框-》点击扩展属性-》新增或者删除扩展属性。使用T-SQL脚本修改数据库架构语法–声明数据库引用use database_name;go 修改用户或者角色alter authorization on schema::[ArchitectureName] to [schemaOwner];go –修改用户或角色权限–授予插入grant insert on schema::[ArchitectureName] to [rolename_username];go –授予查看定义grant view definition on schema::[ArchitectureName] to [rolename_username];go –授予查看更改跟踪grant view change tracking on schema::[ArchitectureName] to [rolename_username];go –授予创建序列grant create sequence on schema::[ArchitectureName] to [rolename_username];go –授予更改grant alter on schema::[ArchitectureName] to [rolename_username];go –授予更新grant update on schema::[ArchitectureName] to [rolename_username];go –接管所有权grant take ownership on schema::[ArchitectureName] to [rolename_username];go –授予控制grant control on schema::[ArchitectureName] to [rolename_username];go –授予删除grant delete on schema::[ArchitectureName] to [rolename_username];go –授予选择grant select on schema::[ArchitectureName] to [rolename_username];go –授予引用grant references on schema::[ArchitectureName] to [rolename_username];go –授予执行grant execute on schema::[ArchitectureName] to [rolename_username];go –授予并允许转授插入grant insert on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授查看定义grant view definition on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授查看更改跟踪grant view change tracking on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授创建序列grant create sequence on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授更改grant alter on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授更新grant update on schema::[ArchitectureName] to [rolename_username] with grant option;go –接管并允许转授所有权grant take ownership on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授控制grant control on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授删除grant delete on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授选择grant select on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授引用grant references on schema::[ArchitectureName] to [rolename_username] with grant option;go –授予并允许转授执行grant execute on schema::[ArchitectureName] to [rolename_username] with grant option;go –拒绝插入deny insert on schema::[ArchitectureName] to [rolename_username];go –拒绝查看定义deny view definition on schema::[ArchitectureName] to [rolename_username];go –拒绝查看更改跟踪deny view change tracking on schema::[ArchitectureName] to [rolename_username];go –拒绝创建序列deny create sequence on schema::[ArchitectureName] to [rolename_username];go –拒绝更改deny alter on schema::[ArchitectureName] to [rolename_username];go –拒绝更新deny update on schema::[ArchitectureName] to [rolename_username];go –拒绝所有权deny take ownership on schema::[ArchitectureName] to [rolename_username];go –拒绝控制deny control on schema::[ArchitectureName] to [rolename_username];go –拒绝删除deny delete on schema::[ArchitectureName] to [rolename_username];go –拒绝选择deny select on schema::[ArchitectureName] to [rolename_username];go –拒绝引用deny references on schema::[ArchitectureName] to [rolename_username];go –拒绝执行deny execute on schema::[ArchitectureName] to [rolename_username];go 删除数据库架构扩展属性exec sys.sp_dropextendedproperty @name=N’extendedAttributeName’,@level0type=N’schema’,@level0name=N’extendedAttributeValue’go 创建数据库架构扩属性exec sys.sp_addextendedproperty @name=N’newExtendedAttributeName’,@value=N’newExtendedAttributeValue’ , @level0type=N’schema’,@level0name=N’ArchitectureName’go –修改数据库架构alter schema schema_name(你要修改成得新架构)transfer { object | type | xml schema collection } securable_name (原架构名.对象名);go语法解析–语法解析–schema_name–当前数据库中的架构名称,安全对象将移入其中。其数据类型不能为sys或information_schema。–ArchitectureName–架构名称–schemaOwner–架构所有者–rolename_username–用户或角色–extendedAttributeName–要删除的扩展属性名称–extendedAttributeValue–要删除的扩展属性值–newExtendedAttributeName–新添加扩展属性名称–newExtendedAttributeValue–新添加的扩展属性值–transfer { object | type | xml schema collection }–更改其所有者的实体的类。object是默认值。–securable_name–要移入架构中的架构范围内的安全对象的一部分或两部分名称。示例–声明数据库引用use [testss];go –修改数据库架构–修改架构所有者alter authorization on schema::[testarchitecture] to [db_datareader];go –修改用户或角色权限–授予插入grant insert on schema::[testarchitecture] to [guest];go –授予查看定义grant view definition on schema::[testarchitecture] to [guest];go –授予查看更改跟踪grant view change tracking on schema::[testarchitecture] to [guest];go –授予创建序列grant create sequence on schema::[testarchitecture] to [guest];go –授予更改grant alter on schema::[testarchitecture] to [guest];go –授予更新grant update on schema::[testarchitecture] to [guest];go –接管所有权grant take ownership on schema::[testarchitecture] to [guest];go –授予控制grant control on schema::[testarchitecture] to [guest];go –授予删除grant delete on schema::[testarchitecture] to [guest];go –授予选择grant select on schema::[testarchitecture] to [guest];go –授予引用grant references on schema::[testarchitecture] to [guest];go –授予执行grant execute on schema::[testarchitecture] to [guest];go —-授予并允许转授插入–grant insert on schema::[testarchitecture] to [[guest]] with grant option;–go —-授予并允许转授查看定义–grant view definition on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授查看更改跟踪–grant view change tracking on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授创建序列–grant create sequence on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授更改–grant alter on schema::[testarchitecture] to [guest] with grant option;–go – –授予并允许转授更新–grant update on schema::[testarchitecture] to [guest] with grant option;–go —-接管并允许转授所有权–grant take ownership on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授控制–grant control on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授删除–grant delete on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授选择–grant select on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授引用–grant references on schema::[testarchitecture] to [guest] with grant option;–go —-授予并允许转授执行–grant execute on schema::[testarchitecture] to [guest] with grant option;–go —-拒绝插入–deny insert on schema::[testarchitecture] to [guest];–go —-拒绝查看定义–deny view definition on schema::[testarchitecture] to [guest];–go —-拒绝查看更改跟踪–deny view change tracking on schema::[testarchitecture] to [guest];–go —-拒绝创建序列–deny create sequence on schema::[testarchitecture] to [guest];–go —-拒绝更改–deny alter on schema::[testarchitecture] to [guest];–go —-拒绝更新–deny update on schema::[testarchitecture] to [guest];–go —-拒绝所有权–deny take ownership on schema::[testarchitecture] to [guest];–go —-拒绝控制–deny control on schema::[testarchitecture] to [guest];–go —-拒绝删除–deny delete on schema::[testarchitecture] to [guest];–go —-拒绝选择–deny select on schema::[testarchitecture] to [guest];–go —-拒绝引用–deny references on schema::[testarchitecture] to [guest];–go —-拒绝执行–deny execute on schema::[testarchitecture] to [guest];–go –删除数据库架构扩展属性exec sys.sp_dropextendedproperty @name=N’testcrituer’ , @level0type=N’schema’,@level0name=N’testarchitecture’go –创建数据库架构扩属性exec sys.sp_addextendedproperty @name=N’testcrituer’, @value=N’测试创建数据库架构’ , @level0type=N’schema’,@level0name=N’testarchitecture’go –修改架构下对象所有权,从[testarchitecture]转移到[dbo]alter schema [dbo] transfer [testarchitecture].[schema_table1];go示例结果:执行T-SQL脚本需要刷新表文件夹才能查看执行结果。 ...

January 26, 2019 · 4 min · jiezi

【SqlServer】统计索引使用情况解决DB的CPU高和IO高的问题

查看索引情况sp_helpindex 表名;显示索引使用情况user_seeks和user_scans字段都为0的,考虑是否为垃圾索引另外last_user_seek,last_user_scan如果是一个很早的时间,则考虑是否应用变化导致该索引不被使用了SELECT i.name indexname,user_seeks,user_scans,last_user_seek,last_user_scanFROM sys.dm_db_index_usage_stats sINNER JOIN sys.indexes i ONs.object_id = i.object_id ANDs.index_id = i.index_idWHERE database_id = db_id(‘ClntMgr’) AND s.object_id = object_id(‘IDVerifyTbl’);返回指定数据库、表、索引的碎片对于索引类型为HEAP,一般情况下碎片比例会较大原因:1.没有聚集索引的表称为堆,意思是其中存储的数据没有特定的顺序。2.在索引重建或者重新组织时,聚集索引依照聚集键和它重排序的数据页进行排序。3.但是堆不会在索引重建或重新组织期间被重新生成,所以会脱离控制的增长,占用的数据页比必要的多很多。SELECT OBJECT_NAME(f.object_id) 表名,i.name 索引名,f.index_type_desc 索引类型, f.avg_fragmentation_in_percent 碎片比例FROM sys.dm_db_index_physical_stats(DB_ID(‘库名’),OBJECT_ID(‘表名’),NULL,NULL,’limited’) fINNER JOIN sys.indexes i ONi.[object_id] = f.object_id ANDi.index_id = f.index_idORDER BY f.avg_fragmentation_in_percent DESC;在线重新生成表的所有索引ALTER INDEX ALL ON 库名.dbo.表名 REBUILD WITH (ONLINE = ON);重新组织表的所有索引ALTER INDEX all ON 库名.dbo.表名 REORGANIZE;查看表、索引占用磁盘空间情况SELECT name ‘表名’,convert (char(11), row_Count) as ‘数据条数’,(reservedpages * 8) ‘已用空间(KB)’,(pages * 8) ‘数据占用空间(KB)’,(CASE WHEN usedpages > pages THEN (usedpages - pages) ELSE 0 END) * 8 ‘索引占用空间(KB)’,(CASE WHEN reservedpages > usedpages THEN (reservedpages - usedpages) ELSE 0 END) * 8 ‘未用空间(KB)’,LTRIM (STR (reservedpages * 8/1024/1024, 15, 0) + ’ GB’) as ‘已用空间(GB)‘from(SELECT name,SUM (reserved_page_count) as reservedpages ,SUM (used_page_count) as usedpages ,SUM ( CASE WHEN (index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count) ELSE lob_used_page_count + row_overflow_used_page_count END ) as pages,SUM ( CASE WHEN (index_id < 2) THEN row_count ELSE 0 END ) as row_CountFROM sys.dm_db_partition_statsinner join sys.objects on sys.dm_db_partition_stats.object_id=sys.objects.object_idwhere type=‘U’group by sys.objects.nameunionSELECT sys.objects.name,sum(reserved_page_count) as reservedpages,sum(used_page_count) as usedpages,0 as pages,0 as row_countfrom sys.objects inner join sys.internal_tables on sys.objects.object_id = sys.internal_tables.parent_id inner join sys.dm_db_partition_stats on sys.dm_db_partition_stats.object_id=sys.internal_tables.object_idwhere sys.internal_tables.internal_type IN (202,204,211,212,213,214,215,216) group by sys.objects.name) torder by ‘已用空间(KB)’ desc查看表缺失的索引信息SELECT DatabaseName = DB_NAME(database_id),[Number Indexes Missing] = count(*)FROM sys.dm_db_missing_index_detailsGROUP BY DB_NAME(database_id)ORDER BY [Number Indexes Missing] DESC;确定开销最高的缺失索引column_usage的取值有如下几种情况:1.EqualityUsage代表在该列上做了相等运算;2.InequalityUsage代表在该列上做了不等运算;3.Include Cloumns代表包含性列此查询的结果(按"总开销"排序)显示最重要缺失索引的成本以及有关数据库/架构/表和缺失索引中所需列的信息。特别是,此脚本可确定哪些列在相等和不相等 SQL 语句中使用。另外,它还报告应将哪些其他列用作缺失索引中的包含性列。使用包含性列可以在不从基础页获取数据的情况下满足更多的覆盖查询,因而使用的 I/O 操作更少,从而提高性能。SELECT TOP 100[Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0), avg_user_impact, TableName = statement, [EqualityUsage] = equality_columns, [InequalityUsage] = inequality_columns, [Include Cloumns] = included_columnsFROM sys.dm_db_missing_index_groups gINNER JOIN sys.dm_db_missing_index_group_stats s ON s.group_handle = g.index_group_handleINNER JOIN sys.dm_db_missing_index_details d ON d.index_handle = g.index_handleORDER BY [Total Cost] DESC; ...

January 25, 2019 · 2 min · jiezi

SQLServer之创建数据库架构

创建数据库架构注意事项包含 CREATE SCHEMA AUTHORIZATION 但未指定名称的语句仅允许用于向后兼容性。 该语句未引起错误,但未创建一个架构。CREATE SCHEMA 可以在单条语句中创建架构以及该架构所包含的表和视图,并授予对任何安全对象的 GRANT、REVOKE 或 DENY 权限。 此语句必须作为一个单独的批处理执行。 CREATE SCHEMA 语句所创建的对象将在要创建的架构内进行创建。CREATE SCHEMA 事务是原子级的。 如果 CREATE SCHEMA 语句执行期间出现任何错误,则不会创建任何指定的安全对象,也不会授予任何权限。由 CREATE SCHEMA 创建的安全对象可以任何顺序列出,但引用其他视图的视图除外。 在这种情况下,被引用的视图必须在引用它的视图之前创建。因此,GRANT 语句可以在创建某个对象自身之前对该对象授予权限,CREATE VIEW 语句也可以出现在创建该视图所引用表的 CREATE TABLE 语句之前。 同样,CREATE TABLE 语句可以在 CREATE SCHEMA 语句定义表之前声明表的外键。执行 CREATE SCHEMA 的主体可以将另一个数据库主体指定为要创建的架构的所有者。 完成此操作需要另外的权限,如本主题下文中的“权限”部分所述。新架构由以下数据库级别主体之一拥有:数据库用户、数据库角色或应用程序角色。 在架构内创建的对象由架构所有者拥有,这些对象在 sys.objects 中的 principal_id为 NULL。 架构所包含对象的所有权可转让给任何数据库级主体,但架构所有者始终保留对该架构内对象的 CONTROL 权限。隐式架构和用户创建在某些情况下,用户可在没有数据库用户帐户(数据库中的数据库主体)的情况下使用数据库。 这可发生在以下情况中:登录名具有 CONTROL SERVER 特权。Windows 用户没有单独的数据库用户帐户(数据库中的数据库主体),但以具有数据库用户帐户(Windows 组的数据库主体)的 Windows 组成员的身份访问数据库。如果没有数据库用户帐户的用户在不指定现有架构的情况下创建对象,则将在数据库中自动为该用户创建数据库主体和默认架构。 创建的数据库主体和架构采用的名称将与连接到 SQL Server 时用户使用的名称( SQL Server 身份验证登录名或 Windows 用户名)相同。若要允许基于 Windows 组的用户创建和拥有对象,此行为很有必要。 但这种行为可能将导致意外创建架构和用户。 为了避免隐式创建用户和架构,请尽可能显式创建数据库主体和分配默认架构。 或者,在数据库中创建对象时,使用由两部分或三部分组成的对象名称显式声明现有架构。当前支持不指定架构名称的 CREATE SCHEMA 语句,目的是为了向后兼容。 此类语句并不在数据库中实际创建架构,但它们会创建表和视图,并授予权限。 主体不需要 CREATE SCHEMA 权限来执行这一早期形式的 CREATE SCHEMA,因为不会创建任何架构。 此功能将从 SQL Server 的未来版本中删除。需要对数据库拥有 CREATE SCHEMA 权限。若要创建在 CREATE SCHEMA 语句中指定的对象,用户必须拥有相应的 CREATE 权限。若要指定其他用户作为所创建架构的所有者,则调用方必须具有对该用户的 IMPERSONATE 权限。 如果指定一个数据库角色作为所有者,则调用方必须拥有该角色的成员身份或对该角色拥有 ALTER 权限。使用SSMS数据库管理工具创建数据库架构1、连接服务器-》展开数据库文件夹-》选择数据库并展开-》展开安全性-》展开架构-》右键单击架构文件夹选择创建架构。2、在新建架构弹出框-》点击常规-》输入新建架构名称-》点击搜索选择架构所有者。3、在新建架构弹出框-》点击权限-》点击搜索选择新建架构的用户或角色-》选择用户或角色后选择新建架构的权限。4、在新建架构弹出框-》点击扩展属性-》输入扩展属性名称和值-》点击确定。5、不需要刷新即可在对象资源管理器中查看创建结果。使用T-SQL脚本创建数据库架构语法—-声明数据库引用–use database_name;–go —-创建数据库架构–create schema schema_name authorization owner_name –{ table_definition | view_definition | grant_statement | revoke_statement | deny_statement }–;–go语法解析–语法解析–database_name–架构所在的数据库名–schema_name–在数据库内标识架构的名称。–authorization owner_name–指定将拥有架构的数据库级主体的名称。此主体还可以拥有其他架构,并且可以不使用当前架构作为其默认架构。–table_definition–指定在架构内创建表的CREATE TABLE语句。执行此语句的主体必须对当前数据库具有CREATE TABLE权限。–view_definition–指定在架构内创建视图的CREATE VIEW语句。执行此语句的主体必须对当前数据库具有CREATE VIEW权限。–grant_statement–指定可对除新架构外的任何安全对象授予权限的GRANT语句。–revoke_statement–指定可对除新架构外的任何安全对象撤消权限的REVOKE语句。–deny_statement–指定可对除新架构外的任何安全对象拒绝授予权限的DENY语句。示例–声明数据库引用use [testss];go if exists(select * from sys.schemas where name=‘testarchitecture’)–删除数据库架构注释exec sys.sp_dropextendedproperty @name=N’testcrituer’ , @level0type=N’schema’,@level0name=N’testarchitecture’; –删除架构下的所有表 if exists(select * from sys.tables where name=‘schema_table1’) drop table [testarchitecture].[schema_table1]; go–删除数据库架构drop schema testarchitecture; go –创建数据库架构create schema [testarchitecture] authorization [db_accessadmin]create table schema_table1(id int identity(1,1) not null,name nvarchar(50),primary key clustered(id asc) with(ignore_dup_key=off) on [primary])on [primary]go –授予插入grant insert on schema::[testarchitecture] to [public];go –授予查看定义grant view definition on schema::[testarchitecture] to [public];go –授予查看更改跟踪grant view change tracking on schema::[testarchitecture] to [public];go –授予创建序列grant create sequence on schema::[testarchitecture] to [public];go –授予更改grant alter on schema::[testarchitecture] to [public];go –授予更新grant update on schema::[testarchitecture] to [public];go –接管所有权grant take ownership on schema::[testarchitecture] to [public];go –授予控制grant control on schema::[testarchitecture] to [public];go –授予删除grant delete on schema::[testarchitecture] to [public];go –授予选择grant select on schema::[testarchitecture] to [public];go –授予引用grant references on schema::[testarchitecture] to [public];go –授予执行grant execute on schema::[testarchitecture] to [public];go —-授予并允许转授插入–grant insert on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授查看定义–grant view definition on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授查看更改跟踪–grant view change tracking on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授创建序列–grant create sequence on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授更改–grant alter on schema::[testarchitecture] to [public] with grant option;–go – –授予并允许转授更新–grant update on schema::[testarchitecture] to [public] with grant option;–go —-接管并允许转授所有权–grant take ownership on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授控制–grant control on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授删除–grant delete on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授选择–grant select on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授引用–grant references on schema::[testarchitecture] to [public] with grant option;–go —-授予并允许转授执行–grant execute on schema::[testarchitecture] to [public] with grant option;–go —-拒绝插入–deny insert on schema::[testarchitecture] to [public];–go —-拒绝查看定义–deny view definition on schema::[testarchitecture] to [public];–go —-拒绝查看更改跟踪–deny view change tracking on schema::[testarchitecture] to [public];–go —-拒绝创建序列–deny create sequence on schema::[testarchitecture] to [public];–go —-拒绝更改–deny alter on schema::[testarchitecture] to [public];–go —-拒绝更新–deny update on schema::[testarchitecture] to [public];–go —-拒绝所有权–deny take ownership on schema::[testarchitecture] to [public];–go —-拒绝控制–deny control on schema::[testarchitecture] to [public];–go —-拒绝删除–deny delete on schema::[testarchitecture] to [public];–go —-拒绝选择–deny select on schema::[testarchitecture] to [public];–go —-拒绝引用–deny references on schema::[testarchitecture] to [public];–go —-拒绝执行–deny execute on schema::[testarchitecture] to [public];–go –用户或者角色alter authorization on schema::[testarchitecture] to [public];go –创建扩展属性exec sys.sp_addextendedproperty @name=N’testcrituer’, @value=N’测试创建数据库架构’ , @level0type=N’schema’,@level0name=N’testarchitecture’go示例结果:使用T-SQL脚本创建数据库架构需要刷新数据库才能查看结果。 ...

January 23, 2019 · 3 min · jiezi

SQLServer之附加数据库

附加数据库注意事项必须首先分离数据库。 尝试附加未分离的数据库将返回错误。 附加数据库时,所有数据文件(MDF 文件和 LDF 文件)都必须可用。 如果任何数据文件的路径不同于首次创建数据库或上次附加数据库时的路径,则必须指定文件的当前路径。在附加数据库时,如果 MDF 和 LDF 文件位于不同目录并且其中一条路径包含 ?GlobalRoot,该操作将失败。需要 CREATE DATABASE、CREATE ANY DATABASE 或 ALTER ANY DATABASE 权限。分离再重新附加只读数据库后,会丢失有关当前差异基准的备份信息。 “差异基准” 是数据库或其文件或文件组子集中所有数据的最新完整备份。 如果没有基准备份信息,master 数据库会变得与只读数据库不同步,这样之后进行的差异备份可能会产生意外结果。 因此,如果对只读数据库使用差异备份,在重新附加数据库后,应通过进行完整备份来建立新的差异基准。附加时,数据库会启动。 通常,附加数据库时会将数据库重置为它分离或复制时的状态。 但是,附加和分离操作都会禁用数据库的跨数据库所有权链接。附加日志文件的要求在某些方面取决于数据库是读写的还是只读的,如下所示:对于读写数据库,通常可以附加新位置中的日志文件。 不过,在某些情况下,重新附加数据库需要使用其现有的日志文件。 因此,请务必保留所有分离的日志文件,直到在不需要这些日志文件的情况下成功附加了数据库。如果读写数据库具有单个日志文件,并且您没有为该日志文件指定新位置,附加操作将在旧位置中查找该文件。 如果找到了旧日志文件,则无论数据库上次是否完全关闭,都将使用该文件。 但是,如果未找到旧文件日志,数据库上次是完全关闭且现在没有活动日志链,则附加操作将尝试为数据库创建新的日志文件。如果附加的主数据文件是只读的,则 数据库引擎 假定数据库也是只读的。 对于只读数据库,日志文件在数据库主文件中指定的位置上必须可用。 因为 SQL Server 无法更新主文件中存储的日志位置,所以无法生成新的日志文件。使用SSMS数据库管理工具附加数据库1、连接服务器-》在对象资源管理器窗口展开数据库文件夹-》右键点击数据库文件夹-》选择附加。2、在附加数据库弹出框-》点击添加(查找必需的主数据库文件。 当用户选择 .mdf 文件时,就会在 “要附加的数据库” 网格的相应字段中自动填充合适的信息。)。3、在定位数据库文件弹出框中-》选择指定路径下分离的数据库文件-》点击确定。4、在附加数据库弹出框-》要附加的数据库窗格(显示所选数据库的有关信息。):MDF 文件位置(显示选定 MDF 文件的路径和文件名。);数据库名称(显示数据库的名称。);附加为(根据需要,可以指定要附加数据库的其他名称。);“所有者”(提供数据库可能所有者的下拉列表,您可以根据需要从其中选择其他所有者。);“状态”(显示下表中相应的数据库状态。),状态一图标为无图标,状态文本为无文本,描述为此对象的附加操作尚未启动或者可能挂起。 这是打开该对话框时的默认值;状态二图标为绿色的右向三角形,状态文本为正在进行,描述为已启动附加操作,但是该操作未完成;状态三图标为绿色的选中标记,状态文本为成功,描述为已成功附加该对象;状态四图标为包含白色十字形的红色圆圈,状态文本为错误,描述为附加操作遇到错误,未成功完成;状态五图标为包含左、右两个黑色象限和上、下两个白色象限的圆圈,状态文本为已停止,描述为由于用户停止了附加操作,该操作未成功完成;状态六图标为包含一个指向逆时针方向的曲线箭头的圆圈,状态文本为已回滚,状态描述为附加操作已成功,但已对其进行回滚,因为在附加其他对象的过程中出现了错误。-》删除(从 “要附加的数据库” 网格中删除选定文件。)-》数据库详细信息窗格:原始文件名(显示属于数据库的已附加文件的名称。);文件类型(指示文件类型,即 “数据” 或 “日志”。);当前文件路径(显示所选数据库文件的路径。 可以手动编辑该路径。);消息(显示空消息或 “找不到文件” 超链接。)-》点击确定。5、查看附加结果(不需要刷新即可在对象资源管理器窗口查看)。使用T-SQL脚本附加数据库语法–语法一–声明数据库引用use other_database_name;go –附加数据库create database database_nameon (filename=‘mdf_path’),(filename=‘ldf_path’)for attachgo –语法二–声明数据库引用use other_database_name;go –附加数据库create database database_nameon (name=‘logical_file_name’,filename=‘filestream_path’,size= size_number [ KB | MB | GB | TB ],maxsize= { max_size_number [ KB | MB | GB | TB ] | unlimited },filegrowth= growth_increment [ KB | MB | GB | TB | % ]),(name=‘logical_log_file_name’filename=‘log_filestream_path’,size= size_number [ KB | MB | GB | TB ],maxsize= { max_size_number [ KB | MB | GB | TB ] | unlimited },filegrowth= growth_increment [ KB | MB | GB | TB | % ])for { attach with[ enable_broker | new_broker | error_broker_conversations ][,restricted_user][,filestream ( directory_name={ ‘directory_name’ | NULL })] | attach_rebuild_log }go语法解析–语法解析–other_database_name–其它数据库,不能使用要附加的数据库进行附加。–database_name–新数据库的名称。数据库名称在SQL Server的实例中必须唯一,并且必须符合标识符规则。–mdf_path–数据库分离的数据文件完整路径。–ldf_path–数据库分离的日志文件完整路径。–name –指定文件的逻辑名称。 指定filename时,–需要使用name,除非指定for attach子句之一。 无法将filestream文件组命名为primary。–logical_file_name–在SQL Server中引用文件时所用的逻辑名称。 Logical_file_name在数据库中必须唯一,并且必须符合标识符规则。 –名称可以是字符或Unicode常量,也可以是常规标识符或分隔标识符。–filename–指定操作系统(物理)文件名称。–filestream_path–数据库数据文件完整路径–logical_log_file_name–数据库日志名称。–log_filestream_path–数据库日志文件完整路径–size–指定文件的大小。–将 os_file_name 指定为UNC路径时,不能指定SIZE。 SIZE不适用于FILESTREAM文件组。–size_number–文件的初始大小。–maxsize–指定文件可增大到的最大大小。将os_file_name指定为UNC路径时,不能指定maxsize。–max_size_number–最大的文件大小。可以使用 KB、MB、GB 和 TB 后缀。默认值为 MB。指定一个整数,不包含小数位。 –如果未指定 max_size,文件将一直增长到磁盘变满为止。Max_size 是一个整数值。对于大于2147483647的值,使用更大的单位。–unlimited–指定文件将增长到磁盘充满。在SQL Server中,指定为不限制增长的日志文件的最大大小为2TB,而数据文件的最大大小为16TB。–filegrowth–指定文件的自动增量。文件的filegrowth设置不能超过max_size_number设置。将os_file_name指定为UNC路径时,不能指定filegrowth。–filegrowth不适用于filestream文件组。–growth_increment–每次需要新空间时为文件添加的空间量。–该值可以MB、KB、GB、TB 或百分比 (%)为单位指定。–如果未在数量后面指定MB、KB 或%,则默认值为MB。 –如果指定%,则增量大小为发生增长时文件大小的指定百分比。 定的大小舍入为最接近的64KB的倍数,最小值为64KB。–值为0时表明自动增长被设置为关闭,不允许增加空间。–enable_broker–指定对指定的数据库启用Service Broker。 也就是说,启动了消息传递,–并且在sys.databases 目录视图中将is_broker_enabled设置为true。数据库保留现有的Service Broker标识符。–new_broker–在sys.databases和还原数据库中都创建一个新的service_broker_guid值,并通过清除结束所有会话端点。 –Broker已启用,但未向远程会话端点发送消息。必须使用新标识符重新创建任何引用旧Service Broker标识符的路由。–error_broker_conversations–结束所有会话,并产生一个错误指出数据库已附加或还原。 –Broker一直处于禁用状态直到此操作完成,然后再将其启用。数据库保留现有的Service Broker标识符。–restricted_user–对于attach,可以指定restricted_user选项。–restricted_user只允许db_owner固定数据库角色成员以及dbcreator和sysadmin固定服务器角色成员连接到数据库,–不过对连接数没有限制。无资格用户的尝试将被拒绝。–filestream–将包含filestream选项“目录名称”的数据库附加到SQL Server实例中将提示SQL Server验证Database_Directory名称是否唯一。–directory_name={ ‘directory_name’ | NULL }–适用于: SQL Server 2012 (11.x) 到 SQL Server 2017–与Windows兼容的目录名称。此名称应在SQL Server实例的所有Database_Directory名称中唯一。–无论SQL Server排序规则设置如何,唯一性比较都不区分大小写。在此数据库中创建FileTable之前,应设置此选项。–仅在将containment设置为partial之后,才允许使用以下选项。如果将containment设置为none,将发生错误。–for attach_rebuild_log –指定通过附加一组现有的操作系统文件来创建数据库。该选项只限于读/写数据库。 –必须有一个指定主文件的 <filespec> 项。如果缺少一个或多个事务日志文件,将重新生成日志文件。–attach_rebuild_log自动创建一个新的1MB的日志文件。此文件放置于默认的日志文件位置。–for attach_rebuild_log具有以下要求:完全关闭数据库。所有数据文件(MDF 和 NDF)都必须可用。–通常,FOR ATTACH_REBUILD_LOG 用于将具有大型日志的可读/写数据库复制到另一台服务器,–在这台服务器上,数据库副本频繁使用,或仅用于读操作,因而所需的日志空间少于原始数据库。–不能对数据库快照指定for attach_rebuild_log。示例–示例一–声明数据库引用use master;go –附加数据库create database testsson (filename=‘D:\SQLServer\tests.mdf’),(filename=‘D:\SQLServer\testslog.ldf’)for attachgo –示例二–声明数据库引用use master;go –附加数据库create database testsson (name=‘testss’,filename=‘D:\SQLServer\tests.mdf’,size=1021KB,maxsize=1024MB,filegrowth=1024MB),(name=‘testsslog’,filename=‘D:\SQLServer\testslog.ldf’,size=1021KB,maxsize=1024MB,filegrowth=1024MB)for attachwithenable_broker,restricted_user–,filestream ( directory_name=‘D:\SQLServer')go示例结果:使用T-SQL脚本附加数据库成功后需要刷新数据库文件夹才能查看结果。 ...

January 20, 2019 · 2 min · jiezi

SQLServer之分离数据库

分离数据库注意事项要求具有 db_owner 固定数据库角色中的成员资格。可以分离数据库的数据和事务日志文件,然后将它们重新附加到同一或其他 SQL Server实例。 如果要将数据库更改到同一计算机的不同 SQL Server 实例或要移动数据库,分离和附加数据库会很有用。分离数据库是指将数据库从 SQL Server 实例中删除,但使数据库在其数据文件和事务日志文件中保持不变。 之后,就可以使用这些文件将数据库附加到任何 SQL Server实例,包括分离该数据库的服务器。如果存在下列任何情况,则不能分离数据库:已复制并发布数据库。 如果进行复制,则数据库必须是未发布的。 必须通过运行 sp_replicationdboption禁用发布后,才能分离数据库。如果无法使用 sp_replicationdboption,可以通过运行 sp_removedbreplication删除复制。数据库中存在数据库快照。必须首先删除所有数据库快照,然后才能分离数据库。 不能分离或附加数据库快照。该数据库正在某个数据库镜像会话中进行镜像。除非终止该会话,否则无法分离该数据库。数据库处于可疑状态。 无法分离可疑数据库;必须将数据库设为紧急模式,才能对其进行分离。 数据库为系统数据库。分离只读数据库将会丢失有关差异备份的差异基准的信息。分离数据库时生成的错误会阻止完全关闭数据库和重新生成事务日志。 收到错误消息后,请执行下列更正操作:重新附加与数据库关联的所有文件,而不仅仅是主文件。解决导致生成错误消息的问题。再次分离数据库。使用SSMS数据库工具分离数据库1、连接服务器-》展开服务器-》选择数据库-》右键点击-》选择任务-》选择分离。2、在分离数据库对话框-》右边要分离得数据库对话框-》数据库名称:列出要分离的数据库-》删除连接:断开与指定数据库的连接,不能分离连接为活动状态的数据库-》更新统计信息:默认情况下,分离操作将在分离数据库时保留过期的优化统计信息;若要更新现有的优化统计信息,请单击此复选框-》状态:显示以下状态之一: 就绪或 未就绪-》消息:当数据库进行了复制操作,则 状态为未就绪, 消息列将显示已复制数据库。如果数据库有一个或多个活动连接,则状态为未就绪,消息列显示<number_of_active_connections> 个活动连接,例如:1 个活动连接。 在分离数据库之前,需要通过选择 删除连接断开所有活动连接。3、数据库分离结果。使用T-SQL脚本分离数据库语法–声明数据库引用use other_database_name;go –语法exec sp_detach_db [@dbname=] ‘database_name’ [,[@skipchecks= ] ‘skipchecks’] [,[@keepfulltextindexfile=] ‘KeepFulltextIndexFile’ ];go语法注释–语法示例–other_database_name–声明当前使用的数据库不是要分离的数据库–[@dbname=]‘database_name’–要分离的数据库的名称。database_name是sysname值,默认值为NULL。–[@skipchecks =]‘skipchecks’–指定跳过还是运行update statistic。同时将skipchecks是nvarchar(10)值,默认值为NULL。–若要跳过更新统计信息,请指定,则返回 true。 若要显式运行更新统计信息,请指定false。–默认情况下,执行update statistic可更新有关表和索引中的数据的信息。 对于要移动到只读介质的数据库,执行 UPDATE STATISTICS 非常有用。–[@keepfulltextindexfile=] ‘KeepFulltextIndexFile’–指定在数据库分离操作过程中不会删除与所分离的数据库关联的全文索引文件。–KeepFulltextIndexFile是nvarchar(10)值,该值具有默认值为true。–如果KeepFulltextIndexFile是false、 与数据库关联的全文索引的所有文件和全文索引的元数据被删除,除非数据库是只读的。–如果为NULL,则返回true,全文索引相关的元数据保留。 –@keepfulltextindexfile中的未来版本将删除参数SQL Server。请不要在新的开发工作中使用此参数,并尽快修改当前仍在使用此参数的应用程序。示例–声明数据库引用use master;go –进行数据库分离–方式一–exec sp_detach_db @dbname=‘testss’–,@skipchecks=‘true’–,@keepfulltextindexfile=‘true’; –方式二exec sp_detach_db ’testss’,’true’,’true’;go示例结果:T-SQL脚本执行完毕需要在对象资源管理器刷新才能看到分离结果。

January 19, 2019 · 1 min · jiezi

SQLServer之删除用户自定义数据库用户

删除用户自定义数据库用户注意事项不能从数据库中删除拥有安全对象的用户。 必须先删除或转移安全对象的所有权,才能删除拥有这些安全对象的数据库用户。不能删除 guest 用户,但可在除 master 或 tempdb 之外的任何数据库中执行 REVOKE CONNECT FROM GUEST 来撤消它的 CONNECT 权限,从而禁用 guest 用户。需要对数据库具有 ALTER ANY USER 权限。使用SSMS数据库管理工具删除用户自定义数据库用户1、连接服务器-》展开数据库-》选择要删除用户的数据库-》展开数据库-》展开安全性-》展开用户-》选择要删除的用户右键点击-》选择删除。2、在删除对象弹出框-》点击确定。3、不需要刷新即可查看删除结果。使用T-SQL脚本删除用户自定义用户语法–声明数据库引用use database_name;go –判断是否存在用户自定义用户,如果存在则删除。if exists(select * from sys.database_principals where name=user_name)–把架构所有者修改回来架构自身alter authorization on schema::[Architecture_name] to Architecture_name;–删除角色拥有的成员alter role [[Architecture_name] drop member user_name;–删除扩展属性exec sys.sp_dropextendedproperty @name=N’tests_description’, @level0type=N’user’,@level0name=N’user_name’–删除用户架构drop user user_name;go语法注释–database_name–数据库名称–user_name–用户名称–Architecture_name–架构名称–tests_description–扩展属性名称示例–声明数据库引用use [testss];go –判断是否存在用户自定义用户,如果存在则删除。if exists(select * from sys.database_principals where name=‘test1’)–把架构所有者修改回来架构自身alter authorization on schema::[db_accessadmin] to db_accessadmin;–删除角色拥有的成员alter role [db_accessadmin] drop member test1;–删除扩展属性–exec sys.sp_dropextendedproperty @name=N’tests_description’, @level0type=N’user’,@level0name=N’test1’–删除用户架构drop user test1;go示例结果:使用T-SQL脚本删除用户需要刷新用户文件夹才能查看删除结果。

January 8, 2019 · 1 min · jiezi

SQLServer之修改用户自定义数据库用户

修改用户自定义数据库用户注意事项默认架构将是服务器为此数据库用户解析对象名时将搜索的第一个架构。 除非另外指定,否则默认架构将是此数据库用户创建的对象所属的架构。如果用户具有默认架构,则将使用默认架构。 如果用户不具有默认架构,但该用户是具有默认架构的组的成员,则将使用该组的默认架构。 如果用户不具有默认架构而且是多个组的成员,则该用户的默认架构将是具有最低 principle_id 的 Windows 组的架构和一个显式设置的默认架构。 如果不能为用户确定默认架构,则将使用 dbo 架构。可以将 DEFAULT_SCHEMA 设置为数据库中当前不存在的架构。 因此,可以在创建架构之前将 DEFAULT_SCHEMA 分配给用户。不能为映射到证书或非对称密钥的用户指定 DEFAULT_SCHEMA。如果用户是 sysadmin 固定服务器角色的成员,则忽略 DEFAULT_SCHEMA 的值。 sysadmin 固定服务器角色的所有成员都有默认架构 dbo。仅当新用户名的 SID 与在数据库中记录的 SID 匹配时,才能更改映射到 Windows 登录名或组的用户的名称。此检查将帮助防止数据库中的 Windows 登录名欺骗。使用 WITH LOGIN 子句可以将用户重新映射到一个不同的登录名。 不能使用此子句重新映射以下用户:不具有登录名的用户、映射到证书的用户或映射到非对称密钥的用户。 只能重新映射 SQL 用户和 Windows 用户(或组)。 不能使用 WITH LOGIN 子句更改用户类型,例如将 Windows 帐户更改为 SQL Server 登录名。如果满足以下条件,则用户的名称会自动重命名为登录名。用户是一个 Windows 用户。名称是一个 Windows 名称(包含反斜杠)。未指定新名称。当前名称不同于登录名。如果不满足上述条件,则不会重命名用户,除非调用方另外调用了 NAME 子句。被映射到 SQL Server 登录名、证书或非对称密钥的用户名不能包含反斜杠字符 ()。更改用户名需要具有 ALTER ANY USER 权限。更改用户的目标登录名需要对数据库拥有 CONTROL 权限。若要更改对数据库拥有 CONTROL 权限的用户名名称,则需要对数据库拥有 CONTROL 权限。更改默认架构或语言需要对用户拥有 ALTER 权限。 用户可更改自己的默认架构或语言。使用SSMS数据库管理工具修改用户自定义数据库用户1、连接服务器-》在对象资源管理器窗口-》展开数据库-》选择数据库并展开-》展开安全性-》展开用户-》选择要修改的用户右键点击-》选择属性。2、在数据库用户弹出框-》点击常规-》修改用户默认架构。3、在数据库用户弹出框-》点击拥有的架构-》添加此用户拥有的架构。4、在数据库用户弹出框-》点击成员身份-》添加或者删除数据库角色成员身份。5、在数据库用户弹出框-》点击安全对象-》点击搜索添加安全对象-》点击安全对象修改安全对象拥有的权限。6、在数据库用户弹出框-》点击扩展属性-》添加或者删除扩展属性。使用T-SQL脚本修改用户自定义数据库用户语法–创建用户自定义数据库用户–声明数据库引用use database_name;go–修改用户自定义数据库用户alter user user_namewithname=new_user_name,default_schema={ schemaname | null },login=login_name,password=‘password’ [old_password=‘old_password’],default_language={ none | <lcid> | <language_name> | <language alias> },allow_encrypted_value_modifications={ on | off } –添加拥有的架构use database_name;goalter authorization on schema::[db_accessadmin] to user_name;goalter authorization on schema::[db_backupoperator] to user_name;goalter authorization on schema::[db_datareader] to user_name;goalter authorization on schema::[db_datawriter] to user_name;goalter authorization on schema::[db_ddladmin] to user_name;goalter authorization on schema::[db_denydatareader] to user_name;goalter authorization on schema::[db_denydatawriter] to user_name;goalter authorization on schema::[db_owner] to user_name;goalter authorization on schema::[db_securityadmin] to user_name;goalter authorization on schema::[guest] to user_name;go删除拥有的架构(把架构付给自己就行了)goalter authorization on schema::[db_accessadmin] to db_accessadmin;goalter authorization on schema::[db_backupoperator] to db_backupoperator;goalter authorization on schema::[db_datareader] to db_datareader;goalter authorization on schema::[db_datawriter] to db_datawriter;goalter authorization on schema::[db_ddladmin] to db_ddladmin;goalter authorization on schema::[db_denydatareader] to db_denydatareader;goalter authorization on schema::[db_denydatawriter] to db_denydatawriter;goalter authorization on schema::[db_owner] to db_owner;goalter authorization on schema::[db_securityadmin] to db_securityadmin;goalter authorization on schema::[guest] to guest;go –添加成员身份use database_name;goalter role [db_accessadmin] add member user_name;goalter role [db_backupoperator] add member user_name;goalter role [db_datareader] add member user_name;goalter role [db_datawriter] add member user_name;goalter role [db_ddladmin] add member user_name;goalter role [db_denydatareader] add member user_name;goalter role [db_denydatawriter] add member user_name;goalter role [db_owner] add member user_name;goalter role [db_securityadmin] add member user_name;go–删除成员身份use database_name;goalter role [db_accessadmin] drop member user_name;goalter role [db_backupoperator] drop member user_name;goalter role [db_datareader] drop member user_name;goalter role [db_datawriter] drop member user_name;goalter role [db_ddladmin] drop member user_name;goalter role [db_denydatareader] drop member user_name;goalter role [db_denydatawriter] drop member user_name;goalter role [db_owner] drop member user_name;goalter role [db_securityadmin] drop member user_name;go –安全对象–use database_name;–go–授予权限–备份日志grant backup log to user_name;go–备份数据库grant backup database to user_name;go–插入grant insert to user_name;go–查看定义grant view definition to user_name;go–查看任意列加密密钥定义grant view any column encryption key definition to user_name;go–查看任意列主密钥定义grant view any column master key definition to user_name;go–查看数据库状态grant view database state to user_name;go–撤销掩码grant unmask to user_name;go–创建xml架构集合grant create xml schema collection to user_name;go–创建表grant create table to user_name;go–创建程序集grant create assembly to user_name;go–创建队列GRANT CREATE QUEUE to user_name;go–创建对称密钥grant create symmetric key to user_name;go–创建非对称密钥grant create asymmetric key to user_name;go–创建服务grant create service to user_name;go–创建规则grant create rule to user_name;go–创建过程grant create procedure to user_name;go–创建函数grant create function to user_name;go–创建架构grant create schema to user_name;go–创建角色grant create role to user_name;go–创建类型grant create type to user_name;go–创建路由grant create route to user_name;go–创建默认值grant create default to user_name;go–创建全文目录grant create fulltext catalog to user_name;go–创建视图grant create view to user_name;go–创建数据库DDL事件通知grant create database dll event notification to user_name;go–创建同义词grant create synonym to user_name;go–创建消息类型grant create message type to user_name;go–创建远程服务绑定grant create remote service binding to user_name;go–创建约定grant create contract to user_name;go–创建证书grant create certificate to user_name;go–订阅查询通知grant subscribe query notifications to user_name;go–更改grant alter to user_name;go–更改任何外部数据源grant alter any external data source to user_name;go–更改任何外部文件格式grant alter any external file format to user_name;go–更改任何掩码grant alter any mask to user_name;go–更改任意安全策略grant alter any security policy to user_name;go–更改任意程序集grant alter any assembly to user_name;go–更改任意对称密钥grant alter any symmetric key to user_name;go–更改任意非对称密钥grant alter any asymmetric key to user_name;go–更改任意服务grant alter any service to user_name;go–更改任意架构grant alter any schema to user_name;go–更改任意角色grant alter any role to user_name;go–更改任意路由grant alter any route to user_name;go–更改任意全文目录grant alter any fulltext catalog to user_name;go–更改任意数据空间grant alter any dataspace to user_name;go–更改任意数据库DDL数据库触发器grant alter any database ddl trigger to user_name;go–更改任意数据库审核grant alter any database audit to user_name;go–更改任意数据库事件通知grant alter any database event notification to user_name;go–更改任意消息类型grant alter any message type to user_name;go–更改任意应用程序角色grant alter any application role to user_name;go–更改任意用户grant alter any user to user_name;go–更改任意远程服务绑定grant alter any remote service binding to user_name;go–更改任意约定grant alter any contract to user_name;go–更改任意证书grant alter any certificate to user_name;go–更新grant update to user_name;go–检查点grant checkpoint to user_name;go–接管所有权grant take ownership to user_name;go–控制grant control to user_name;go–控制聚合grant create aggregate to user_name;go–连接grant connect to user_name;go–连接复制grant connect replication to user_name;go–删除grant delete to user_name;go–身份验证grant authenticate to user_name;go–显示计划grant showplan to user_name;go–选择grant select to user_name;go–引用grant references to user_name;go–执行grant execute to user_name;go –授予并允许转售权限–安全对象–use database_name;–go–备份日志grant backup log to user_name with grant option;go–备份数据库grant backup database to user_name with grant option;go–插入grant insert to user_name with grant option;go–查看定义grant view definition to user_name with grant option;go–查看任意列加密密钥定义grant view any column encryption key definition to user_name with grant option;go–查看任意列主密钥定义grant view any column master key definition to user_name with grant option;go–查看数据库状态grant view database state to user_name with grant option;go–撤销掩码grant unmask to user_name with grant option;go–创建xml架构集合grant create xml schema collection to user_name with grant option;go–创建表grant create table to user_name with grant option;go–创建程序集grant create assembly to user_name with grant option;go–创建队列GRANT CREATE QUEUE to user_name with grant option;go–创建对称密钥grant create symmetric key to user_name with grant option;go–创建非对称密钥grant create asymmetric key to user_name with grant option;go–创建服务grant create service to user_name with grant option;go–创建规则grant create rule to user_name with grant option;go–创建过程grant create procedure to user_name with grant option;go –创建函数grant create function to user_name with grant option;go–创建架构grant create schema to user_name with grant option;go–创建角色grant create role to user_name with grant option;go–创建类型grant create type to user_name with grant option;go–创建路由grant create route to user_name with grant option;go–创建默认值grant create default to user_name with grant option;go–创建全文目录grant create fulltext catalog to user_name with grant option;go–创建视图grant create view to user_name with grant option;go–创建数据库DDL事件通知grant create database dll event notification to user_name with grant option;go–创建同义词grant create synonym to user_name with grant option;go–创建消息类型grant create message type to user_name with grant option;go–创建远程服务绑定grant create remote service binding to user_name with grant option;go–创建约定grant create contract to user_name with grant option;go–创建证书grant create certificate to user_name with grant option;go–订阅查询通知grant subscribe query notifications to user_name with grant option;go–更改grant alter to user_name with grant option;go–更改任何外部数据源grant alter any external data source to user_name with grant option;go–更改任何外部文件格式grant alter any external file format to user_name with grant option;go–更改任何掩码grant alter any mask to user_name with grant option;go–更改任意安全策略grant alter any security policy to user_name with grant option;go–更改任意程序集grant alter any assembly to user_name with grant option;go–更改任意对称密钥grant alter any symmetric key to user_name with grant option;go–更改任意非对称密钥grant alter any asymmetric key to user_name with grant option;go–更改任意服务grant alter any service to user_name;go–更改任意架构grant alter any schema to user_name with grant option;go–更改任意角色grant alter any role to user_name with grant option;go–更改任意路由grant alter any route to user_name with grant option;go–更改任意全文目录grant alter any fulltext catalog to user_name with grant option;go–更改任意数据空间grant alter any dataspace to user_name with grant option;go–更改任意数据库DDL数据库触发器grant alter any database ddl trigger to user_name with grant option;go–更改任意数据库审核grant alter any database audit to user_name with grant option;go–更改任意数据库事件通知grant alter any database event notification to user_name with grant option;go–更改任意消息类型grant alter any message type to user_name with grant option;go–更改任意应用程序角色grant alter any application role to user_name with grant option;go–更改任意用户grant alter any user to user_name with grant option;go–更改任意远程服务绑定grant alter any remote service binding to user_name with grant option;go–更改任意约定grant alter any contract to user_name with grant option;go–更改任意证书grant alter any certificate to user_name with grant option;go–更新grant update to user_name with grant option;go–检查点grant checkpoint to user_name with grant option;go–接管所有权grant take ownership to user_name with grant option;go–控制grant control to user_name with grant option;go–控制聚合grant create aggregate to user_name with grant option;go–连接grant connect to user_name with grant option;go–连接复制grant connect replication to user_name with grant option;go–删除grant delete to user_name with grant option;go–身份验证grant authenticate to user_name with grant option;go–显示计划grant showplan to user_name with grant option;go–选择grant select to user_name with grant option;go–引用grant references to user_name with grant option;go–执行grant execute to user_name with grant option;go –拒绝权限–安全对象use database_name;go–备份日志deny backup log to user_name;go–备份数据库deny backup database to user_name;go–插入deny insert to user_name;go–查看定义deny view definition to user_name;go–查看任意列加密密钥定义deny view any column encryption key definition to user_name;go–查看任意列主密钥定义deny view any column master key definition to user_name;go–查看数据库状态deny view database state to user_name;go–撤销掩码deny unmask to user_name;go–创建xml架构集合deny create xml schema collection to user_name;go–创建表deny create table to user_name;go–创建程序集deny create assembly to user_name;go–创建队列deny CREATE QUEUE to user_name;go–创建对称密钥deny create symmetric key to user_name;go–创建非对称密钥deny create asymmetric key to user_name;go–创建服务deny create service to user_name;go–创建规则deny create rule to user_name;go–创建过程deny create procedure to user_name;go–创建函数deny create function to user_name;go–创建架构deny create schema to user_name;go–创建角色deny create role to user_name;go–创建类型deny create type to user_name;go–创建路由deny create route to user_name;go–创建默认值deny create default to user_name;go–创建全文目录deny create fulltext catalog to user_name;go–创建视图deny create view to user_name;go–创建数据库DDL事件通知deny create database dll event notification to user_name;go–创建同义词deny create synonym to user_name;go–创建消息类型deny create message type to user_name;go–创建远程服务绑定deny create remote service binding to user_name;go–创建约定deny create contract to user_name;go–创建证书deny create certificate to user_name;go–订阅查询通知deny subscribe query notifications to user_name;go–更改deny alter to user_name;go–更改任何外部数据源deny alter any external data source to user_name;go–更改任何外部文件格式deny alter any external file format to user_name;go–更改任何掩码deny alter any mask to user_name;go–更改任意安全策略deny alter any security policy to user_name;go–更改任意程序集deny alter any assembly to user_name;go–更改任意对称密钥deny alter any symmetric key to user_name;go–更改任意非对称密钥deny alter any asymmetric key to user_name;go–更改任意服务deny alter any service to user_name;go–更改任意架构deny alter any schema to user_name;go–更改任意角色deny alter any role to user_name;go–更改任意路由deny alter any route to user_name;go–更改任意全文目录deny alter any fulltext catalog to user_name;go–更改任意数据空间deny alter any dataspace to user_name;go–更改任意数据库DDL数据库触发器deny alter any database ddl trigger to user_name;go–更改任意数据库审核deny alter any database audit to user_name;go–更改任意数据库事件通知deny alter any database event notification to user_name;go–更改任意消息类型deny alter any message type to user_name;go–更改任意应用程序角色deny alter any application role to user_name;go–更改任意用户deny alter any user to user_name;go–更改任意远程服务绑定deny alter any remote service binding to user_name;go–更改任意约定deny alter any contract to user_name;go–更改任意证书deny alter any certificate to user_name;go–更新deny update to user_name;go–检查点deny checkpoint to user_name;go–接管所有权deny take ownership to user_name;go–控制deny control to user_name;go–控制聚合deny create aggregate to user_name;go–连接deny connect to user_name;go–连接复制deny connect replication to user_name;go–删除deny delete to user_name;go–身份验证deny authenticate to user_name;go–显示计划deny showplan to user_name;go–选择deny select to user_name;go–引用deny references to user_name;go–执行deny execute to user_name;go –扩展属性–声明数据库引用–use database_namego–添加扩展注释exec sys.sp_addextendedproperty @name=N’description_name’, @value=N’description_value’, @level0type=N’user’,@level0name=N’user_name’;go–删除扩展注释exec sys.sp_dropextendedproperty @name=N’description_name’, @level0type=N’user’,@level0name=N’user_name’go语法注释–database_name–数据库名称–user_name–指定在此数据库中用于识别该用户的名称。–login=login_name–通过将用户的安全标识符(SID)更改为另一个登录名的SID,使用户重新映射到该登录名。–如果ALTER USER语句是SQL批处理中唯一的语句,则Windows Azure SQL Database将支持WITH LOGIN子句。 –如果 ALTER USER 语句不是SQL批处理中唯一的语句或在动态SQL中执行,则不支持WITH LOGIN子句。–name=new_user_name–指定此用户的新名称。 newUserName 不能已存在于当前数据库中。–default_schema={ schemaname | null }–指定服务器在解析此用户的对象名时将搜索的第一个架构。 –将默认架构设置为NULL将从Windows组中删除默认架构。Windows用户不能使用NULL选项。–password=‘password’ [old_password=‘old_password’]–适用范围:SQL Server 2012 (11.x)到SQL Server 2017、SQL Database。–指定正在更改的用户的密码。 密码是区分大小写的。–old_password=‘old_password’–适用范围:SQL Server 2012 (11.x)到SQL Server 2017、SQL Database。–将替换为“password”的当前用户密码。密码是区分大小写的。–除非拥有ALTER ANY USER权限,否则需要具有OLD_PASSWORD才能更改密码。需要OLD_PASSWORD可防止拥有IMPERSONATION权限的用户更改密码。–此选项仅适用于包含的用户。–default_language={ none | <lcid> | <language_name> | <language alias> }–适用范围: SQL Server 2012 (11.x) 到 SQL Server 2017。–指定将指派给用户的默认语言。如果将此选项设置为NONE,则默认语言将设置为数据库的当前默认语言。如果之后更改数据库的默认语言,用户的默认语言将保持不变。–DEFAULT_LANGUAGE可以为本地 ID (lcid)、语言的名称或语言别名。–此选项只能在包含数据库中指定,且只能用于包含的用户。–allow_encrypted_value_modifications={ on | off }–适用范围:SQL Server 2016 (13.x)到SQL Server 2017、SQL Database。–取消在大容量复制操作期间对服务器进行加密元数据检查。 这使用户能够在表或数据库之间大容量复制加密数据,而无需对数据进行解密。 默认为 OFF。–description_name–用户自定义用户注释名称–description_value–用户自定义用户注释值示例/示例/–声明数据库引用use [testss];go –添加拥有的架构alter authorization on schema::[db_accessadmin] to test1;go–删除拥有的架构alter authorization on schema::[db_accessadmin] to db_accessadmin;go –添加成员身份alter role [db_backupoperator] add member test1;goalter role [db_datareader] add member test1;go–删除成员身份alter role [db_backupoperator] drop member test1;goalter role [db_datareader] drop member test1;go –安全对象–授予权限–备份日志grant backup log to test1;go –扩展属性–删除扩展属性exec sys.sp_dropextendedproperty @name=N’tests_description’, @level0type=N’user’,@level0name=N’test1’go–添加扩展注释exec sys.sp_addextendedproperty @name=N’tests_description’, @value=N’用户自定义用户描述’, @level0type=N’user’,@level0name=N’test1’;go –修改当前数据库用户自定义用户属性alter user test1withname=test1,default_schema=dbo,–login=tests,–password=‘1234’ old_password=‘1234’,–default_language=English,allow_encrypted_value_modifications=off;go示例结果 ...

January 8, 2019 · 8 min · jiezi

SQLServer创建用户自定义数据库用户

创建用户自定义数据库用户注意事项如果已忽略 FOR LOGIN,则新的数据库用户将被映射到同名的SQL Server登录名。默认架构将是服务器为此数据库用户解析对象名时将搜索的第一个架构。 除非另外指定,否则默认架构将是此数据库用户创建的对象所属的架构。如果用户具有默认架构,则将使用默认架构。 如果用户不具有默认架构,但该用户是具有默认架构的组的成员,则将使用该组的默认架构。 如果用户不具有默认架构而且是多个组的成员,则该用户的默认架构将是具有最低principle_id的Windows组的架构和一个显式设置的默认架构。(不可能将可用的默认架构之一显式选作首选架构。)如果不能为用户确定默认架构,则将使用 dbo 架构。DEFAULT_SCHEMA可在创建它所指向的架构前进行设置。在创建映射到证书或非对称密钥的用户时,不能指定DEFAULT_SCHEMA。如果用户是sysadmin固定服务器角色的成员,则忽略DEFAULT_SCHEMA的值。sysadmin固定服务器角色的所有成员都有默认架构dbo。WITHOUT LOGIN子句可创建不映射到SQL Server登录名的用户。它可以作为guest连接到其他数据库。可以将权限分配给这一没有登录名的用户,当安全上下文更改为没有登录名的用户时,原始用户将收到无登录名用户的权限。 只有映射到Windows主体的用户才能包含反斜杠字符 ()。不能使用CREATE USER创建guest用户,因为每个数据库中均已存在guest用户。可通过授予guest用户CONNECT权限来启用该用户,如下所示:可以在 sys.database_principals 目录视图中查看有关数据库用户的信息。使用SSMS数据库管理工具创建用户自定义数据库用户1、连接服务器-》在对象资源管理器窗口选择数据库-》展开数据库-》展开安全性-》展开用户-》右键点击用户-》选择新建。2、在数据库用户-新建弹出框-》点击常规-》选择用户类型-》输入用户名-》选择登录名-》选择用户所属架构。3、在数据库用户-新建弹出框-》选择用户所拥有的架构。4、在数据库用户-新建弹出框-》点击成员身份-》选择数据库成员身份。5、在数据库用户-新建弹出框-》点击搜索选择一个安全对象-》选择安全对象以后选择安全对象所拥有的权限。6、在数据库用户-新建弹出框-》选择扩展属性-》输入注释名称-》输入注释值-》点击确定。7、不需要刷新即可在对象资源管理器查看创建结果。使用T-SQL脚本创建用户自定义数据库用户语法—-创建用户自定义数据库用户—-声明数据库引用–use database_name;–go—-windows用户–create user user_name for login login_name with default_schema=architecture_name,allow_encrypted_value_modifications={ on | off };—-不带登录名的SQL用户–create user user_name without login with default_schema=architecrure_name,allow_encrypted_value_modifications={ on | off };—-带登录名的SQL用户–create user user_name for login login_name with default_schema=architecture_name,allow_encrypted_value_modifications={ on | off };—-映射到非对称密钥的用户–create user user_name for asymmetric key asym_key_name;—-映射到证书的用户–create user user_name for certificate certificate_name; –拥有的架构–use database_name;–go–alter authorization on schema::[db_accessadmin] to user_name;–go–alter authorization on schema::[db_backupoperator] to user_name;–go–alter authorization on schema::[db_datareader] to user_name;–go–alter authorization on schema::[db_datawriter] to user_name;–go–alter authorization on schema::[db_ddladmin] to user_name;–go–alter authorization on schema::[db_denydatareader] to user_name;–go–alter authorization on schema::[db_denydatawriter] to user_name;–go–alter authorization on schema::[db_owner] to user_name;–go–alter authorization on schema::[db_securityadmin] to user_name;–go–alter authorization on schema::[guest] to user_name;–go –成员身份–use database_name;–go–alter role [db_accessadmin] add member user_name;–go–alter role [db_backupoperator] add member user_name;–go–alter role [db_datareader] add member user_name;–go–alter role [db_datawriter] add member user_name;–go–alter role [db_ddladmin] add member user_name;–go–alter role [db_denydatareader] add member user_name;–go–alter role [db_denydatawriter] add member user_name;–go–alter role [db_owner] add member user_name;–go–alter role [db_securityadmin] add member user_name;–go —-安全对象—-use database_name;—-go—-授予权限—-备份日志–grant backup log to user_name;–go—-备份数据库–grant backup database to user_name;–go—-插入–grant insert to user_name;–go—-查看定义–grant view definition to user_name;–go—-查看任意列加密密钥定义–grant view any column encryption key definition to user_name;–go—-查看任意列主密钥定义–grant view any column master key definition to user_name;–go—-查看数据库状态–grant view database state to user_name;–go—-撤销掩码–grant unmask to user_name;–go—-创建xml架构集合–grant create xml schema collection to user_name;–go—-创建表–grant create table to user_name;–go—-创建程序集–grant create assembly to user_name;–go—-创建队列–GRANT CREATE QUEUE to user_name;–go—-创建对称密钥–grant create symmetric key to user_name;–go—-创建非对称密钥–grant create asymmetric key to user_name;–go—-创建服务–grant create service to user_name;–go—-创建规则–grant create rule to user_name;–go—-创建过程–grant create procedure to user_name;–go—-创建函数–grant create function to user_name;–go—-创建架构–grant create schema to user_name;–go—-创建角色–grant create role to user_name;–go—-创建类型–grant create type to user_name;–go—-创建路由–grant create route to user_name;–go—-创建默认值–grant create default to user_name;–go—-创建全文目录–grant create fulltext catalog to user_name;–go—-创建视图–grant create view to user_name;–go—-创建数据库DDL事件通知–grant create database dll event notification to user_name;–go—-创建同义词–grant create synonym to user_name;–go—-创建消息类型–grant create message type to user_name;–go—-创建远程服务绑定–grant create remote service binding to user_name;–go—-创建约定–grant create contract to user_name;–go—-创建证书–grant create certificate to user_name;–go—-订阅查询通知–grant subscribe query notifications to user_name;–go—-更改–grant alter to user_name;–go—-更改任何外部数据源–grant alter any external data source to user_name;–go—-更改任何外部文件格式–grant alter any external file format to user_name;–go—-更改任何掩码–grant alter any mask to user_name;–go—-更改任意安全策略–grant alter any security policy to user_name;–go—-更改任意程序集–grant alter any assembly to user_name;–go—-更改任意对称密钥–grant alter any symmetric key to user_name;–go—-更改任意非对称密钥–grant alter any asymmetric key to user_name;–go—-更改任意服务–grant alter any service to user_name;–go—-更改任意架构–grant alter any schema to user_name;–go—-更改任意角色–grant alter any role to user_name;–go—-更改任意路由–grant alter any route to user_name;–go—-更改任意全文目录–grant alter any fulltext catalog to user_name;–go—-更改任意数据空间–grant alter any dataspace to user_name;–go—-更改任意数据库DDL数据库触发器–grant alter any database ddl trigger to user_name;–go—-更改任意数据库审核–grant alter any database audit to user_name;–go—-更改任意数据库事件通知–grant alter any database event notification to user_name;–go—-更改任意消息类型–grant alter any message type to user_name;–go—-更改任意应用程序角色–grant alter any application role to user_name;–go—-更改任意用户–grant alter any user to user_name;–go—-更改任意远程服务绑定–grant alter any remote service binding to user_name;–go—-更改任意约定–grant alter any contract to user_name;–go—-更改任意证书–grant alter any certificate to user_name;–go—-更新–grant update to user_name;–go—-检查点–grant checkpoint to user_name;–go—-接管所有权–grant take ownership to user_name;–go—-控制–grant control to user_name;–go—-控制聚合–grant create aggregate to user_name;–go—-连接–grant connect to user_name;–go—-连接复制–grant connect replication to user_name;–go—-删除–grant delete to user_name;–go—-身份验证–grant authenticate to user_name;–go—-显示计划–grant showplan to user_name;–go—-选择–grant select to user_name;–go—-引用–grant references to user_name;–go—-执行–grant execute to user_name;–go —-授予并允许转售权限—-安全对象—-use database_name;—-go—-备份日志–grant backup log to user_name with grant option;–go—-备份数据库–grant backup database to user_name with grant option;–go—-插入–grant insert to user_name with grant option;–go—-查看定义–grant view definition to user_name with grant option;–go—-查看任意列加密密钥定义–grant view any column encryption key definition to user_name with grant option;–go—-查看任意列主密钥定义–grant view any column master key definition to user_name with grant option;–go—-查看数据库状态–grant view database state to user_name with grant option;–go—-撤销掩码–grant unmask to user_name with grant option;–go—-创建xml架构集合–grant create xml schema collection to user_name with grant option;–go—-创建表–grant create table to user_name with grant option;–go—-创建程序集–grant create assembly to user_name with grant option;–go—-创建队列–GRANT CREATE QUEUE to user_name with grant option;–go—-创建对称密钥–grant create symmetric key to user_name with grant option;–go—-创建非对称密钥–grant create asymmetric key to user_name with grant option;–go—-创建服务–grant create service to user_name with grant option;–go—-创建规则–grant create rule to user_name with grant option;–go—-创建过程–grant create procedure to user_name with grant option;–go —-创建函数–grant create function to user_name with grant option;–go—-创建架构–grant create schema to user_name with grant option;–go—-创建角色–grant create role to user_name with grant option;–go—-创建类型–grant create type to user_name with grant option;–go—-创建路由–grant create route to user_name with grant option;–go—-创建默认值–grant create default to user_name with grant option;–go—-创建全文目录–grant create fulltext catalog to user_name with grant option;–go—-创建视图–grant create view to user_name with grant option;–go—-创建数据库DDL事件通知–grant create database dll event notification to user_name with grant option;–go—-创建同义词–grant create synonym to user_name with grant option;–go—-创建消息类型–grant create message type to user_name with grant option;–go—-创建远程服务绑定–grant create remote service binding to user_name with grant option;–go—-创建约定–grant create contract to user_name with grant option;–go—-创建证书–grant create certificate to user_name with grant option;–go—-订阅查询通知–grant subscribe query notifications to user_name with grant option;–go—-更改–grant alter to user_name with grant option;–go—-更改任何外部数据源–grant alter any external data source to user_name with grant option;–go—-更改任何外部文件格式–grant alter any external file format to user_name with grant option;–go—-更改任何掩码–grant alter any mask to user_name with grant option;–go—-更改任意安全策略–grant alter any security policy to user_name with grant option;–go—-更改任意程序集–grant alter any assembly to user_name with grant option;–go—-更改任意对称密钥–grant alter any symmetric key to user_name with grant option;–go—-更改任意非对称密钥–grant alter any asymmetric key to user_name with grant option;–go—-更改任意服务–grant alter any service to user_name;–go—-更改任意架构–grant alter any schema to user_name with grant option;–go—-更改任意角色–grant alter any role to user_name with grant option;–go—-更改任意路由–grant alter any route to user_name with grant option;–go—-更改任意全文目录–grant alter any fulltext catalog to user_name with grant option;–go—-更改任意数据空间–grant alter any dataspace to user_name with grant option;–go—-更改任意数据库DDL数据库触发器–grant alter any database ddl trigger to user_name with grant option;–go—-更改任意数据库审核–grant alter any database audit to user_name with grant option;–go—-更改任意数据库事件通知–grant alter any database event notification to user_name with grant option;–go—-更改任意消息类型–grant alter any message type to user_name with grant option;–go—-更改任意应用程序角色–grant alter any application role to user_name with grant option;–go—-更改任意用户–grant alter any user to user_name with grant option;–go—-更改任意远程服务绑定–grant alter any remote service binding to user_name with grant option;–go—-更改任意约定–grant alter any contract to user_name with grant option;–go—-更改任意证书–grant alter any certificate to user_name with grant option;–go—-更新–grant update to user_name with grant option;–go—-检查点–grant checkpoint to user_name with grant option;–go—-接管所有权–grant take ownership to user_name with grant option;–go—-控制–grant control to user_name with grant option;–go—-控制聚合–grant create aggregate to user_name with grant option;–go—-连接–grant connect to user_name with grant option;–go—-连接复制–grant connect replication to user_name with grant option;–go—-删除–grant delete to user_name with grant option;–go—-身份验证–grant authenticate to user_name with grant option;–go—-显示计划–grant showplan to user_name with grant option;–go—-选择–grant select to user_name with grant option;–go—-引用–grant references to user_name with grant option;–go—-执行–grant execute to user_name with grant option;–go —-拒绝权限—-安全对象–use database_name;–go—-备份日志–deny backup log to user_name;–go—-备份数据库–deny backup database to user_name;–go—-插入–deny insert to user_name;–go—-查看定义–deny view definition to user_name;–go—-查看任意列加密密钥定义–deny view any column encryption key definition to user_name;–go—-查看任意列主密钥定义–deny view any column master key definition to user_name;–go—-查看数据库状态–deny view database state to user_name;–go—-撤销掩码–deny unmask to user_name;–go—-创建xml架构集合–deny create xml schema collection to user_name;–go—-创建表–deny create table to user_name;–go—-创建程序集–deny create assembly to user_name;–go—-创建队列–deny CREATE QUEUE to user_name;–go—-创建对称密钥–deny create symmetric key to user_name;–go—-创建非对称密钥–deny create asymmetric key to user_name;–go—-创建服务–deny create service to user_name;–go—-创建规则–deny create rule to user_name;–go—-创建过程–deny create procedure to user_name;–go—-创建函数–deny create function to user_name;–go—-创建架构–deny create schema to user_name;–go—-创建角色–deny create role to user_name;–go—-创建类型–deny create type to user_name;–go—-创建路由–deny create route to user_name;–go—-创建默认值–deny create default to user_name;–go—-创建全文目录–deny create fulltext catalog to user_name;–go—-创建视图–deny create view to user_name;–go—-创建数据库DDL事件通知–deny create database dll event notification to user_name;–go—-创建同义词–deny create synonym to user_name;–go—-创建消息类型–deny create message type to user_name;–go—-创建远程服务绑定–deny create remote service binding to user_name;–go—-创建约定–deny create contract to user_name;–go—-创建证书–deny create certificate to user_name;–go—-订阅查询通知–deny subscribe query notifications to user_name;–go—-更改–deny alter to user_name;–go—-更改任何外部数据源–deny alter any external data source to user_name;–go—-更改任何外部文件格式–deny alter any external file format to user_name;–go—-更改任何掩码–deny alter any mask to user_name;–go—-更改任意安全策略–deny alter any security policy to user_name;–go—-更改任意程序集–deny alter any assembly to user_name;–go—-更改任意对称密钥–deny alter any symmetric key to user_name;–go—-更改任意非对称密钥–deny alter any asymmetric key to user_name;–go—-更改任意服务–deny alter any service to user_name;–go—-更改任意架构–deny alter any schema to user_name;–go—-更改任意角色–deny alter any role to user_name;–go—-更改任意路由–deny alter any route to user_name;–go—-更改任意全文目录–deny alter any fulltext catalog to user_name;–go—-更改任意数据空间–deny alter any dataspace to user_name;–go—-更改任意数据库DDL数据库触发器–deny alter any database ddl trigger to user_name;–go—-更改任意数据库审核–deny alter any database audit to user_name;–go—-更改任意数据库事件通知–deny alter any database event notification to user_name;–go—-更改任意消息类型–deny alter any message type to user_name;–go—-更改任意应用程序角色–deny alter any application role to user_name;–go—-更改任意用户–deny alter any user to user_name;–go—-更改任意远程服务绑定–deny alter any remote service binding to user_name;–go—-更改任意约定–deny alter any contract to user_name;–go—-更改任意证书–deny alter any certificate to user_name;–go—-更新–deny update to user_name;–go—-检查点–deny checkpoint to user_name;–go—-接管所有权–deny take ownership to user_name;–go—-控制–deny control to user_name;–go—-控制聚合–deny create aggregate to user_name;–go—-连接–deny connect to user_name;–go—-连接复制–deny connect replication to user_name;–go—-删除–deny delete to user_name;–go—-身份验证–deny authenticate to user_name;–go—-显示计划–deny showplan to user_name;–go—-选择–deny select to user_name;–go—-引用–deny references to user_name;–go—-执行–deny execute to user_name;–go —-扩展属性—-声明数据库引用—-use database_name–go—-添加扩展注释–exec sys.sp_addextendedproperty @name=N’description_name’, @value=N’description_value’, @level0type=N’user’,@level0name=N’user_name’;–go语法注释–database_name–数据库名称–user_name–指定在此数据库中用于识别该用户的名称。user_name 为 sysname。 –它的长度最多是 128 个字符。在创建基于Windows主体的用户时,除非指定其他用户名,否则Windows主体名称将成为用户名。–login_name–指定要为其创建数据库用户的登录名。login_name必须是服务器中的有效登录名。 –可以是基于Windows主体(用户或组)的登录名,也可以是使用SQL Server身份验证的登录名。–当此SQL Server登录名进入数据库时,它将获取正在创建的这个数据库用户的名称和ID。–在创建从 Windows 主体映射的登录名时,请使用格式 [<domainName><loginName>]。 –如果CREATE USER语句是SQL批处理中唯一的语句,则Windows Azure SQL Databas 将支持WITH LOGIN子句。 –如果CREATE USER语句不是SQL批处理中唯一的语句或在动态SQL中执行,则不支持 WITH LOGIN 子句。–with default_schema=architecture_name;–指定服务器为此数据库用户解析对象名时将搜索的第一个架构。–allow_encrypted_value_modifications={ on | off } –适用范围:SQL Server 2016 (13.x) 到SQL Server 2017、SQL Database。–取消在大容量复制操作期间对服务器进行加密元数据检查。这使用户能够在表或数据库之间大容量复制加密数据,–而无需对数据进行解密。默认为 OFF。–without login–指定不应将用户映射到现有登录名。–asymmetric KEY asym_key_name–适用范围:SQL Server 2008到SQL Server 2017、SQL Database。–指定要为其创建数据库用户的非对称密钥。–certificate certificate_name–适用范围:SQL Server 2008到SQL Server 2017、SQL Database。–指定要为其创建数据库用户的证书。–description_name–用户自定义用户注释名称。–description_value–用户自定义用户注释值。示例/示例/–声明数据库引用use [testss];go–判断用户是否存在,如果存在则删除,不存在则创建if exists(select * from sys.database_principals where name=‘tests’)–把架构修改回来架构自身alter authorization on schema::[db_accessadmin] to db_accessadmin;–删除角色拥有的成员alter role [db_accessadmin] drop member tests;–删除用户drop user tests;go–创建当前数据库用户自定义用户create user testsfor login testswith default_schema=dbo,allow_encrypted_value_modifications=on; –拥有的架构use testss;goalter authorization on schema::[db_accessadmin] to tests;go –成员身份use testss;goalter role [db_accessadmin] add member tests;go –安全对象use testss;go–授予权限–备份日志grant backup log to tests;go –扩展属性–声明数据库引用–use database_namego–添加扩展注释exec sys.sp_addextendedproperty @name=N’tests_description’, @value=N’用户自定义用户描述’, @level0type=N’user’,@level0name=N’tests’;go示例结果 ...

January 6, 2019 · 7 min · jiezi

SQLServer之删除用户定义的数据库角色

删除用户定义的数据库角色注意事项无法从数据库删除拥有安全对象的角色。 若要删除拥有安全对象的数据库角色,必须首先转移这些安全对象的所有权,或从数据库删除它们。 无法从数据库删除拥有成员的角色。 若要删除拥有成员的角色,必须首先删除角色的成员。若要删除数据库角色中的成员,请使用 ALTER ROLE (Transact-SQL)。不能使用 DROP ROLE 删除固定数据库角色。在 sys.database_role_members 目录视图中可以查看有关角色成员身份的信息。若要删除服务器角色,请使用DROP SERVER ROLE (Transact-SQL)。要求对数据库具有 ALTER ANY ROLE 权限、对角色具有 CONTROL 权限或具有 db_securityadmin 中的成员身份。使用SSMS数据库管理工具删除用户定义的数据库角色1、连接服务器-》在对象资源管理器窗口,展开数据库-》选择数据库并展开-》展开安全性-》展开角色-》展开数据库角色-》选择要删除的数据库角色-》右键点击-》选择删除。2、在删除对象弹出框-》点击确定。3、不需要刷新即可在对象资源管理器窗口看到删除结果。使用T-SQL脚本删除用户定义的数据库角色语法–声明数据库引用use database_name;go –创建用新的数据库角色之前判断角色是否已存在,如果已存在则删除。if exists(select * from sys.database_principals where name=role_name)drop role role_name;go语法注释–语法注释–database_name–引用数据库名称–role_name–指定要从数据库删除的角色。示例–声明数据库引用use [testss];go –创建用新的数据库角色之前判断角色是否已存在,如果已存在则删除。if exists(select * from sys.database_principals where name=‘testrole’)drop role testrole;go示例结果:使用T-SQL脚本删除角色需要刷新数据库角色文件夹才能查看删除结果。

January 5, 2019 · 1 min · jiezi

SQLServer更改用户定义的数据库角色

更改用户定义的数据库角色注意事项需具有以下一项或多项权限或成员身份才能运行此命令:对角色具有 ALTER 权限对数据库具有 ALTER ANY ROLE 权限具有 db_securityadmin 固定数据库角色的成员身份此外,若要更改固定数据库角色中的成员身份还需要:具有 db_owner 固定数据库角色的成员身份不能更改固定数据库角色的名称。使用SSMS数据库管理工具更改用户定义的数据库角色1、连接数据库-》选择数据库-》展开安全性-》展开角色-》展开数据库角色-》选择要修改的数据库角色-》右键点击-》选择属性。2、在数据库角色属性弹出框-》点击常规-》修改角色所有者-》修改角色拥有的架构(数据库架构,类似于数据库对象的命名空间,用户通过架构访问数据库对象,数据库角色可以添加,可以定制不同权限,可以拥有一个或者多个数据库架构)-》修改角色成员(角色指定向数据库角色的成员身份添加数据库主体)。3、在数据库角色属性弹出框-》点击安全对象-》修改数据库角色名称-》修改数据库角色安全对象-》修改数据库角色安全对象权限(当使用角色执行数据库操作、对象和资源时,通过安全对象和权限设置来定义和解决这个问题)。4、在数据库角色属性弹出框-》点击扩展属性-》修改数据库角色注释(对角色进行注释解说)-》点击确定,修改完成。使用T-SQL脚本更改用户定义的数据库角色语法–声明数据库引用use database_name;go–修改数据库中创建新的数据库角色名称alter role role_name with name=new_role_name;go –修改此角色拥有的架构 –添加时执行下列语法use database_namegoalter authorization on schema::架构名称 to role_name;go–删除或者时把架构拥有者改为架构本身即,注意不要删除架构use database_namegoalter authorization on schema::架构名称 to 架构名称;go —-此角色的成员–添加成员use database_namegoalter role role_name add member database_principal;go—-删除成员use database_namegoalter role role_name drop member database_principal;go —-此角色的安全对象—-授予权限use database_namego—-授予备份日志的权限grant 权限名称 to role_name;go—-授予并允许转授备份日志的权限grant 权限名称 to role_name with grant option;go—-回收授予并允许转转授备份数据库的权限revoke grant option for 权限名称 to role_name cascade as 所有者;go—-拒绝不安全的程序集deny 权限名称 to role_name cascade;go –修改此角色注释use database_namegoexec sys.sp_updateextendedproperty @name=扩展属性名称, @value=扩展属性值 , @level0type=N’user’,@level0name=role_name ;go语法注释–database_name–数据库名称–role_name–适用范围:SQL Server(从 2008 版开始)和 Azure SQL Database–指定要更改的数据库角色。–with name=new_role_name–适用范围:SQL Server(从 2008 版开始)和 Azure SQL Database–指定更改用户定义的数据库角色的名称。 数据库中必须尚未包含新名称。–更改数据库角色的名称不会更改角色的 ID 号、所有者或权限。–add member database_principal–适用范围:SQL Server(从 2012 版开始)和Azure SQL Database–指定向数据库角色的成员身份添加数据库主体。–database_principal 是数据库用户或用户定义的数据库角色。–database_principal 不能是固定的数据库角色或是服务器主体。–drop member database_principal–适用范围:SQL Server(从 2012 版开始)和Azure SQL Database–指定从数据库角色的成员身份删除数据库主体。–database_principal 是数据库用户或用户定义的数据库角色。–database_principal 不能是固定的数据库角色或是服务器主体。示例–修改此角色拥有的架构 –添加时执行下列语法–use [testss]–go–alter authorization on schema::[db_accessadmin] to testrole;–go–删除或者时把架构拥有者改为架构本身即,注意不要删除架构use [testss]goalter authorization on schema::[db_accessadmin] to [db_accessadmin]go /**********语法添加角色成员alter role role_name add member database_principal–add member database_principal–适用范围:SQL Server(从 2012 版开始)和Azure SQL Database–指定向数据库角色的成员身份添加数据库主体。–database_principal 是数据库用户或用户定义的数据库角色。–database_principal 不能是固定的数据库角色或是服务器主体。 删除角色成员alter role role_name drop member database_principal–drop member database_principal–适用范围:SQL Server(从 2012 版开始)和Azure SQL Database–指定从数据库角色的成员身份删除数据库主体。–database_principal 是数据库用户或用户定义的数据库角色。–database_principal 不能是固定的数据库角色或是服务器主体。***********/—-此角色的成员–添加成员–use [testss]–go–alter role testrole add member [guest];–go—-删除成员use [testss]goalter role [testrole] drop member [guest];go —-此角色的安全对象—-授予权限–use [testss]–go—-授予备份日志的权限–grant backup log to [testrole];–go—-授予并允许转授备份日志的权限–grant backup log to [testrole] with grant option;–go—-回收授予并允许转转授备份数据库的权限–revoke grant option for backup log to [testrole] cascade as [dbo];–go—-拒绝不安全的程序集–deny backup log to [testrole] cascade;–go –修改此角色注释use [testss]goexec sys.sp_updateextendedproperty @name=N’roledescript’, @value=N’修改测试角色’ , @level0type=N’user’,@level0name=N’testrole’;go /语法alter role role_name with name=new_name;–role_name–适用范围:SQL Server(从 2008 版开始)和 Azure SQL Database–指定要更改的数据库角色。–with name=new_name–适用范围:SQL Server(从 2008 版开始)和 Azure SQL Database–指定更改用户定义的数据库角色的名称。 数据库中必须尚未包含新名称。–更改数据库角色的名称不会更改角色的 ID 号、所有者或权限。/–声明数据库引用use [testss];go–修改数据库中创建新的数据库角色名称alter role testrole with name=alterrole;go示例结果:注意T-SQL脚本执行完成之后需要刷信查看执行结果! ...

January 4, 2019 · 2 min · jiezi

SQLServer删除登录帐户

删除登陆账户注意事项不能删除正在登录的登录名。 也不能删除拥有任何安全对象、服务器级对象或 SQL Server 代理作业的登录名。可以删除数据库用户映射到的登录名,但是这会创建孤立用户。 有关详细信息,请参阅 孤立用户故障排除 (SQL Server)。在 SQL Database中,对连接和服务器级别的防火墙规则进行身份验证时所需的登录数据会暂时缓存在每个数据库中。 此缓存定期刷新。 若要强制刷新身份验证缓存并确保数据库具有最新版本的登录名表,请执行 DBCC FLUSHAUTHCACHE (Transact-SQL)。要求对服务器拥有 ALTER ANY LOGIN 权限。使用SSMS数据库管理工具删除登陆账户1、连接数据库-》展开安全性-》展开登陆名-》选择要删除的登录名-》右键点击-》选择删除。2、在删除对象弹出框-》点击确定。3、不需要刷新-》在登录名查看,登陆对象已被删除。使用T-SQL脚本删除登陆账户语法–声明数据库引用use database_name;go –判断是否存在用户,如果存在则删除if exists(select * from sys.sql_logins where name=login_name)drop login login_name;go语法解析–database_name–数据库名称–login_name–指定要删除的登录名。示例–声明数据库引用use [testss]go –判断是否存在用户,如果存在则删除if exists(select * from sys.sql_logins where name=‘testuser’)drop login [testuser];go示例结果

January 2, 2019 · 1 min · jiezi

SQLServer修改登陆账户信息

修改登陆账户信息注意事项如果 CHECK_POLICY设置为ON,则无法使用 HASHED参数。如果 CHECK_POLICY更改为ON,则将出现以下行为:用当前的密码哈希值初始化密码历史记录。如果 CHECK_POLICY 更改为 OFF,则将出现以下行为:CHECK_EXPIRATION 也设置为 OFF。清除密码历史记录。重置 lockout_time 的值。如果指定MUST_CHANGE,则CHECK_EXPIRATION和CHECK_POLICY必须设置为ON。 否则,该语句将失败。如果CHECK_POLICY设置为OFF,则CHECK_EXPIRATION不能设置为ON。 包含此选项组合的 ALTER LOGIN 语句将失败。不能使用带DISABLE 参数的ALTER_LOGIN来拒绝对Windows 组的访问。 例如,ALTER_LOGIN [domaingroup] DISABLE将返回下列错误信息:“消息 15151,级别 16,状态 1,第 1 行"“无法更改登录名 ‘DomainGroup’,因为它不存在,或者你没有相应权限。“这是设计的结果。在SQL Database中,对连接和服务器级别的防火墙规则进行身份验证时所需的登录数据会暂时缓存在每个数据库中。 此缓存定期刷新。 若要强制刷新身份验证缓存并确保数据库具有最新版本的登录名表,请执行DBCC FLUSHAUTHCACHE (Transact-SQL)。需要ALTER ANY LOGIN权限。如果使用CREDENTIAL选项,则还需要ALTER ANY CREDENTIAL权限。如果正在更改的登录名是sysadmin固定服务器角色的成员或CONTROL SERVER权限的被授权者,则进行以下更改时还需要CONTROL SERVER权限:在不提供旧密码的情况下重置密码。启用MUST_CHANGE、CHECK_POLICY或CHECK_EXPIRATION。更改登录名。启用或禁用登录名。将登录名映射到其他凭据。主体可更改用于自身登录的密码、默认语言以及默认数据库。使用SSMS数据库管理工具修改登陆账户信息1、连接数据库-》展开安全性-》展开登陆名-》选择要修改的登陆账户-》右键点击-》选择属性。2、在登陆属性弹出框-》点击常规-》修改登陆名、密码、证书、映射到凭据、默认数据库、语言等。3、在登陆属性弹出框-》点击服务器角色-》修改服务器角色(数据库角色指定了可以访问相同数据库对象的一组数据库用户)。4、在登陆属性弹出框-》点击服务器角色-》修改用户映射(登录名用于授权并访问服务器资源,如果需要访问数据库,需要对数据库内部的用户进行映射。用户是数据库级别的安全主体,访问数据库资源是授予给用户,而不是登录名。)。5、在登陆属性弹出框-》点击安全对象-》修改数据库安全对象和安全对象权限(安全对象,是SQL Server 数据库引擎授权系统控制对其进行访问的资源。通俗点说,就是在SQL Server权限体系下控制的对象,因为所有的对象(从服务器,到表,到视图触发器等)都在SQL Server的权限体系控制之下,所以在SQL Server中的任何对象都可以被称为安全对象)。6、在登陆属性弹出框-》点击状态-》修改登陆账户状态(禁用用户登陆或者连接数据库)。使用T-SQL脚本修改登陆账户信息启用或禁用此登录名语法–声明数据库引用use database_name;go –创建登录用户alter login login_name { enable | disable }go语法解析–database_name–数据库名–login_name–指定正在更改的SQL Server登录名的名称。 域登录名必须用方括号括起来,其格式为[domainuser]。–enable | disable–启用或禁用此登录名。 禁用登录名不会影响已连接登录名的行为。 –(使用 KILL 语句终止现有连接。)禁用的登录名将保留它们的权限,且仍然可以模拟。示例–声明数据库引用use testss;go –创建登录用户alter login testuserdisablego示例结果更改登录帐户的属性语法–声明数据库引用use database_name;go –修改登录账户属性alter login login_name withpassword={ ‘password’ | hashed_password hashed [old_password=‘oldpassword’ [must_change | unlock] ]}[,]default_database=database[,] default_language=language[,]name=login_name[,] check_policy={ on | off }[,] check_expiration={ on | off }[,]credential=credential_name[,] no credential[,]add credential credential_name[,] drop credential credential_name 语法解析–database_name–数据库名称–login_name–指定正在更改的SQL Server登录名的名称。 域登录名必须用方括号括起来,其格式为 [domainuser]。–password=‘password*’ –仅适用于SQL Server登录名。指定正在更改的登录名的密码。密码是区分大小写的。–与SQL数据库持续保持活动连接需要至少每隔10小时进行重新授权(由数据库引擎执行)。 –数据库引擎使用最初提交的密码尝试重新授权,且无需用户输入。出于性能原因,在SQL数据库中重置密码时,连接将不会重新进行身份验证,即使该连接因连接池而重置。 –这与本地SQLServer的行为不同。如果自最初授权连接时已更改密码,则必须终止连接,并使用新密码建立新连接。具有KILL DATABASE CONNECTION权限的用户可使用KILL命令,显式终止与SQL数据库的连接。–password=hashed_password–仅适用于HASHED关键字。指定要创建的登录名的密码的哈希值。–hashed–仅适用于SQL Server登录名。 指定在PASSWORD参数后输入的密码已经过哈希运算。 –如果未选择此选项,则在将密码存储到数据库之前,对其进行哈希运算。此选项只能用于在两台服务器之间同步登录名。 切勿使用HASHED选项定期更改密码。–old _password=‘oldpassword’–仅适用于SQL Server登录名。要指派新密码的登录的当前密码。密码是区分大小写的。–must_change –适用范围: SQL Server 2008 到 SQL Server 2017、并行数据仓库。–仅适用于SQL Server 登录名。 如果包括此选项,则SQL Server将在首次使用已更改的登录名时提示输入更新的密码。–unlock–适用范围:SQL Server 2008到SQL Server 2017、并行数据仓库。–仅适用于SQL Server登录名。 指定应解锁被锁定的登录名。–default_database=database–适用范围:SQL Server 2008到SQL Server 2017。–指定将指派给登录名的默认数据库。–default_language=language–适用范围: SQL Server 2008 到 SQL Server 2017。–指定将指派给登录名的默认语言。 所有SQL数据库登录名的默认语言为英语,并且无法更改。 –Linux上SQL Server的sa登录名的默认语言是英语,但可以更改。–name=login_name–正在重命名的登录的新名称。–如果是Windows登录,则与新名称对应的Windows主体的SID必须匹配与SQL Server中的登录相关联的SID。 –SQL Server登录名的新名称不能包含反斜杠字符 ()–check_expiration={ on | off }–适用范围:SQL Server 2008到SQL Server 2017、并行数据仓库。–仅适用于SQL Server登录名。指定是否应对此登录帐户强制实施密码过期策略。默认值为OFF。–check_policy={ on | off }–适用范围:SQL Server 2008到SQL Server 2017、并行数据仓库。–仅适用于SQL Server登录名。指定应对此登录名强制实施运行SQL Server的计算机的Windows密码策略。 默认值为ON。–credential=credential_name–适用范围:SQL Server 2008到SQL Server 2017。–将映射到SQL Server登录的凭据的名称。该凭据必须已存在于服务器中。–有关详细信息,请参阅凭据(数据库引擎)。凭据不能映射到sa登录名。–no credential –适用范围:SQL Server 2008到SQL Server 2017。–删除登录到服务器凭据的当前所有映射。–add credential–适用范围:SQL Server 2008到SQL Server 2017。–将可扩展的密钥管理 (EKM) 提供程序凭据添加到登录名。有关详细信息,请参阅可扩展的密钥管理(EKM)。–drop credentiil–适用范围:SQL Server 2008到SQL Server 2017。–从登录名删除可扩展密钥管理 (EKM) 提供程序凭据。有关详细信息,请参阅可扩展的密钥管理(EKM)。示例–声明数据库引用use testss;go –修改登陆账户属性alter login testuser withpassword=‘1234’,–default_database=database[,] –default_language=language[,]name=testuser, check_policy=on,check_expiration=on–credential=credential_name [,]–no credential[,]–add credential credential_name[,] –drop credential credential_name –可以添加多个服务器角色–创建服务器角色, 服务器角色用于向用户授权服务器范围内的安全特权–alter server role [bulkadmin] drop member [testuser];–go–alter server role [dbcreator] drop member [testuser];–go–alter server role [diskadmin] drop member [testuser];–go–alter server role [processadmin] drop member [testuser];–go–alter server role [securityadmin] drop member [testuser];–go–alter server role [serveradmin] drop member [testuser];–go–alter server role [setupadmin] drop member [testuser];–go–alter server role [sysadmin] drop member [testuser];–go –创建用户映射,映射到此登录名的用户–use [master]–go–drop user [testuser]–go –use [msdb]–go–drop user [testuser]–go –use [ReportServer]–go–drop user [testuser]–go –use [ReportServerTempDB]–go–drop user [testuser]–go –use [tempdb]–go–drop user [testuser]–go –use [testss]–go–drop user [testuser]–go —-声明数据库引用–use [testss]–go —-授予不安全的程序集–grant unsafe assembly to testuser;–go —-授予查看服务器状态–grant view server state to testuser;–go —-授予查看任意定义–grant view any definttion to testuser;–go —-授予查看任意数据库–grant view any database to testuser;–go —-授予创建DDL事件通知–grant create ddl event notification to testuser;–go —-授予创建端点–grant create endpoint to testuser;–go —-授予创建服务器角色–grant create server role to testuser;–go —-授予创建跟踪事件通知–grant create trace event notification to testuser;–go —-授予创建可用性组–grant create availability group to testuser;–go —-授予创建任意数据库–grant create any database to testuser;–go —-授予更改服务器状态–grant alter server state to testuser;–go —-授予更改跟踪–grant alter trace to testuser;–go —-授予更改任何服务器角色–grant alter any server role to testuser;–go —-授予更改任何可用性组–grant alter any availability group to testuser;–go —-授予更改任意登录名–grant alter any login to testuser;–go —-授予更改任意端点–grant alter any endpoint to testuser;–go —-授予更改任意服务器审核–grant alter any server audit to testuser;–go —-授予更改任意权限–grant alter any connection to testuser;–go —-授予更改任意连接服务器–grant alter any linked server to testuser;–go —-授予更改任意凭据–grant alter any credential to testuser;–go —-授予更改任意事件会话–grant alter any event session to testuser;–go —-授予更改任意事件通知–grant alter any event notification to testuser;–go —-授予更改任意数据库–grant alter any database to testuser;–go —-授予更改设置–grant alter settings to testuser;–go —-授予更改资源–grant alter resources to testuser;–go —-授予关闭–grant shutdown to testuser;–go —-授予管理大容量操作–grant administer bulk operations to testuser;–go —-授予控制服务器–grant control server to testuser;–go —-授予连接SQL–grant connect sql to testuser;–go —-授予外部访问程序集–grant external access assembly to testuser;–go —-授予验证服务器–grant authenticate server to testuser;–go –设置是否允许连接到数据库引擎–deny connect sql to testuser;–go –是否允许登录–alter login testuser disable;–go —-用户状态—-声明默认数据库引用–use [testuser]–go—-是否允许用户连接到数据库引擎–deny connect sql to [testuser];–go—-是否允许登录–alter login [testuser] { enable | disable }–go示例结果 ...

January 1, 2019 · 3 min · jiezi

SQLServer之当前数据库中创建新的数据库角色

当前数据库中创建新的数据库角色注意事项角色是数据库级别的安全对象。 在创建角色后,可以使用 grant、deny 和revoke来配置角色的数据库级权限。 若要向数据库角色添加成员,请使用alter role(Transact-SQL)。 在 sys.database_role_members 和 sys.database_principals 目录视图中可以查看数据库角色。有关设计权限系统的信息,请参阅 Getting Started with Database Engine Permissions。要求对数据库具有create role权限或者在 db_securityadmin固定数据库角色中具有成员身份。 使用authorization选项时,还需要具有下列权限:若要将角色的所有权分配给另一个用户,则需要对该用户具有impersonate权限。若要将角色的所有权分配给另一个角色,则需要具有被分配角色的成员身份或对该角色具有alter权限。若要将角色的所有权分配给应用程序角色,则需要对该应用程序角色具有alter权限。使用SSMS数据库管理工具在当前数据库中创建新的数据库角色1、登陆服务器-》在对象资源管理器选择数据库-》展开数据库-》展开安全性-》展开数据库角色-》右键点击数据库角色-》点击新建数据库角色。2、在数据库角色-新建弹出框-》输入角色名称-》点击角色拥有者。3、在选择数据库用户或角色弹出框-》修改对象类型或者不修改-》点击浏览。4、在查找对象-》选择匹配的对象-》点击确定。5、在选择数据库用户或角色弹出框-》点击确定。6、在数据角色-新建-》选择此角色拥有的架构,可多选。7、在数据角色-新建-》选择此角色的成员-》点击添加。8、在选择数据库用户或角色弹出框-》更改对象类型,可使用系统默认-》点击浏览选择对象名称。9、在查找对象弹出框-》选增匹配的对象,可多选-》选择完成以后点击确定。10、在选择数据库用户或角色弹出框-》点击确定。11、在数据库角色-新建-》点击安全对象,选择安全对象并且赋予权限。12、在数据库角色-新建弹出框-》点击搜索选择安全对象。13、在添加对象弹出框-》选择对象(本示例演示特定数据库对象)-》点击确定。14、在选择对象弹出框-》首先选择对象。15、在选择对象类型-》选择对象(本示例演示数据库级别的对象)-》点击确定。16、在选择对象弹出框-》选择浏览。17、在查找对象弹出框-》选择数据库对象-》点击确定。18、在选择对象弹出框-》点击确定。19、在数据库角色-新建-》选择新建角色拥有数据库权限。20、在新建角色-新建弹窗框-》点击扩展属性-》输入新建角色名称和值-》点击确定。21、查看创建结果。使用T-SQL脚本创建新的数据库角色语法:–声明数据库引用use 数据库名;go –创建用新的数据库角色之前判断角色是否已存在,如果已存在则删除。if exists(select * from sys.database_principals where name=role_name)–此角色的成员删除成员use 数据库名goalter role role_name drop member owner_namego –删除角色注释use 数据库名goexec sys.sp_dropextendedproperty @name=扩展属性名称,@level0type=N’user’,@level0name=role_namego –删除此角色drop role role_name; go –当前数据库中创建新的数据库角色create role role_name–角色拥有者authorization owner_name;语法解析:–role_name–待创建角色的名称。–authorization owner_name–将拥有新角色的数据库用户或角色。如果未指定用户,则执行create role的用户将拥有该角色。示例:–声明数据库引用use [testss];go –创建用新的数据库角色之前判断角色是否已存在,如果已存在则删除。if exists(select * from sys.database_principals where name=‘testrole’)–此角色的成员删除成员use [testss]goalter role [testrole] drop member [guest]go –删除角色注释use [testss]goexec sys.sp_dropextendedproperty @name=N’roledescript’,@level0type=N’user’,@level0name=N’testrole’go –删除此角色drop role testrole; go –当前数据库中创建新的数据库角色create role testrole –角色拥有者authorization dbo; –role_name–待创建角色的名称。–authorization owner_name–将拥有新角色的数据库用户或角色。如果未指定用户,则执行create role的用户将拥有该角色。 –创建此角色拥有的架构use [testss]goalter authorization on schema::[db_accessadmin] to testrole;gouse [testss]goalter authorization on schema::[db_accessadmin] to [db_accessadmin]go —-此角色的成员—-添加成员–use [testss]–go–alter role testrole add member [guest];–go –此角色的安全对象use [testss]gogrant backup log to testrole with grant option;go –添加此角色注释use [testss]goexec sys.sp_addextendedproperty @name=N’roledescript’, @value=N’新建测试角色’ , @level0type=N’user’,@level0name=N’testrole’;go示例结果: ...

December 29, 2018 · 1 min · jiezi

浅谈SQL Server内部运行机制

对于已经很熟悉T-SQL的读者,或者对于较专业的DBA来说,逻辑的增删改查,或者较复杂的SQL语句,都是非常简单的,不存在任何挑战,不值得一提,那么,SQL的哪些方面是他们的挑战 或者软肋呢?那就是sql优化。然而,要向成为一个好的Sql优化高手,首先要做的一件事无疑就是了解sql语句在SQL Server中是如何执行的。在这一系列中,我们将开始sqlserver优化系列讲解,本 讲为优化系列的开篇文章,在本篇文章中,我们将重点讲解SQL Server体系结构 在正式讲解之前,我们先来看看如下问题,你是否遇到过,若你遇到过且成功解决,那么这篇文章,你可以跳过。 为了测试需要,我们先模拟插入5亿3千多万条数据。 1 SELECT COUNT(1) FROM BigDataTest(一)查询缓慢问题 *,临时表,表连接,子查询等造成的查询缓慢问题,你能解决吗? (二)内存泄漏 如下查询了8分2秒,然后内存溢出,你知道问题吗? 1 SELECT * FROM BigDataTest(三)经常听说如下概念,你都能解决吗?事务与锁ACID,隔离级别,脏读,分表分库,水平拆分,垂直拆分,高并发等一 SQL Server体系结构抽象二 SQL Server体系结构概述 SQL Server核心体系结构,大致包括六大部分:客户端访问工具、SQL Server 网络接口(SQL Server Network Interface,SNI)、关系引擎、存储引擎、磁盘和缓冲池。下图为SQL Server核心体系大致轮廓图。(一)SQL Server客户端访问工具 SQL Server客户端访问工具,提供了远程访问技术,它与SQL Server服务端基于一定的协议,使其能够远程访问数据库,就像在本地操作数据库一样,如我们经常用的Microsoft SQL Server Management Studio。 SQL Server客户端访问工具是比较多的,其中比较流行的要数Microsoft SQL Server Management Studio 和Navicat(Navicat在MySQL中也是比较常用的)了,至于其他工具,本篇文章就不列举了,感兴趣的读者朋友,可以查询一下。(二)SQL Server网络协议 SQL Server网络协议,又叫SQL Server网络接口(SNI),它是构成客户端和服务端通信的桥梁,它与SQL Server服务端基于一定协议,方可通信,如我们在客户端输入一条查询语句SELECT * FROM BigDataTest,这条语句,只有客户端和服务端基于一定协议,方可被服务端解析,否则,被视为无效语句。 SQL Server网络协议,由一组API构成,这些API供SQL Server数据库引擎和SQL Server本地客户端调用,如实现最基本的CRUD通信。 SQL Server 网络接口(SQL Server Network Interface,SNI)只需要在客户端和服务端配置网络协议即可,它支持一下协议: (1)共享内存 (2)TCP/IP (3)命名管道 (4)VIA(三)关系引擎关系引擎,也叫查询引擎,其主要功能是负责处理SQL语句,其核心组件由三部分组成:命令分析器、查询优化器和查询执行器。(1)命令分析器:负责解析客户端传递过来的T-SQL语句,如客户端传递一条SQL语句:SELECT * FROM BigDataTest,它会检查该语句的语法结构,若语法错误,它会将错误返回给协议层,然后协议层将错误返回给客户端;如果语法结构正确,它会根据查询命令生成查询计划或寻找一个已存在的查询计划(先在缓冲池计划缓存中查找,若找到,则直接给查询执行器执行,若未找到,则会生成基于T-SQL的查询树,然后交给查询优化器优化) (2)查询优化器:负责优化命令解析器生成的T-SQL查询树(基于资源的优化,而非基于时间的优化),然后将最终优化结果传递给查询执行器执行。查询优化器是基于“资源开销”的优化器,这种算法评估多种可执行的查询方式,并从中选择开销最低的方案作为优化结果,然后将该结果生成查询计划输出给查询执行器。注意,查询优化器是“基于资源开销最优”而非“基于方案最优”,也就是,查询优化器的最终优化结果未必是最好的方案,但一定是资源开销最低的方案。 (3)查询执行器:负责执行查询。假若查询执行器接收到命令解析器或查询优化器传递过来的SQL语句:SELECT * FROM BigDataTest,它通过OLE DB接口传递到存储引擎,再传递到存储引擎的访问方法。(四)存储引擎存储引擎,本质就是管理资源存储的,它的核心组件包括三部分:访问方法、事务管理器和缓冲区管理器。 (1)访问方法:访问方法本质是一个接口,供查询执行器调用(该接口提供了所有检索数据的代码,接口的实际执行是由缓冲区管理器来执行的),假若查询执行器传递一条SQL语句:SELECT * FROM BigDataTest,访问方法接收到该请求命令后,就会调用缓冲区管理器,缓冲区管理器就会调用缓冲池的计划缓存,在计划缓存中寻找到相应的结果集,然后返回给关系引擎。 (2)缓冲区管理器:供访问方法调用,管理缓冲池,在缓冲池中查询相应资源并返回结果集,供访问方法返回给关系引擎。 (3)事务管理器:主要负责事务的管理(ACID管理)和高并发管理(锁),它包括两个核心组件(日志管理器和锁管理器),锁管理器负责提供并发数据访问,设置隔离级别等;日志管理器负责记录所有访问方法操作动作,如基本的CRUD。(五)缓冲池缓冲池驻于内存中,是磁盘和缓冲区管理器的桥梁SQL Server中,所有资源的查询都是在内存中进行的,即在缓冲池中进行的,假若缓冲池接收到缓冲区管理器传递过来的的一条SQL语句:SELECT * FROM BigDataTest,缓冲区管理器数据缓存先从磁盘数据库中取满足条件的结果集,然后放在缓冲池数据缓冲中,然后以结果集的形式返回给缓冲区管理器,供访问方法返回给关系引擎的查询执行器,然后返回给协议层,协议层再返回给客户端。注意,这里操作的是缓冲池中数据,而不是磁盘DB中的数据,并且操作的缓冲池数据不会立即写入磁盘,因此就会造成查询到结果与BD中的结果不一致,这就是所谓的脏读。 缓冲池主要包括两部分:计划缓存(生成执行计划是非常耗时耗资源的,计划缓存主要用来存储执行计划,以备后续使用)和数据缓存(通常是缓存池中容量最大的,消耗内存最大,从磁盘中读取的数据页只要放在这里,方可调用)(六)磁盘 磁盘主要是用来存储持久化资源的,如日志资源,数据库资源和缓存池持久化支援等。三 一个查询的完整流程 如下为一个比较完善的查询过程,即第二部分查询语句:SELECT * FROM BigDataTest 整个过程。 ...

December 19, 2018 · 1 min · jiezi

SQLServer创建用户登录

创建用户登录注意事项密码是区分大小写的。只有创建SQL Server登录时,才支持对密码预先进行哈希运算。如果指定MUST_CHANGE,则CHECK_EXPIRATION和 CHECK_POLICY必须设置为 ON。 否则,该语句将失败。不支持CHECK_POLICY=OFF和 CHECK_EXPIRATION=ON的组合。如果CHECK_POLICY设置为OFF,将对lockout_time进行重置,并将CHECK_EXPIRATION设置为OFF。只有在Windows Server 2003及更高版本上才会强制执行CHECK_EXPIRATION 和 CHECK_POLICY。 从证书或非对称密钥创建的登录名仅用于代码签名。不能用于连接到 SQL Server。仅当master中已存在证书或非对称密钥时,才能从证书或非对称密钥创建登录名。有关用于传输登录名的脚本,请参阅如何在 SQL Server 2005 和 SQL Server 2008 的实例之间传输登录名和密码。自动创建登录名将启用新的登录名,并授予它服务器级CONNECT SQL 权限。服务器的身份验证模式必须匹配登录名类型才能允许访问。有关设计权限系统的信息,请参阅 Getting Started with Database Engine Permissions。只有具有针对服务器的ALTER ANY LOGIN权限或securityadmin固定服务器角色的成员身份的用户才可创建登录。如果使用CREDENTIAL选项,则还需要对此服务器的ALTER ANY CREDENTIAL权限。使用SSMS数据库管理工具创建用户登录1、连接数据库-》展开安全性-》选择登录名-》选择新建登录名。2、在登录名-新建弹出框-》点击常规-》输入登录名-》选择sqlserver身份验证-》输入密码-》选择不强制实施密码过期策略-》选择默认数据库-》选择默认语言。3、在登录名-新建弹出框-》点击服务器角色-》选择要向角色授予的安全特权。4、在登录名-新建弹出框-》点击用户映射-》选择用户可以登录的数据库-》选择用户拥有的登录数据库的权限。5、在登录名-新建弹出框-》点击安全对象-》点击搜索添加安全对象-》安全对象添加完成后选择安全对象权限。6、在登录名-新建弹出框-》点击状态-》选择默认即可。7、点击确定-》查看添加结果。使用T-SQL脚本创建用户登录语法–声明数据库引用use testss;go创建用户登录create login login_name with password={ ‘password’ | hashed_password hashed }must_changesid=0x14585E90117152449347750164BA00A7default_database=database_namedefault_language=languagecheck_expiration={ on | off }check_policy={ on | off }[credential=credential_name]语法注释–login_name–指定创建的登录名。有四种类型的登录:SQLServer登录、Windows登录、证书映射登录和非对称密钥映射登录。–在创建从Windows域帐户映射的登录名时,必须以[<domainName><login_name>]格式使用Windows 2000之前的用户登录名。 –不能使用login_name@DomainName格式的UPN。 –有关示例,请参阅本文后面的示例D。身份验证登录的类型为sysname,它必须符合标识符规则,且不能包含“”。 –Windows登录名可以包含“”。Active Directory用户的登录名需少于21个字符。–password=‘password*’ –仅适用于SQL Server登录。指定正在创建的登录名的密码。应使用强密码。 –有关详细信息,请参阅强密码和密码策略。从SQL Server 2012 (11.x)开始,存储的密码信息使用 SHA-512 加盐密码进行计算。–密码是区分大小写的。密码应始终至少包含 8 个字符,并且不能超过128个字符。 –密码可以包含 a-z、A-Z、0-9 和大多数非字母数字字符。 密码不能包含单引号或 login_name。–password=hashed_password–仅适用于hashed关键字。指定要创建的登录名的密码的哈希值。–hashed仅适用于SQL Server登录。指定在password参数后输入的密码已经过哈希运算。 –如果未选择此选项,则在将作为密码输入的字符串存储到数据库中之前,对其进行哈希运算。 –此选项应仅用于在服务器之间迁移数据库。切勿使用hashed选项创建新的登录名。hashed选项不能用于SQL 7或更早版本创建的哈希。–must_change –仅适用于SQL Server登录。如果包括此选项,则SQL Server将在首次使用新登录时提示用户输入新密码。–sid=sid–用于重新创建登录名。仅适用于SQL Server身份验证登录,不适用于Windows身份验证登录。指定新SQL Server身份验证登录的sid。–如果未使用此选项,SQL Server将自动分配sid。sid结构取决于SQL Server版本。 QL Server登录sid:基于GUID的16 字节(binary(16))文本值。 例如,sid 0x14585E90117152449347750164BA00A7。–default_database=database–指定将指派给登录名的默认数据库。如果未包括此选项,则默认数据库将设置为master。–default_language=language–指定将指派给登录名的默认语言。如果未包括此选项,则默认语言将设置为服务器的当前默认语言。即使将来服务器的默认语言发生更改,登录名的默认语言也仍保持不变。–check_expiration={ on | off }–仅适用于SQL Server登录。 指定是否应对此登录帐户强制实施密码过期策略。 默认值为off。–check_policy={ on | off }–仅适用于SQL Server登录。 指定应对此登录强制实施运行SQL Server 计算机的 Windows 密码策略。 默认值为on。–如果 Windows 策略要求强密码,密码必须至少包含以下四个特点中的三个:–大写字符 (A-Z)。–小写字符 (a-z)。–数字 (0-9)。–一个非字母数字字符,如空格、、@、*、^、%、!、$、# 或 &。–credential=credential_name–将映射到新SQL Server登录的凭据名称。 该凭据必须已存在于服务器中。当前此选项只将凭据链接到登录名。凭据不能映射到系统管理员(sa)登录名。示例–声明数据库引用use testss;go–创建登录用户create login testuserwith password=‘123456’,–must_change,–sid=0x14585E90117152449347750164BA00A7,default_database=master,–default_language=language,check_expiration=off,check_policy=off–credential=[sysadmin]go–可以添加多个服务器角色–创建服务器角色, 服务器角色用于向用户授权服务器范围内的安全特权–alter server role [bulkadmin] add member testuser;–go–alter server role [dbcreator] add member testuser;–go–alter server role [diskadmin] add member testuser;–go–alter server role [processadmin] add member testuser;–go–alter server role [securityadmin] add member testuser;–go–alter server role [serveradmin] add member testuser;–go–alter server role [setupadmin] add member testuser;–goalter server role [sysadmin] add member testuser;go–创建用户映射,映射到此登录名的用户use [model]gocreate user testuser for login testuser;go–use [msdb]–go–create user testuser for login testuser;–go–use [ReportServer]–go–create user testuser for login testuser;–go–use [ReportServerTempDB]–go–create user testuser for login testuser;–go–use [tempdb]–go–create user testuser for login testuser;–gouse [testss]gocreate user testuser for login testuser;go—-创建用户登录数据库–use [master]–go–create user [testuser] for login [testuser];–go—-创建用户登录多个数据库–use [testss]–go –create user [testuser] for login [testuser];–go—-声明数据库应用–use [testss]–go—-授予不安全的程序集–grant unsafe assembly to testuser;–go—-授予查看服务器状态–grant view server state to testuser;–go—-授予查看任意定义–grant view any definttion to testuser;–go—-授予查看任意数据库–grant view any database to testuser;–go—-授予创建DDL事件通知–grant create ddl event notification to testuser;–go—-授予创建端点–grant create endpoint to testuser;–go—-授予创建服务器角色–grant create server role to testuser;–go—-授予创建跟踪事件通知–grant create trace event notification to testuser;–go—-授予创建可用性组–grant create availability group to testuser;–go—-授予创建任意数据库–grant create any database to testuser;–go—-授予更改服务器状态–grant alter server state to testuser;–go—-授予更改跟踪–grant alter trace to testuser;–go—-授予更改任何服务器角色–grant alter any server role to testuser;–go—-授予更改任何可用性组–grant alter any availability group to testuser;–go—-授予更改任意登录名–grant alter any login to testuser;–go—-授予更改任意端点–grant alter any endpoint to testuser;–go—-授予更改任意服务器审核–grant alter any server audit to testuser;–go—-授予更改任意权限–grant alter any connection to testuser;–go—-授予更改任意连接服务器–grant alter any linked server to testuser;–go—-授予更改任意凭据–grant alter any credential to testuser;–go—-授予更改任意事件会话–grant alter any event session to testuser;–go—-授予更改任意事件通知–grant alter any event notification to testuser;–go—-授予更改任意数据库–grant alter any database to testuser;–go—-授予更改设置–grant alter settings to testuser;–go—-授予更改资源–grant alter resources to testuser;–go—-授予关闭–grant shutdown to testuser;–go—-授予管理大容量操作–grant administer bulk operations to testuser;–go—-授予控制服务器–grant control server to testuser;–go—-授予连接SQL–grant connect sql to testuser;–go—-授予外部访问程序集–grant external access assembly to testuser;–go—-授予验证服务器–grant authenticate server to testuser;–go–设置是否允许连接到数据库引擎–deny connect sql to testuser;–go –是否允许登录–alter login testuser disable;–go—-用户状态—-声明默认数据库引用–use [testuser]–go—-是否允许用户连接到数据库引擎–deny connect sql to [testuser];–go—-是否允许登录–alter login [testuser] disable–go示例结果使用新创建的用户名登录1、在对象资源管理器中-》点击新建连接。2、在连接到服务器弹出框-》选择sqlserver身份验证-》输入用户名和密码-》点击连接。3、查看结果。 ...

December 19, 2018 · 2 min · jiezi

SQLServer之创建Transact-SQL游标

什么是游标结果集,结果集就是select查询之后返回的所有行数据的集合。游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据。一般复杂的存储过程,都会有游标的出现,他的用处主要有:定位到结果集中的某一行。对当前位置的数据进行读写。可以对结果集中的数据单独操作,而不是整行执行相同的操作。是面向集合的数据库管理系统和面向行的程序设计之间的桥梁。游标使用三步曲:第一步创建游标,第二步打开游标,第三步使用游标。游标的使用范围是当前会话。游标使用第一步创建游标语法–声明数据库引用use testss;go–第二种Transact-SQL扩展语法–Transact-SQL Extended Syntax declare cursor_name cursor [ local | global ] [ forward_only | scroll ] [ static | keyset | dynamic | fast_forward ] [ read_only | scroll_locks | optimistic ] [ type_warning ] for select_statement [ for update [ of column_name [ ,…n ] ] ] [;]语法注释–cursor_name–Transact-SQL服务器游标定义的名称。 cursor_name必须符合有关标识符的规则。–local–指定该游标的范围对在其中创建它的批处理、存储过程或触发器是局部的。 –该游标名称仅在这个作用域内有效。在批处理、存储过程、触发器或存储过程output参数中,该游标可由局部游标变量引用。–output参数用于将局部游标传递回调用批处理、存储过程或触发器,它们可在存储过程终止后给游标变量分配参数使其引用游标。–除非output参数将游标传递回来,否则游标将在批处理、存储过程或触发器终止时隐式释放。如果output参数将游标传递回来,则游标在最后引用它的变量释放或离开作用域时释放。–global–指定该游标范围对连接是全局的。在由此连接执行的任何存储过程或批处理中,都可以引用该游标名称。 –该游标仅在断开连接时隐式释放。–备注–如果global和local参数都未指定,则默认值由“默认为本地游标”数据库选项的设置控制。–forward_only–指定游标只能从第一行滚动到最后一行。fetch next是唯一支持的提取选项。–如果指定了forward_only而没有指定static、keyset和dynamic关键字,则游标作为dynamic游标进行操作。 –如果未指定forward_only和scroll,则默认为forward_only,–除非指定了关键字static、keyset或dynamic。static、keyset和dynamic游标默认为scroll。 –与odbc和ado等数据库API不同,static、keyset和dynamic Transact-SQL游标支持forward_only。–scroll–指定所有的提取选项(first、last、prior、next、relative和absolute)均可用。 如果未在iso declare cursor中指定scroll,则next是唯一支持的提取选项。 –如果还指定了fast_forward,则无法指定scroll。–static–定义一个游标,以创建将由该游标使用的数据的临时副本。对游标的所有请求都从tempdb中的这一临时表中得到应答;–因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。–keyset–指定当游标打开时,游标中行的成员身份和顺序已经固定。对行进行唯一标识的键集内置在tempdb内一个称为keyset的表中。–备注–如果查询引用了至少一个无唯一索引的表,则键集游标将转换为静态游标。–对基表中的非键值所做的更改(由游标所有者更改或由其他用户提交)可以在用户滚动游标时看到。 –其他用户执行的插入是不可见的(不能通过Transact-SQL服务器游标执行插入)。如果删除某一行,则在尝试提取该行时返回的@@fetch_status为-2。–从游标外部更新键值类似于删除旧行后再插入新行。具有新值的行不可见,且尝试提取具有旧值的行时返回的@@fetch_status为 -2。 –如果通过指定where current of子句来通过游标执行更新,则新值可见。–dynamic–定义一个游标,以反映在滚动游标时对结果集内的各行所做的所有数据更改。 –行的数据值、顺序和成员身份在每次提取时都会更改。动态游标不支持absolute提取选项。–fast_forward–指定已启用了性能优化的fast_forward和read_only游标。如果还指定了scroll或for_update,则无法指定fast_forward。–备注–可以在相同的declare cursor语句中使用fast_forward和forward_only。–read_only–禁止通过该游标进行更新。无法在update或delete语句的where current of子句中引用游标。 –该选项优先于要更新的游标的默认功能。–scroll_locks–指定通过游标进行的定位更新或删除一定会成功。将行读入游标时SQLServer将锁定这些行,以确保随后可对它们进行修改。 –如果还指定了fast_forward或static,则无法指定scroll_locks。–optimistic–指定如果行自读入游标以来已得到更新,则通过游标进行的定位更新或定位删除不成功。 –当将行读入游标时,SQLServer不锁定行。 –相反,它使用timestamp列值的比较,或者如果表没有timestamp列则使用校验和值,以确定将行读入游标后是否已修改该行。–如果已修改该行,尝试进行的定位更新或定位删除将失败。如果还指定了fast_forward,则无法指定optimistic。–type_warning–指定如果游标从所请求的类型隐式转换为另一种类型,则向客户端发送警告消息。–select_statement–定义游标结果集的标准select语句。在游标声明的select_statement中不允许使用关键字compute、compute by、for browse和into。–备注–可以在游标声明中使用查询提示;但如果还使用for update of子句,请在for update of之后指定option(<query_hint>)。–如果select_statement中的子句与所请求的游标类型的功能有冲突,则SQLServer会将游标隐式转换为其他类型。有关详细信息,请参阅“隐式游标转换”。–for update [of column_name [,…n]]–定义游标中可更新的列。 如果提供了of <column_name> [, <… n>],则只允许修改所列出的列。 如果指定了update,但未指定列的列表,则除非指定了read_only并发选项,否则可以更新所有的列。示例declare firstcursor cursorscrollstaticread_onlytype_warningforselect id,name from test1–for update;示例结果第二步打开游标语法open { { [ global ] cursor_name } | cursor_variable_name }语法解析–global–指定cursor_name是指全局游标。–cursor_name–已声明的游标的名称。当同时存在以cursor_name作为名称的全局游标和局部游标时,如果指定global,则cursor_name是指全局游标;否则,cursor_name是指局部游标。–cursor_variable_name–游标变量的名称,该变量引用一个游标。示例open firstcursor;示例结果第三步使用游标语法fetch [ [ next | prior | first | last | absolute { n | @nvar } | relative { n | @nvar } ] from ] { { [ global ] cursor_name } | @cursor_variable_name } [ into @variable_name [ ,…n ] ]语法注释–next–紧跟当前行返回结果行,并且当前行递增为返回行。如果fetch next为对游标的第一次提取操作,则返回结果集中的第一行。next为默认的游标提取选项。–prior–返回紧邻当前行前面的结果行,并且当前行递减为返回行。如果fetch prior为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。–first–返回游标中的第一行并将其作为当前行。–last–返回游标中的最后一行并将其作为当前行。–absolute { n| @nvar}–如果 n 或 @nvar 为正,则返回从游标起始处开始向后的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为负,则返回从游标末尾处开始向前的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为 0,则不返回行。 n 必须是整数常量,并且 @nvar 必须是 smallint、tinyint 或 int。–relative { n| @nvar}–如果 n 或 @nvar 为正,则返回从当前行开始向后的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为负,则返回从当前行开始向前的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为 0,则返回当前行。 在对游标进行第一次提取时,–如果在将 n 或 @nvar 设置为负数或 0 的情况下指定fetch relative,则不返回行。 n 必须是整数常量,并且 @nvar 必须是 smallint、tinyint 或 int。–global–指定 cursor_name 是指全局游标。–cursor_name–要从中进行提取的开放游标的名称。 当同时存在以 cursor_name 作为名称的全局游标和局部游标时,–如果指定global,则 cursor_name 指全局游标,如果未指定 global,则指局部游标。–@cursor_variable_name–游标变量名,引用要从中进行提取操作的打开的游标。–into @variable_name[ ,…n]–允许将提取操作的列数据放到局部变量中。 列表中的各个变量从左到右与游标结果集中的相应列相关联。 –各变量的数据类型必须与相应的结果集列的数据类型匹配,或是结果集列数据类型所支持的隐式转换。 变量的数目必须与游标选择列表中的列数一致。示例declare @id nvarchar(50),@name nvarchar(50);fetch first from firstcursor into @id,@name;select @id,@name;示例结果 ...

December 18, 2018 · 2 min · jiezi

Spring Boot 集成 MyBatis和 SQL Server实践

文章共 509字,阅读大约需要 2分钟 !概 述Spring Boot工程集成 MyBatis来实现 MySQL访问的示例我们见过很多,而最近用到了微软的 SQL Server数据库,于是本文则给出一个完整的 Spring Boot + MyBatis + SQL Server 的工程示例。注: 本文首发于 My Personal Blog:CodeSheep·程序羊,欢迎光临 小站工程搭建新建 Spring Boot工程pom.xml 中添加 MyBatis和 SQL Server相关的依赖<!–for mybatis–><dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version></dependency><!–for SqlServer–><dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>sqljdbc4</artifactId> <version>4.0</version></dependency>配置 application.properties这里同样主要是对于 MyBatis 和 SQL Server连接相关的配置server.port=89# mybatis 配置mybatis.type-aliases-package=cn.codesheep.springbt_mybatis_sqlserver.entitymybatis.mapper-locations=classpath:mapper/*.xmlmybatis.configuration.map-underscore-to-camel-case=true## ————————————————-## SqlServer 配置spring.datasource.url=jdbc:sqlserver://xxxx:1433;databasename=MingLispring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriverspring.datasource.username=xxxxspring.datasource.password=xxxx建立 SQL Server数据表和实体类首先在 SQL Server数据库中新建数据表 user_test作为测试用表DROP TABLE [demo].[user_test]GOCREATE TABLE [dbo].[user_test] ([user_id] int NOT NULL ,[user_name] varchar(50) NOT NULL ,[sex] tinyint NOT NULL ,[created_time] varchar(50) NOT NULL )GO然后在我们的工程中对应建立的 User实体类其字段和实际数据表的字段一一对应public class User { private Long userId; private String userName; private Boolean sex; private String createdTime; public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public Boolean getSex() { return sex; } public void setSex(Boolean sex) { this.sex = sex; } public String getCreatedTime() { return createdTime; } public void setCreatedTime(String createdTime) { this.createdTime = createdTime; }}Mybatis Mapper映射配置MyBatis映射配置的 XML文件如下:<?xml version=“1.0” encoding=“UTF-8” ?><!DOCTYPE mapper PUBLIC “-//mybatis.org//DTD Mapper 3.0//EN” “http://mybatis.org/dtd/mybatis-3-mapper.dtd" ><mapper namespace=“cn.codesheep.springbt_mybatis_sqlserver.mapper.UserMapper”> <resultMap id=“userMap” type=“cn.codesheep.springbt_mybatis_sqlserver.entity.User”> <id property=“userId” column=“user_id” javaType=“java.lang.Long”></id> <result property=“userName” column=“user_name” javaType=“java.lang.String”></result> <result property=“sex” column=“sex” javaType=“java.lang.Boolean”></result> <result property=“createdTime” column=“created_time” javaType=“java.lang.String”></result> </resultMap> <select id=“getAllUsers” resultMap=“userMap”> select * from user_test </select> <insert id=“addUser” parameterType=“cn.codesheep.springbt_mybatis_sqlserver.entity.User”> insert into user_test ( user_id, user_name, sex, created_time ) values ( #{userId}, #{userName}, #{sex}, #{createdTime} ) </insert> <delete id=“deleteUser” parameterType=“cn.codesheep.springbt_mybatis_sqlserver.entity.User”> delete from user_test where user_name = #{userName} </delete></mapper>与此同时,这里也给出对应 XML的 DAO接口public interface UserMapper { List<User> getAllUsers(); int addUser( User user ); int deleteUser( User user );}为了试验起见,这里给出了 增 / 删 / 查 三个数据库操作动作。编写 Service 和测试Controller上面这些准备工作完成之后,接下来编写数据库 CRUD的 Service类@Service@Primarypublic class UserServiceImpl implements IUserService { @Autowired private UserMapper userMapper; @Override public List<User> getAllUsers() { return userMapper.getAllUsers(); } @Override public int addUser(User user) { SimpleDateFormat form = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”); user.setCreatedTime( form.format(new Date()) ); return userMapper.addUser( user ); } @Override public int deleteUser(User user) { return userMapper.deleteUser( user ); }}这里的 Service功能同样主要关于数据表的 增 / 删 / 查 三个数据库操作动作。对照着上面的Service,我们编写一个对应接口测试的Controller@RestControllerpublic class UserController { @Autowired private IUserService userService; @RequestMapping(value = “/getAllUser”, method = RequestMethod.GET) public List<User> getAllUser() { return userService.getAllUsers(); } @RequestMapping(value = “/addUser”, method = RequestMethod.POST) public int addUser( @RequestBody User user ) { return userService.addUser( user ); } @RequestMapping(value = “/deleteUser”, method = RequestMethod.POST) public int deleteUser( @RequestBody User user ) { return userService.deleteUser( user ); }}实验测试插入数据依次用 POSTMAN通过 Post /addUser接口插入三条数据:{“userId”:1,“userName”:“刘能”,“sex”:true}{“userId”:2,“userName”:“赵四”,“sex”:false}{“userId”:3,“userName”:“王大拿”,“sex”:true}插入完成后去 SQL Server数据库里看一下数据插入情况如下:查询数据调用 Get /getAllUser接口,获取刚插入的几条数据删除数据调用 Post /deleteUser 接口,可以通过用户名来删除对应的用户后 记由于能力有限,若有错误或者不当之处,还请大家批评指正,一起学习交流!My Personal Blog:CodeSheep 程序羊我的半年技术博客之路 ...

December 18, 2018 · 2 min · jiezi

SQLServer之ISO游标使用

什么是游标结果集,结果集就是select查询之后返回的所有行数据的集合。游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据。一般复杂的存储过程,都会有游标的出现,他的用处主要有:定位到结果集中的某一行。对当前位置的数据进行读写。可以对结果集中的数据单独操作,而不是整行执行相同的操作。是面向集合的数据库管理系统和面向行的程序设计之间的桥梁。游标使用三步曲:第一步创建游标,第二步打开游标,第三步使用游标。游标使用第一步创建游标语法–声明数据库引用use 数据库名;go–创建游标declare cursor_name [insensitive] [scroll] cursorfor select_statement[for { read only | update [of column_name [,……n] ] } ];语法注释–cursor_name–Transact-SQL服务器游标定义的名称。cursor_name必须符合有关标识符的规则。–insensitive–定义一个游标,以创建将由该游标使用的数据的临时副本。对游标的所有请求都从tempdb中的这一临时表中得到应答;–因此,在对该游标进行提取操作时返回的数据中不反映对基表所做的修改,并且该游标不允许修改。 –使用ISO语法时,如果省略insensitive,则已提交的(任何用户)对基础表的删除和更新则会反映在后面的提取操作中。–scroll–指定所有的提取选项(first、last、prior、next、relative和absolute)均可用。 如果未在iso declare cursor中指定scroll,则next是唯一支持的提取选项。 –如果还指定了fast_forward,则无法指定scroll。–select_statement–是定义游标结果集的标准select语句。在游标声明的select_statement中不允许使用关键字for browse和into。–如果select_statement中的子句与所请求的游标类型的功能有冲突,则SQLServer会将游标隐式转换为其他类型。–read only–禁止通过该游标进行更新。无法在update或delete语句的where current of子句中引用游标。该选项优先于要更新的游标的默认功能。–update [of column_name [,…n]]–定义游标中可更新的列。如果指定了of <column_name> [, <… n>],则只允许修改所列出的列。 如果指定了update,但未指定列的列表,则可以更新所有列。示例–声明数据库引用use testss;go–第一种ISO语法–游标使用三步曲–第一步声明游标declare synae_cursor_name insensitive scroll cursorfor select id,name from test1for read only;示例结果第二步打开游标语法open { { [ global ] cursor_name } | cursor_variable_name }语法解析–global–指定cursor_name是指全局游标。–cursor_name–已声明的游标的名称。当同时存在以cursor_name作为名称的全局游标和局部游标时,如果指定global,则cursor_name是指全局游标;否则,cursor_name是指局部游标。–cursor_variable_name–游标变量的名称,该变量引用一个游标。示例open global synae_cursor_name;示例结果第三步使用游标语法fetch [ [ next | prior | first | last | absolute { n | @nvar } | relative { n | @nvar } ] from ] { { [ global ] cursor_name } | @cursor_variable_name } [ into @variable_name [ ,…n ] ]语法注释–next–紧跟当前行返回结果行,并且当前行递增为返回行。如果fetch next为对游标的第一次提取操作,则返回结果集中的第一行。next为默认的游标提取选项。–prior–返回紧邻当前行前面的结果行,并且当前行递减为返回行。如果fetch prior为对游标的第一次提取操作,则没有行返回并且游标置于第一行之前。–first–返回游标中的第一行并将其作为当前行。–last–返回游标中的最后一行并将其作为当前行。–absolute { n| @nvar}–如果 n 或 @nvar 为正,则返回从游标起始处开始向后的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为负,则返回从游标末尾处开始向前的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为 0,则不返回行。 n 必须是整数常量,并且 @nvar 必须是 smallint、tinyint 或 int。–relative { n| @nvar}–如果 n 或 @nvar 为正,则返回从当前行开始向后的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为负,则返回从当前行开始向前的第 n 行,并将返回行变成新的当前行。 –如果 n 或 @nvar 为 0,则返回当前行。 在对游标进行第一次提取时,–如果在将 n 或 @nvar 设置为负数或 0 的情况下指定fetch relative,则不返回行。 n 必须是整数常量,并且 @nvar 必须是 smallint、tinyint 或 int。–global–指定 cursor_name 是指全局游标。–cursor_name–要从中进行提取的开放游标的名称。 当同时存在以 cursor_name 作为名称的全局游标和局部游标时,–如果指定global,则 cursor_name 指全局游标,如果未指定 global,则指局部游标。–@cursor_variable_name–游标变量名,引用要从中进行提取操作的打开的游标。–into @variable_name[ ,…n]–允许将提取操作的列数据放到局部变量中。 列表中的各个变量从左到右与游标结果集中的相应列相关联。 –各变量的数据类型必须与相应的结果集列的数据类型匹配,或是结果集列数据类型所支持的隐式转换。 变量的数目必须与游标选择列表中的列数一致。示例declare @id nvarchar(50),@name nvarchar(50);fetch last from synae_cursor_name into @id,@name;select @id,@name;示例结果游标使用扩展查看游标语法exec sp_cursor_list [ @cursor_return = ] cursor_variable_name output, [ @cursor_scope = ] cursor_scope [;]语法解析–[@cursor_return=] cursor_variable_name 输出–已声明的游标变量的名称。 cursor_variable_name是光标,无默认值。 游标是可滚动、 动态、 只读游标。–[ @cursor_scope=] cursor_scope–指定要报告的游标级别。 cursor_scope是int,无默认值,并且可以是下列值之一。–@cursor_scope=1(local)(报告所有本地游标)–@cursor_scope=2(global)(报告所有全局游标) –@cursor_scope=3(global和local)(报告本地游标和全局游标)示例declare @result cursorexec sp_cursor_list @cursor_return=@result output,@cursor_scope=2;fetch next from @result;示例结果关闭游标语法close { { [ global ] cursor_name } | cursor_variable_name }语法解析–global–指定cursor_name是指全局游标。–cursor_name–打开的游标的名称。 当同时存在以cursor_name作为名称的全局游标和局部游标时,如果指定global,则cursor_name 是指全局游标;否则,cursor_name 是指局部游标。–cursor_variable_name–与打开的游标关联的游标变量的名称。示例close global synae_cursor_name;示例结果删除游标语法deallocate { { [ global ] cursor_name } | @cursor_variable_name }语法解析–cursor_name–已声明游标的名称。 当同时存在以 cursor_name 作为名称的全局游标和局部游标时,如果指定 GLOBAL,则 cursor_name 指全局游标,如果未指定 GLOBAL,则指局部游标。–@cursor_variable_name–cursor 变量的名称。 @cursor_variable_name必须为cursor类型。示例deallocate global synae_cursor_name;示例结果 ...

December 17, 2018 · 2 min · jiezi