• [技术干货] Sql Server 数据库索引整理语句,自动整理数据库索引
    在一个大型数据库中,数据的更改是非常频繁的。而建立在这些数据上的索引也是需要经常去维护的。否则这这些数据索引就起不到起应起的作用。甚至会成为数据库本身的负担。我们就要定期的对数据库的索引进行维护 我在MSDN上发现了这个脚本不过其中有些小问题我已经修正 大家可以使用这个脚本对数据库的索引进行日常维护SET NOCOUNT ON;  DECLARE @objectid int;  DECLARE @indexid int;  DECLARE @partitioncount bigint;  DECLARE @schemaname sysname;  DECLARE @objectname sysname;  DECLARE @indexname sysname;  DECLARE @partitionnum bigint;  DECLARE @partitions bigint;  DECLARE @frag float;  DECLARE @command varchar(8000);  DECLARE @dbId int;  -- ensure the temporary table does not exist  IF EXISTS (SELECT name FROM sys.objects WHERE name = 'work_to_do')  DROP TABLE work_to_do;  -- conditionally select from the function, converting object and index IDs to names.  set @dbId=DB_ID();  SELECT  object_id AS objectid,  index_id AS indexid,  partition_number AS partitionnum,  avg_fragmentation_in_percent AS frag  INTO work_to_do FROM sys.dm_db_index_physical_stats (@dbId, NULL, NULL , NULL, 'LIMITED')  WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;  -- Declare the cursor for the list of partitions to be processed.  DECLARE partitions CURSOR FOR SELECT * FROM work_to_do;  -- Open the cursor.  OPEN partitions;  -- Loop through the partitions.  FETCH NEXT  FROM partitions  INTO @objectid, @indexid, @partitionnum, @frag;  WHILE @@FETCH_STATUS = 0  BEGIN;  SELECT @objectname = o.name, @schemaname = s.name  FROM sys.objects AS o  JOIN sys.schemas as s ON s.schema_id = o.schema_id  WHERE o.object_id = @objectid;  SELECT @indexname = name  FROM sys.indexes  WHERE object_id = @objectid AND index_id = @indexid;  SELECT @partitioncount = count (*)  FROM sys.partitions  WHERE object_id = @objectid AND index_id = @indexid;  -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding  IF @frag < 30.0  BEGIN;  SELECT @command = 'ALTER INDEX [' + @indexname + '] ON ' + @schemaname + '.[' + @objectname + '] REORGANIZE';  IF @partitioncount > 1  SELECT @command = @command + ' PARTITION=' + CONVERT (CHAR, @partitionnum);  EXEC (@command);  END;  IF @frag >= 30.0  BEGIN;  SELECT @command = 'ALTER INDEX [' + @indexname +'] ON ' + @schemaname + '.[' + @objectname + '] REBUILD';  IF @partitioncount > 1  SELECT @command = @command + ' PARTITION=' + CONVERT (CHAR, @partitionnum);  EXEC (@command);  END;  PRINT 'Executed ' + @command;  FETCH NEXT FROM partitions INTO @objectid, @indexid, @partitionnum, @frag;  END;  -- Close and deallocate the cursor.  CLOSE partitions;  DEALLOCATE partitions;  -- drop the temporary table  IF EXISTS (SELECT name FROM sys.objects WHERE name = 'work_to_do')  DROP TABLE work_to_do;  GO这个脚本在运行时 会建立一个表 work_to_do 整理完毕后会自动删除这个表。如果不喜欢的话的可以用一个临时的表解决。
  • [技术干货] SQL Server如何通过创建临时表遍历更新数据详解
    前言:前段时间新项目上线为了赶进度很多模块的功能都没有经过详细的测试导致了生成环境中的数据和实际数据对不上,因此需要自己手写一个数据库脚本来更新下之前的数据。(线上数据库用是SQL Server2012)关于数据统计汇总的问题肯定会用到遍历统计汇总,那么问题来了数据库中如何遍历呢?好像并没有for和foreach这种类型的功能呀,不过关于数据库遍历最常见的方法当然是大家经常会想到的游标啦,但是这次我并没有使用游标,而是通过创建临时表的方式来更新遍历数据的。为什么不使用游标,而使用创建临时表?首先使用游标的方式遍历数据可能代码上比较直观,但是代码比较繁琐(声明游标,打开游标,使用游标,关闭游标和释放游标)并且不符合操作集合的原则,而且也非常的耗费性能,因此通常数据量比较大的情况下不推荐使用游标。通过临时表while遍历数据,更符合我们日常的编程思想操作集合原则,性能上虽不敢保证表使用游标要好多少,但是在把临时表使用恰当的前提是能减少大量的性能消耗,并且使用起来非常简单易懂。通过创建临时表遍历更新数据:注意:这里只是一个简单的临时表更新实例。我的目的是把TalkingSkillType表中的Sort值更新成为与Id一样的值!未更新前的数据如下图所示:临时表遍历更新SQL语句:----SQL SERVER通过临时表遍历数据 -- 判断是否存在(object(‘objectname',‘type')) IF OBJECT_ID('tempdb.dbo.#temp','U') IS NOT NULL DROP TABLE dbo.#temp;   GO -- 声明变量  DECLARE  @ID AS INT,  @Name AS VARCHAR(50),  @Num AS INT   --数据插入临时表(select * INTO #Temp from 来源表) SELECT ID,Name INTO #temp FROM TalkingSkillType   --查询临时表中数据 --SELECT * FROM #temp    set @Num=0 --赋初始值   --查询是否存在记录,只要存在会一直循环直到不存在(WHILE EXISTS) WHILE EXISTS(SELECT ID FROM #temp)  BEGIN       set @Num= @Num + 1          -- 取值(把临时表中的值赋值给定义的变量)    SELECT top 1 @ID= ID,@Name=Name FROM #temp;       -- 输出操作(用于查看执行效果)    PRINT(@Num)        --更新    UPDATE TalkingSkillType SET Sort=@ID where id=@ID       -- 删除本次操临时表中的数据(避免无限循环)    DELETE FROM #temp WHERE ID=@ID;  END   --删除临时表 #temp --drop table #tempPRINT(@Num)输入日志:遍历更新成功后结果如下图所示:
  • [技术干货] 华为云RDS-SQLserver主备集群定时作业手动同步实践指导
    【背景】 SQLserver原生产品不支持主备之间作业自动同步,主备集群架构下备节点需手动配置作业,避免主节点故障或者降备,备节点升主后集群作业不生效。影响数据同步或者数据迁移。以下操作指导介绍如何在华为云上通过DAS登录备节点同步主节点作业。【试验环境】【环境配置】1.   通过以下SQL脚本,创建timedtask数据库、taskinfo表、初始化表数据--创建数据库CREATE DATABASE timedtask;--创建表USE [timedtask];CREATE TABLE [dbo].[taskinfo] (        [ID] int NOT NULL,        [taskname] varchar(50) NULL,        [begintime] datetime DEFAULT GETDATE() NULL,        [endtime] datetime DEFAULT GETDATE() NULL,        PRIMARY KEY CLUSTERED ([ID]));--插入数据insert into [taskinfo] ([ID],[taskname],[begintime],[endtime]) values ('1','taskinfo-table-back','2020-10-09 14:21:07.417','2020-10-09 14:21:07.417');insert into [taskinfo] ([ID],[taskname],[begintime],[endtime]) values ('2','taskinfo-table-back','2020-10-08 14:22:04.000','2020-10-08 14:22:04.000');insert into [taskinfo] ([ID],[taskname],[begintime],[endtime]) values ('3','taskinfo-table-back','2020-10-07 14:23:17.000','2020-10-07 14:23:17.000');insert into [taskinfo] ([ID],[taskname],[begintime],[endtime]) values ('4','taskinfo-table-back','2020-10-06 14:22:23.173','2020-10-06 14:22:23.173'); 2.  下载安装SQL Server Management Studio数据库客户端https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-20173.   准备作业执行SQL脚本DECLARE @UNIXTIME varchar(255),        @TABLES_NAME varchar(255),        @str_sql nvarchar(MAX);SET @UNIXTIME =cast (DATEDIFF(SS,'1970-1-1 00:00:00',GETUTCDATE()) as varchar(255));SET @TABLES_NAME='taskinfo_bak_'+ @UNIXTIME;SET @str_sql='select * into ' + @TABLES_NAME  +  ' from taskinfo' ;EXEC sp_executesql @str_sql;【操作步骤】1.   使用SSMS客户端登录数据库(主节点)2.   创建作业“备份taskinfo表”,并每周日凌晨0点执行作业(主节点)。3.   将新建的作业“备份taskinfo表”导出为SQL脚本用于同步作业到备节点 ,右击鼠标选择编辑作业脚本为-CREATE到-新查询编辑器窗口,如下图所示。4.   登录备节点:使用DAS工具登录数据库,点击“SQL操作-SQL窗口”,点击“主库 切换SQL执行点”,如下图所示5.   确认登录到备库后,然后在SQL查询窗口执行,从“步骤三拷贝的SQL脚本”,并确认执行成功。注意:一般数据库作业都是大批量事务,建议在业务低峰期执行,避免在高峰期执行影响数据库的性能。
  • [技术干货] Sql Server 数据库中调用dll文件的过程
    1.首先新建一个空的解决方案,并添加一个类库,代码如下,编译并生产dllusing System;  using System.Collections.Generic;  using System.Data.SqlTypes;  using System.Linq;  using System.Text;  namespace TEST  {    public class TestTrans    {      [Microsoft.SqlServer.Server.SqlFunction]      public static SqlString GenerateDecryptString(string name)      {        string decode = string.Empty;        decode = string.Format("HELLO WORLD {0}!", name);//DecryptString(dataXML.Value);        SqlString sqlValue = new SqlString(decode);        return sqlValue;      }    }  }2.启用CLR功能默认情况下,SQL Server中的CLR是关闭的,所以我们需要执行如下命令打开CLR:exec sp_configure 'clr enabled',1   reconfigure    Go3.将程序集引用到数据库中CREATE ASSEMBLY testHelloWorld FROM 'C:\TEST.dll'   --('C:/TEST.dll'w为错误写法)4.创建函数CREATE FUNCTION dbo.clrHelloWorld    (      @name as nvarchar(200)    )    RETURNS nvarchar(200)    AS EXTERNAL NAME testHelloWorld.[TEST.TestTrans].GenerateDecryptString5.调用函数SELECT dbo.clrHelloWorld('耿耿')6.执行结果HELLO WORLD  耿耿!
  • [技术干货] SQL Server中row_number函数的常见用法示例详解
    一.SQL Server Row_number函数简介ROW_NUMBER()是一个Window函数,它为结果集的分区中的每一行分配一个连续的整数。 行号以每个分区中第一行的行号开头以下是ROW_NUMBER()函数的语法实例:select *,row_number() over(partition by column1 order by column2) as n from tablename在上面语法中:PARTITION BY子句将结果集划分为分区。 ROW_NUMBER()函数分别应用于每个分区,并重新初始化每个分区的行号。PARTITION BY子句是可选的。如果未指定,ROW_NUMBER()函数会将整个结果集视为单个分区。ORDER BY子句定义结果集的每个分区中的行的逻辑顺序。 ORDER BY子句是必需的,因为ROW_NUMBER()函数对顺序敏感。二.Row_number函数的具体用法1.使用row_number()函数对结果集进行编号,如:select ROW_NUMBER() over(order by recordid ) as 编号,* from [dbo].[Basal_Anormal_Solution]运行结果:              2.对结果集按照指定列进行分组,并在组内按照指定列排序(如:把班级的总分按照小组进行分组显示,分组后在组内进行从高分到低分的排序)select *,row_number() over(partition by createby order by actionOpeid) as n from [dbo].[Basal_Anormal_Solution]运行结果:         3.对结果集按照指定列去重(如:对学生成绩按小组进行分组显示,结果集中只显示每组中一位最高分的学生)select a.* from (select *,row_number() over(partition by createby order by actionOpeid)  as n from [dbo].[Basal_Anormal_Solution])as a where a.n<2运行结果:        注意:当我们求的是第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果。这个时候就要用到另外一个函数,rank()和dense_rank();rank()和dense_rank()区别:rank()是跳跃排序,有两个第二名时接下来就是第四名。这个时候我们通常会选择用rank()函数,灵活应用。
  • [技术干货] SQL Server 分页编号的另一种方式
    今天看书讲T-SQL,看到了UNBOUNDED PRECEDING,就想比对下ROW_NUMBER()的运行速度。sql及相关的结果如下,数据库中的数据有5W+。ROW_NUMBER(): SET STATISTICS TIME ON SELECT   ROW_NUMBER() OVER(ORDER BY Id DESC) rn,Id FROM   dbo.T_MyCourse运行结果:              UNBOUNDED PRECEDING SET STATISTICS TIME ON SELECT   SUM(1) OVER(ORDER BY Id DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) rn,Id FROM   dbo.T_MyCourse运行结果:            通过运行之后,看到结果,使用微软官方提供的方法进行编号排序,速度明显的提高。不过我使用上述方法进行分页获取数据的时候结果又有点不一样。分页获取数据:ROW_NUMBER() 分页获取数据:SET STATISTICS TIME ON SELECT   * FROM   (   SELECT     ROW_NUMBER() OVER(ORDER BY Id DESC) rn,Id   FROM     dbo.T_MyCourse   )a WHERE   a.rn BETWEEN 55 AND 444             执行sql命令:DBCC DROPCLEANBUFFERS ,清除数据库缓存后的结果           UNBOUNDED分页获取数据:SET STATISTICS TIME ON SELECT   * FROM   (   SELECT     SUM(1) OVER(ORDER BY Id DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) rn,Id   FROM     dbo.T_MyCourse   )a WHERE   a.rn BETWEEN 22 AND 444           UNBOUNDED这个方式下执行了DBCC DROPCLEANBUFFERS 清除缓存的sql也没有用,执行时间没有变化。通过上述结果,看到ROW_NUMBER()获取分页的数据明显更快,我猜测是微软对ROW_NUMBER()这个方法做了优化,可能是有缓存,读取的缓存中的数据然后进行分页。
  • [技术干货] SQL Server三种锁定模式的知识讲解
    sql server 锁定模式有三种:共享( S锁),更新(U锁),排他(X锁);S锁是共享锁,如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。个人理解为,对数据A的操作就只能是SELECT ,(联想下,S锁,不就是Select的首字母么),其他事务对A数据的UPDATE ,DELETE都不能进行;U锁是更新锁。用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。原理解释:更新锁       更新 (U) 锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取记录,获取资源(页或行)的共享 (S) 锁,然后修改行,此操作要求锁转换为排它 (X) 锁。       如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它 (X) 锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的排它锁与其它事务的共享模式锁不兼容;发生锁等待。        第二个事务试图获取排它 (X) 锁以进行更新。由于两个事务都要转换为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。若要避免这种潜在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。      如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。      个人理解,打个比方,A,B都拿把枪指着对方说:”我等你放下枪我就放下枪“,大家都等对方放下枪,于是就这么死僵持着......X锁是排他锁,也叫独占锁,事务对A资源的insert ,update ,delete要用独占,不然的话乱套了;这是为了保护数据再一次操作中的准确性;个人理解就是,一次一个....
  • [技术干货] Sql Server数据库常用Transact-SQL脚本
    Transact-SQLTransact-SQL(又称 T-SQL),是在 Microsoft SQL Server 和 Sybase SQL Server 上的 ANSI SQL 实现,与 Oracle 的 PL/SQL 性质相近(不只是实现 ANSI SQL,也为自身数据库系统的特性提供实现支持),在 Microsoft SQL Server 和 Sybase Adaptive Server 中仍然被使用为核心的查询语言。数据库1、创建数据库USE master ;  GO  CREATE DATABASE Sales  ON ( NAME = Sales_dat,   FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\saledat.mdf',   SIZE = 10,   MAXSIZE = 50,   FILEGROWTH = 5 )  LOG ON ( NAME = Sales_log,   FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\salelog.ldf',   SIZE = 5MB,   MAXSIZE = 25MB,   FILEGROWTH = 5MB ) ;  GO2、查看数据库SELECT name, database_id, create_date  FROM sys.databases ;3、删除数据库DROP DATABASE Sales;表1、创建表CREATE TABLE PurchaseOrderDetail  (   ID uniqueidentifier NOT NULL  ,LineNumber smallint NOT NULL  ,ProductID int NULL  ,UnitPrice money NULL  ,OrderQty smallint NULL  ,ReceivedQty float NULL  ,RejectedQty float NULL  ,DueDate datetime NULL );2、删除表DROP TABLE dbo.PurchaseOrderDetail;3、重命名表EXEC sp_rename 'Sales.SalesTerritory', 'SalesTerr';列1、添加列ALTER TABLE dbo.doc_exa ADD column_b VARCHAR(20) NULL, column_c INT NULL ;2、删除列ALTER TABLE dbo.doc_exb DROP COLUMN column_b;3、重命名列EXEC sp_rename 'Sales.SalesTerritory.TerritoryID', 'TerrID', 'COLUMN';约束1、主键--在现有表中创建主键 ALTER TABLE Production.TransactionHistoryArchive  ADD CONSTRAINT PK_TransactionHistoryArchive_TransactionID PRIMARY KEY CLUSTERED (TransactionID);   --在新表中创建主键 CREATE TABLE Production.TransactionHistoryArchive1  (   TransactionID int IDENTITY (1,1) NOT NULL   , CONSTRAINT PK_TransactionHistoryArchive_TransactionID PRIMARY KEY CLUSTERED (TransactionID)  ) ;   --查看主键  SELECT name FROM sys.key_constraints  WHERE type = 'PK' AND OBJECT_NAME(parent_object_id) = N'TransactionHistoryArchive';  GO  --删除主键 ALTER TABLE Production.TransactionHistoryArchive  DROP CONSTRAINT PK_TransactionHistoryArchive_TransactionID;  GO视图1、创建视图CREATE VIEW V_EmployeeHireDate  AS SELECT p.FirstName, p.LastName, e.HireDate  FROM HumanResources.Employee AS e JOIN Person.Person AS p  ON e.BusinessEntityID = p.BusinessEntityID ;  GO2、删除视图DROP VIEW V_EmployeeHireDate;存储过程1、创建存储过程CREATE PROCEDURE P_UspGetEmployeesTest   @LastName nvarchar(50),   @FirstName nvarchar(50)  AS  SELECT FirstName, LastName, Department   FROM HumanResources.vEmployeeDepartmentHistory   WHERE FirstName = @FirstName AND LastName = @LastName   AND EndDate IS NULL;  GO2、删除存储过程DROP PROCEDURE P_UspGetEmployeesTest;3、执行存储过程EXEC P_UspGetEmployeesTest N'Ackerman', N'Pilar';  -- Or  EXEC P_UspGetEmployeesTest @LastName = N'Ackerman', @FirstName = N'Pilar';  GO  -- Or  EXECUTE P_UspGetEmployeesTest @FirstName = N'Pilar', @LastName = N'Ackerman';  GO4、重命名存储过程EXEC sp_rename 'P_UspGetAllEmployeesTest', 'P_UspEveryEmployeeTest2';5、带有输出参数的存储过程CREATE PROCEDURE P_UspGetEmployeeSalesYTD  @SalesPerson nvarchar(50),  @SalesYTD money OUTPUT  AS   SELECT @SalesYTD = SalesYTD   FROM SalesPerson AS sp   JOIN vEmployee AS e ON e.BusinessEntityID = sp.BusinessEntityID   WHERE LastName = @SalesPerson;  RETURN  GO   --调用 DECLARE @SalesYTDBySalesPerson money;  EXECUTE P_UspGetEmployeeSalesYTD   N'Blythe',   @SalesYTD = @SalesYTDBySalesPerson OUTPUT;  GO数据类型                                
  • [技术干货] Sql Server数据把列根据指定内容拆分数据的方法实例
    由于工作需要,需要把数据把列根据指定的内容拆分数据其中一条数据实例 select id , XXXX FROM BIZ_PAPER where  id ='4af210ec675927fa016772bf7dd025b0'  拆分方法:select t3.id ,t3.XXXX as XXXX from ( select A.id , B.XXXX from ( SELECT id, XXXX = CONVERT(xml,'<root><v>' + REPLACE(XXXX , ',', '</v><v>') + '</v></root>') FROM BIZ_PAPER) A outer apply( SELECT XXXX = N.v.value('.', 'varchar(100)') FROM A.XXXX .nodes('/root/v') N(v)) B) t3 where t3.id ='4af210ec675927fa016772bf7dd025b0'结果在自己研究这行代码之后,做出如下讲解,如果有错误的地方还请指教SELECT id, XXXX = CONVERT(xml,'<root><v>' + REPLACE(XXXX , ',', '</v><v>') + '</v></root>') FROM BIZ_PAPER这一行的重点在于CONVERT,XML是指类型,xml 数据类型实例拆分为关系数据,则 nodes() 方法非常有用,至于XML类型的数据,我后面进行补充REPLACE 指按照 ' , ' 进行替换,并且按照指定的内容进行拼接最后的结果为outer apply这个就是表的关联,就像是left join ,但是没有on 作为关联条件,所以通过拆分之后多出来的数据就是通过这个进行关联后产生的SELECT XXXX = N.v.value('.', 'varchar(100)') FROM A.XXXX .nodes('/root/v') N(v)N.v.value('.','varchar(100)'),N是表,别名,v是列,value函数是读取标签之间的值,对于这个列子,读取的为<v>和</v>中间的值;这个可以去了解 xml类型的常用的三个方法 :value()、nodes()、exist()            value的第一个参数是一个字符串文字,从 XML 实例内部检索数据。            XQuery 必须最多返回一个值。 否则,将返回错误;value的第二个参数是指将查询结果转化为何种类型的数据。此处,'.'表示当前目录,即<v>目录,另外'..'表示上级目录,'/'表示根目录,这个跟Linux是一样的总的来说,这个语句的重点在于xml类型的使用和outer apply的使用,其他的都很好理解。这个就是我自己理解后的讲解,部分位置我自己也还没有理解透
  • [技术干货] sql server 交集,差集的用法详解
    概述:        为什么使用集合运行:       在集合运算中比联接查询和EXISTS/NOT EXISTS更方便。并级运算(UNION)并集:俩个集合的并集是一个包含的A和B的中所有的元素。                       在T-SQL中。UNION集合运算可以将两个输入查询的结果组合成一个结果集。需要注意的是:如果一个行在任何一个输入集合中出现,它也会在UNION运算的结果中出现。T-SQL支持以下两种选项:(1)UNION ALL:不会删除重复行-- union allselect  country, region, city from hr.Employees union all select country, region, city from sales.Customers;(2)UNION:会删除重复行-- union select country, region from hr.Employees union select country, region from sales.Customers;交集运算(INTERSECT)交集:两个集合(记为集合A和集合B)的交集是由既属于A,也属于B的所有元素组成的集合。                在T-SQL中,INTERSECT集合运算对两个输入查询的结果取其交集,只返回在两个查询结果集中都出现的行。INTERSECT集合运算在逻辑上会首先删除两个输入集中的重复行,然后返回只在两个集合中中都出现的行。换句话说:如果一个行在两个输入集中都至少出现一次,那么交集返回的结果中将包含这一行。例如,下面返回既是雇员地址,又是客户地址的不同地址:-- intersect select country, region, city from hr.Employees intersect select country, region, city from sales.Customers;这里需要说的是,集合运算对行进行比较时,认为两个NULL值相等,所以就返回该行记录。差集运算(EXCEPT)差集:两个集合(记为集合A和集合B)的由属于集合A,但不属于集合B的所有元素组成的集合。                    在T-SQL中,集合之差使用EXCEPT集合运算实现的。它对两个输入查询的结果集进行操作,反会出现在第一个结果集中,但不出现在第二个结果集中的所有行。       EXCEPT结合运算在逻辑上首先删除两个输入集中的重复行,然后返回只在第一个集合中出现,在第二个结果集中不出现的所有行。       换句话说:一个行能够被返回,仅当这个行在第一个输入的集合中至少出现过一次,而且在第二个集合中一次也没出现过。       此外,相比UNION和INTERSECT,两个输入集合的顺序是会影响到最后返回结果的。      例如,借助EXCEPT运算,我们可以方便地实现属于A但不属于B的场景,下面返回属于员工抵制,但不属于客户地址的地址记录:-- except  select country, region, city from hr.Employees except select country, region, city from sales.Customers;集合运算优先级                 SQL定义了集合运算之间的优先级:INTERSECT最高,UNION和EXCEPT相等。      换句话说:首先会计算INTERSECT,然后按照从左至右的出现顺序依次处理优先级相同的运算。-- 集合运算的优先级 select country, region, city from Production.Suppliers except select country, region, city from hr.Employees intersect select country, region, city from sales.Customers;上面这段SQL代码,因为INTERSECT优先级比EXCEPT高,所以首先进行INTERSECT交集运算。因此,这个查询的含义是:返回没有出现在员工地址和客户地址交集中的供应商地址。集合运算的优先级1.INTERSECT>UNION=EXCEPT2.首先计算INTERSECT,然后从左到右的出现顺序依次处理优先级的相同的运算。3.可以使用圆括号控制集合运算的优先级,它具有最高的优先级。在排序函数的OVER字句中使用ORDER BY ( SELECT <常量> )可以告诉SQL Server不必在意行的顺序。使用表表达式避开不支持的逻辑查询处理集合运算查询本身并不持之除ORDER BY意外的其他逻辑查询处理阶段,但可以通过表表达式来避开这一限制。  解决方案就是:首先根据包含集合运算的查询定义一个表表达式,然后在外部查询中对表表达式应用任何需要的逻辑查询处理。(1)例如,下面的查询返回每个国家中不同的员工地址或客户地址的数量:select country, COUNT(*) as numlocations from (select country, region, city from hr.Employees  union  select country, region, city from sales.Customers) as Ugroup by country;(2)例如,下面的查询返回由员工地址为3或5的员工最近处理过的两个订单:select empid,orderid,orderdate  from (select top (2) empid,orderid,orderdate   from sales.Orders  where empid=3  order by orderdate desc,orderid desc) as D1 union all select empid,orderid,orderdate  from (select top (2) empid,orderid,orderdate   from sales.Orders  where empid=5  order by orderdate desc,orderid desc) as D2;
  • [行业资讯] SQL Server最正确的打开方式
    数据库这个大家庭里,还有一位不容小觑的成员云数据库SQL Server什么是云数据库SQL Server ?Microsoft SQL Server是世界上最受欢迎的商用关系型数据库集成各类管理开发工具。云数据库SQL Server为微软正版授权,完美支持基于Windows架构的应用程序,性能与性价比兼具。云数据库SQL Server优势高用同城高可用架构,自动故障秒级切换高安全14项国际安全合规认证,有效抵御网络攻击全面监控报警专业管理运维平台,多维系统资源监控,自定义报警配置高性价比微软SQL Server企业版授权许可,无需支付版权费用云数据库SQL Server应用场景金融行业支持VPC、子网设置实现网络隔离安全组设置提供访问控制保证数据安全[提供灵活备份方案支持高可靠业务需求互联网行业兼容微软SQL Server 线下数据库迁移上云优秀事务并发处理能力保证数据可靠和稳定要求弹性扩容,匹配业务,节省成本移上云软件开发行业无缝对接微软集成开发工具,缩短开发周期使用微软原生可视化管理工具 |,降低运维难度和成本
  • [技术干货] SQL Server连接不上的判断方法
    场景排查1. ECS能否ping通RDS。如果ping不通,可以查看ECS和RDS是否处于同一个VPC内,是否使用同一个安全组。2. 检查连接IP和端口号是否正确。注意IP和端口号之间使用“逗号”隔开。3. 检查RDS服务的运行状态是否异常。4.查看用户名密码是否正确,尝试重置密码。5. 尝试重启RDS实例,看看是否改善。解决方案步骤 1    登录管理控制台,选择区域和项目,选择“数据库 > 关系型数据库”。进入关系型数据库“实例管理”页面,单击目标实例名称,进入“基本信息”页面和“备份恢复”页面确定连接信息和备份信息。步骤 2    在实例“基本信息”页面查看管理员账户名。步骤 3     下载并在ECS上安装SSMS客户端。步骤 4     从ECS连接到RDS。
  • [技术干货] SQL Server内存管理小知识
    今天和大家聊一聊SQL server的内存管理,说之前我们需要先提出一个问题,SQL Server到底是如何使用内存的?弄清楚如何使用之后,才能谈如何管理。简单说,SQL Server 数据库的内存使用原则是有多少内存就会占用多少内存,不会自动释放内存。原因是它的存储引擎本身是一个Windows下的进程,所以在使用内存时和其它Windows进程是一样的,都要向Windows申请内存,申请到内存之后,SQL Server的内存使用可以粗略地分为两个部分:一是缓冲池内存,被数据页和空闲页占用;二是非缓冲内存,被线程、DLL、链接服务器等占用。其中缓冲池内存占大头。这样会有什么问题呢?打个比方,如在执行一条结果集很大的 sql 时,数据查询取出后,会一直占用内存,直到机器内存被占满(并不会撑爆,因为可以通过图去限制最大内存,一般占满后仍然比服务器机器内存稍小),在重启数据库服务前,SQL Server不会主动释放该内存,也没有任何办法可人为释放,一直占用到 max server memory 的设定值,因此查看 SQL Server的内存基本使用率相对较高(80%以上)。 那怎么解决呢?最直接的办法是:人为修改最大可占用物理内存进行限制。方法一:缓冲池所占内存是通过下图1最大服务器内存和最小服务器内存来设置的,因此sqlservr.exe所占的内存(如图2)有可能会大于图1中所设置的最大内存。管理员用户登录数据库客户端(Microsoft SQL Server Management Studio),在实例名(树形菜单根节点,显示登录名那栏)上右键,选择属性-->内存,设置“最大服务器内存”即可根据实际情况调整内存(单位为MB),如调整到当前总的服务器内存的 70%左右使用率。图1 SQL Server可控制内存选项图2 SQL Server 进程内存使用情况方法二:如果使用的是华为云RDS SQL Server ,那解决方法就更加简单了,只需要到控制台实例管理中修改最大内存(max server memory)参数值即可,且修改完该参数不需要重启数据库,不得不说云数据库使用起来更加便捷清晰,更多华为云RDS SQL Server的使用可参考官方文档:https://support.huaweicloud.com/rds/index.html 
  • [技术干货] U8CLOUDE 线下客户端如何在RDS SQL Server上进行数据库初始化步骤
    背景:用友U8线下盒子账号需要在华为公有云端进行部署安装,在用户将应用端安装到ECS虚拟机上之后,还需要创建RDS SQL Server,并远程指定该实例作为后端数据库,同时需要在该实例上进行U8数据库初始化操作,具体操作流程如下。 步骤:1.创建RDS SQL Server实例,通过华为云DAS数据库在线管理工具直接登录该实例点击实例进入实例详情页,在基本信息Tag页的右上角点击登录按钮2.在DAS在线管理界面点击SQL窗口,在新窗口中输入以下脚本并直接执行(也可以通过SSMS官方客户端连接执行):拷贝以下脚本到窗口中直接执行:-- 创建数据库USE master;goIF DB_ID (N'U8CLOUD') IS NOT NULLDROP DATABASE [U8CLOUD];goCREATE DATABASE [U8CLOUD] ALTER DATABASE [U8CLOUD] ADD FILEGROUP [NNC_DATA01] ALTER DATABASE [U8CLOUD] ADD FILEGROUP [NNC_DATA02] ALTER DATABASE [U8CLOUD] ADD FILEGROUP [NNC_DATA03] ALTER DATABASE [U8CLOUD] ADD FILEGROUP [NNC_INDEX01] ALTER DATABASE [U8CLOUD] ADD FILEGROUP [NNC_INDEX02] ALTER DATABASE [U8CLOUD] ADD FILEGROUP [NNC_INDEX03] ALTER DATABASE [U8CLOUD] ADD FILE(NAME = N'nnc_data01', FILENAME = N'D:\RDSDBDATA\DATA\nnc_data01_Data.NDF' , SIZE = 500, FILEGROWTH = 200) TO FILEGROUP [NNC_DATA01] ALTER DATABASE [U8CLOUD] ADD FILE(NAME = N'nnc_data02', FILENAME = N'D:\RDSDBDATA\DATA\nnc_data02_Data.NDF' , SIZE = 500, FILEGROWTH = 200) TO FILEGROUP [NNC_DATA02] ALTER DATABASE [U8CLOUD] ADD FILE(NAME = N'nnc_data03', FILENAME = N'D:\RDSDBDATA\DATA\nnc_data03_Data.NDF' , SIZE = 500, FILEGROWTH = 200) TO FILEGROUP [NNC_DATA03] ALTER DATABASE [U8CLOUD] ADD FILE(NAME = N'nnc_index01', FILENAME = N'D:\RDSDBDATA\DATA\nnc_index01_Data.NDF' , SIZE = 200, FILEGROWTH = 100) TO FILEGROUP [NNC_INDEX01] ALTER DATABASE [U8CLOUD] ADD FILE(NAME = N'nnc_index02', FILENAME = N'D:\RDSDBDATA\DATA\nnc_index02_Data.NDF' , SIZE = 200, FILEGROWTH = 100) TO FILEGROUP [NNC_INDEX02] ALTER DATABASE [U8CLOUD] ADD FILE(NAME = N'nnc_index03', FILENAME = N'D:\RDSDBDATA\DATA\nnc_index03_Data.NDF' , SIZE = 200, FILEGROWTH = 100) TO FILEGROUP [NNC_INDEX03]--修改数据库字符集ALTER DATABASE [U8CLOUD] COLLATE Chinese_PRC_CI_ASGO--切换数据库use U8CLOUDgo --启用快照隔离declare @exec_stmt nvarchar(4000) select @exec_stmt='ALTER DATABASE '+db_name()+' set read_committed_snapshot ON ' exec (@exec_stmt) 3.返回实例管理详情页:1.在左侧点击参数修改进入参数修改页面2.在查询框中输入max查找参数3.找到max degree of parallelism 将其值修改为14.点击保存完成操作 4.临时数据库不用再改了,已经是最佳实践
  • [技术干货] RDS for SQL Server收缩数据库
    操作场景     华为云SQL Server提供存储过程,用于收缩数据库的数据文件和日志文件,以释放磁盘部分空间。操作步骤     连接RDS for SQL Server实例,执行以下命令,进行数据库收缩。       EXEC [master].[dbo].[rds_shrink_database] @DBName = 'myDBName';     参数       myDBName: 要收缩的数据库名称。如果未指定,则默认对所有数据库进行收缩。       结果A.结果集返回多个结果集,每个结果对应指定数据库(或所有数据库)的每个文件的相关信息。结果集结构如下:列名称说明DbId当前收缩的文件的数据库标识号。FileId当前收缩的文件的文件标识号。CurrentSize文件当前占用的 8 KB 页数。MinimumSize文件最低可以占用的 8   KB 页数。 此数字对应于文件的大小下限或最初创建大小。UsedPages文件当前使用的 8 KB 页数。EstimatedPages数据库引擎估计文件能够收缩到的 8 KB 页数。 B. 消息打印命令执行进度。最佳实践Ø  在执行会产生大量未用空间的操作(如重启)后,执行收缩操作最有效Ø  大多数数据库都需要一些可用空间,以供常规日常操作使用。 如果反复收缩数据库,并且它的大小再次增长,那么常规操作可能需要收缩空间。 在这种情况下,反复收缩数据库是一种无谓的操作。Ø  收缩操作不保留数据库中索引的碎片状态,通常还会在一定程度上增加碎片。 此类碎片是不要反复收缩数据库的另一个原因。故障排除l  文件未收缩1.     如果在执行存储过程后文件大小未改变,请运行以下SQL,验证文件是否有足够的可用空间:SELECT name, size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB FROM sys.database_files; 2.     如果要收缩的数据库文件大小不超过50MB,对该文件的收缩将不起作用。且会打印相关提示。如: l  收缩操作受阻基于行版本控制的隔离级别下运行的事务可能会阻止收缩操作。若要解决此问题,请执行下列任务之一:²  终止阻止收缩操作的事务。²  终止收缩操作。 如果收缩操作终止,所有已完成的工作都会保留。²  不执行任何操作,并允许收缩操作等到阻塞事务完成。示例     收缩指定数据库       以下示例将 dbtest2 数据库进行收缩。EXEC [master].[dbo].[rds_shrink_database] @DBName = 'dbtest2';执行结果如下: 收缩所有数据库以下示例将收缩所有数据库。EXEC [master].[dbo].[rds_shrink_database];
总条数:109 到第
上滑加载中