-
关于Sql Server最大连接数(Max Pool Size)的问题,后来通过查找一些资料解决了,所以想着总结下一、设置最大连接数下面的T-SQL 语句可以配置SQL Server 允许的并发用户连接的最大数目。exec sp_configure 'show advanced options', 1 exec sp_configure 'user connections', 100第一句用以表示显示sp_configure 系统存储过程高级选项,使用user connections 时,要求show advanced options 值为1。第二句配置最大连接数为100,0 表示不限制,但不表示无限,后面将谈谈。也可以在企业管理器中配置,在企业管理器中,可以在实例上点右键->“属性”->“连接”里面更改。需要重新启动SQL Server,该值才会生效。@@max_connectionsselect @@max_connections它总是返回32767,它并不是指上面设置的user connections,实际上它表示user connections 最大可设置为多少。由于它的最大值是32767,那么user connections 为0 时,最大连接数也就是32767 了,并不是无限。默认情况下user connections 值是0,也就是说默认情况下SQL Server 的最大连接数是32767。二、获得当前设置的最大连接数:select value from master.dbo.sysconfigures where [config]=103 三、如何监测SQLServer的连接数/*查询连接数*/ select loginame,count(1) as Nums from sys.sysprocesses group by loginame order by 2 desc select spid,ecid,status,loginame,hostname,cmd,request_id from sys.sysprocesses where loginame='' and hostname=''方法二:SP_WHO 'loginName'loginName 是当然登陆Sql的用户名,一般程序里面都会使用一个username来登陆SQL这样通过这个用户名就能查看到此用户名登陆之后占用的连接了。如果不写loginName,那么返回的就是所有的连接。既然连接数是可预测、可监测的,那么它就是可度量的,那么我们就可以根据实际情况来评估或测试程序的并发放量了。
-
3.最后一步是测试和验证日志表是否正确。以下是添加触发器后对表进行更新的测试:12345678UPDATE Orders SET InternalComments = 'Item is no longer backordered', BackorderOrderID = NULL, IsUndersupplyBackordered = 0, LastEditedBy = 1, LastEditedWhen = SYSUTCDATETIME()FROM sales.OrdersWHERE Orders.OrderID = 10;结果如下:点击并拖拽以移动上面省略了一些列,但是我们可以快速确认已经触发了更改,包括日志表末尾新增的列。INSERT和DELETE前面的示例中,进行插入和删除操作后,读取日志表中使用的数据。这种特殊的表可以作为任何相关写操作的一部分。INSERT将包含**入操作触发,DELETE将被删除操作触发,UPDATE包含**入和删除操作触发。对于INSERT和UPDATE,将包含表中每个列新值的快照。对于DELETE和UPDATE操作,将包含写操作之前表中每个列旧值的快照。触发器什么时候最有用DML触发器的最佳使用是简短、简单且易于维护的写操作,这些操作在很大程度上独立于应用程序业务逻辑。触发器的一些重要用途包括:记录对历史表的更改审计用户及其对敏感表的操作。向表中添加应用程序可能无法使用的额外值(由于安全限制或其他限制),例如: 登录/用户名 操作发生时间服务器/数据库名称简单的验证。关键是让触发器代码保持足够的紧凑,从而便于维护。当触发器增长到成千上万行时,它们就成了开发人员不敢去打扰的黑盒。结果,更多的代码被添加进来,但是旧的代码很少被检查。即使有了文档,这也很难维护。为了让触发器有效地发挥作用,应该将它们编写为基于设置的。如果存储过程必须在触发器中使用,则确保它们在需要时使用表值参数,以便可以基于集的方式移动数据。下面是一个触发器的示例,该触发器遍历id,以便使用结果顺序id执行示例存储过程:123456789101112131415161718CREATE TRIGGER TR_Sales_Orders_Process ON Sales.Orders AFTER INSERTASBEGIN SET NOCOUNT ON; DECLARE @count INT; SELECT @count = COUNT(*) FROM inserted; DECLARE @min_id INT; SELECT @min_id = MIN(OrderID) FROM inserted; DECLARE @current_id INT = @min_id; WHILE @current_id < @current_id + @count BEGIN EXEC dbo.process_order_fulfillment @OrderID = @current_id; SELECT @current_id = @current_id + 1; ENDEND虽然相对简单,但当一次插入多行时对 Sales.Orders的INSERT操作的性能将受到影响,因为SQL Server在执行process_order_fulfillment存储过程时将被迫逐个执行。一个简单的修复方法是重写存储过程,并将一组Order id传递到存储过程中,而不是一次一个地这样做:1234567891011121314CREATE TYPE dbo.udt_OrderID_List AS TABLE( OrderID INT NOT NULL, PRIMARY KEY CLUSTERED ( OrderID ASC));GOCREATE TRIGGER TR_Sales_Orders_Process ON Sales.Orders AFTER INSERTASBEGIN SET NOCOUNT ON; DECLARE @OrderID_List dbo.udt_OrderID_List; EXEC dbo.process_order_fulfillment @OrderIDs = @OrderID_List;END更改的结果是将完整的id集合从触发器传递到存储过程并进行处理。只要存储过程以基于集合的方式管理这些数据,就可以避免重复执行,也就是说,避免在触发器内使用存储过程有很大的价值,因为它们添加了额外的封装层,进一步隐藏了在数据写入表时执行的TSQL。它们应该被认为是最后的手段,只有当可以在应用程序的许多地方多次重写TSQL时才使用。什么时候触发器是危险的架构师和开发人员面临的最大挑战之一是确保触发器只在需要时使用,而不允许它们成为一刀切的解决方案。向触发器添加TSQL通常被认为比向应用程序添加代码更快、更容易,但随着时间的推移,这样做的成本会随着每添加一行代码而增加。触发器在以下情况下会变得危险:保持尽可能少的触发以减少复杂性。触发代码变得复杂。如果更新表中的一行导致要执行数千行添加的触发器代码,那么开发人员就很难完全理解数据写入表时会发生什么。更糟糕的是,当出现问题时,故障排除非常具有挑战性。触发器跨服务器。这将网络操作引入到触发器中,可能导致在出现连接问题时写入速度变慢或失败。如果目标数据库是要维护的对象,那么即使是跨数据库触发器也会有问题。触发器调用触发器。触发器中最令人痛苦的是,当插入一行时,写操作会导致75个表中有100个触发器要执行。在编写触发器代码时,确保触发器可以执行所有必要的逻辑,而不会触发更多触发器。额外的触发通常是不必要的。递归触发器被设置为ON。这是一个默认设置为off的数据库级别设置。打开时,它允许触发器的内容调用相同的触发器。递归触发器会极大地损害性能,调试时也会非常混乱。通常,当一个触发器中的DML作为操作的一部分触发其他触发器时,使用递归触发器。函数、存储过程或视图都在触发器中。在触发器中封装更多的业务逻辑会使它们变得更复杂,并给人一种触发器代码短小简单的错误印象,而实际上并非如此。尽可能避免在触发器中使用存储过程和函数。迭代发生。循环和游标本质上是逐行操作的,可能会导致对1000行的操作一次触发1000次,这极大地损害了查询性能。这是一个很长的列表,但通常可以总结为短而简单的触发器会表现得更好,并避免上面的大多数陷阱。如果使用触发器来维护复杂的业务逻辑,那么随着时间的推移,越来越多的业务逻辑将被添加进来,并且不可避免地将违反上述最佳实践。重要的是要注意,为了维护原子的、事务,受触发器影响的任何对象都将保持事务处于打开状态,直到该触发器完成。这意味着长触发器不仅会使事务持续时间更长,而且还会持有锁并导致持续时间更长。因此,在测试触发器时,在为现有触发器创建或添加额外逻辑时,应该了解它们对锁、阻塞和等待的影响。
-
SQL Server触发器在非常有争议的主题。它们能以较低的成本提供便利,但经常被开发人员、DBA误用,导致性能瓶颈或维护性挑战。本文简要回顾了触发器,并深入讨论了如何有效地使用触发器,以及何时触发器会使开发人员陷入难以逃脱的困境。虽然本文中的所有演示都是在SQL Server中进行的,但这里提供的建议是大多数数据库通用的。触发器带来的挑战在MySQL、PostgreSQL、MongoDB和许多其他应用中也可以看到。什么是触发器可以在数据库或表上定义SQL Server触发器,它允许代码在发生特定操作时自动执行。本文主要关注表上的DML触发器,因为它们往往被过度使用。相反,数据库的DDL触发器通常更集中,对性能的危害更小。触发器是对表中数据更改时进行计算的一组代码。触发器可以定义为在插入、更新、删除或这些操作的任何组合上执行。MERGE操作可以触发语句中每个操作的触发器。触发器可以定义为INSTEAD OF或AFTER。AFTER触发器发生在数据写入表之后,是一组独立的操作,和写入表的操作在同一事务执行,但在写入发生之后执行。如果触发器失败,原始操作也会失败。INSTEAD OF触发器替换调用的写操作。插入、更新或删除操作永远不会发生,而是执行触发器的内容。触发器允许在发生写操作时执行TSQL,而不管这些写操作的来源是什么。它们通常用于在希望确保执行写操作时运行关键操作,如日志记录、验证或其他DML。这很方便,写操作可以来自API、应用程序代码、发布脚本,或者内部流程,触发器无论如何都会触发。触发器是什么样的用WideWorldImporters示例数据库中的Sales.Orders 表举例,假设需要记录该表上的所有更新或删除操作,以及有关更改发生的一些细节。这个操作可以通过修改代码来完成,但是这样做需要对表的代码写入中的每个位置进行更改。通过触发器解决这一问题,可以采取以下步骤:1. 创建一个日志表来接受写入的数据。下面的TSQL创建了一个简单日志表,以及一些添加的数据点:12345678910111213141516171819202122232425262728293031323334353637CREATE TABLE Sales.Orders_log( Orders_log_ID int NOT NULL IDENTITY(1,1) CONSTRAINT PK_Sales_Orders_log PRIMARY KEY CLUSTERED, OrderID int NOT NULL, CustomerID_Old int NOT NULL, CustomerID_New int NOT NULL, SalespersonPersonID_Old int NOT NULL, SalespersonPersonID_New int NOT NULL, PickedByPersonID_Old int NULL, PickedByPersonID_New int NULL, ContactPersonID_Old int NOT NULL, ContactPersonID_New int NOT NULL, BackorderOrderID_Old int NULL, BackorderOrderID_New int NULL, OrderDate_Old date NOT NULL, OrderDate_New date NOT NULL, ExpectedDeliveryDate_Old date NOT NULL, ExpectedDeliveryDate_New date NOT NULL, CustomerPurchaseOrderNumber_Old nvarchar(20) NULL, CustomerPurchaseOrderNumber_New nvarchar(20) NULL, IsUndersupplyBackordered_Old bit NOT NULL, IsUndersupplyBackordered_New bit NOT NULL, Comments_Old nvarchar(max) NULL, Comments_New nvarchar(max) NULL, DeliveryInstructions_Old nvarchar(max) NULL, DeliveryInstructions_New nvarchar(max) NULL, InternalComments_Old nvarchar(max) NULL, InternalComments_New nvarchar(max) NULL, PickingCompletedWhen_Old datetime2(7) NULL, PickingCompletedWhen_New datetime2(7) NULL, LastEditedBy_Old int NOT NULL, LastEditedBy_New int NOT NULL, LastEditedWhen_Old datetime2(7) NOT NULL, LastEditedWhen_New datetime2(7) NOT NULL, ActionType VARCHAR(6) NOT NULL, ActionTime DATETIME2(3) NOT NULL,UserName VARCHAR(128) NULL);该表记录所有列的旧值和新值。这是非常全面的,我们可以简单地记录旧版本的行,并能够通过将新版本和旧版本合并在一起来了解更改的过程。最后3列是新增的,提供了有关执行的操作类型(插入、更新或删除)、时间和操作人。2. 创建一个触发器来记录表的更改:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778CREATE TRIGGER TR_Sales_Orders_Audit ON Sales.Orders AFTER INSERT, UPDATE, DELETEASBEGIN SET NOCOUNT ON; INSERT INTO Sales.Orders_log (OrderID, CustomerID_Old, CustomerID_New, SalespersonPersonID_Old, SalespersonPersonID_New, PickedByPersonID_Old, PickedByPersonID_New, ContactPersonID_Old, ContactPersonID_New, BackorderOrderID_Old, BackorderOrderID_New, OrderDate_Old, OrderDate_New, ExpectedDeliveryDate_Old, ExpectedDeliveryDate_New, CustomerPurchaseOrderNumber_Old, CustomerPurchaseOrderNumber_New, IsUndersupplyBackordered_Old, IsUndersupplyBackordered_New, Comments_Old, Comments_New, DeliveryInstructions_Old, DeliveryInstructions_New, InternalComments_Old, InternalComments_New, PickingCompletedWhen_Old, PickingCompletedWhen_New, LastEditedBy_Old, LastEditedBy_New, LastEditedWhen_Old, LastEditedWhen_New, ActionType, ActionTime, UserName) SELECT ISNULL(Inserted.OrderID, Deleted.OrderID) AS OrderID, Deleted.CustomerID AS CustomerID_Old, Inserted.CustomerID AS CustomerID_New, Deleted.SalespersonPersonID AS SalespersonPersonID_Old, Inserted.SalespersonPersonID AS SalespersonPersonID_New, Deleted.PickedByPersonID AS PickedByPersonID_Old, Inserted.PickedByPersonID AS PickedByPersonID_New, Deleted.ContactPersonID AS ContactPersonID_Old, Inserted.ContactPersonID AS ContactPersonID_New, Deleted.BackorderOrderID AS BackorderOrderID_Old, Inserted.BackorderOrderID AS BackorderOrderID_New, Deleted.OrderDate AS OrderDate_Old, Inserted.OrderDate AS OrderDate_New, Deleted.ExpectedDeliveryDate AS ExpectedDeliveryDate_Old, Inserted.ExpectedDeliveryDate AS ExpectedDeliveryDate_New, Deleted.CustomerPurchaseOrderNumber AS CustomerPurchaseOrderNumber_Old, Inserted.CustomerPurchaseOrderNumber AS CustomerPurchaseOrderNumber_New,该触发器的唯一功能是将数据插入到日志表中,每行数据对应一个给定的写操作。它很简单,随着时间的推移易于记录和维护,表也会发生变化。如果需要跟踪其他详细信息,可以添加其他列,如数据库名称、服务器名称、受影响列的行数或调用的应用程序。
-
首先我的python环境的 python3使用的软件是 PyCharm (社区版可以免费使用) 1.连接前的准备 连接SQL server数据库需要导入 pymssql这个模块,如果你不知道你有没有安装这个模块你可以 win+r键 输入cmd然后输入 pip list后回车 查看这时候如果你发现没有 pymssql的话 那么你需要安装这个模块 在PyCharm里面创建一个项目后新建一个 python文件 然后再第一行输入 import pymssql 这时候就会提示没有这个模块 点击鼠标放在报错的那条线上之后 选择 安装包pymssql然后安装 等待安装完就行了。如果你没有pycharm这个软件的话你也可以win+r输入cmd 打开cmd后输入pip install pymssql后回车等待一会安装成功就行了如果没有安装成功你可能需要配置一下你的 pip.ini文件 关于配置 pip.ini文件 这里就不多讲了以后在讲2.开始导入好模块后 首先我们连接SqlServer数据库 连接前你必须现有SQL server数据库import pymssqldef conn(): connect = pymssql.connect('(local)', 'sa', 'sa', 'MySql') /创建连接对象(local是本地数据库地址,后面的第一个sa是连接SQL server数据库账户第二个是密码 后面的"是你要连接的某个数据库的名字") 反正我是这么认为的 if connect: print("连接成功!") 如果连接成功就打印 连接成功 return connectif __name__ == '__main__': conn = conn() cursor = conn.cursor() sql = "select * from My" //查询语句 cursor.execute(sql) row = cursor.fetchone() while row: print("ID=%s, Pwd=%s" % (row[0], row[1])) 从数据库里读取后输出的结果 row = cursor.fetchone() cursor.close() conn.close() MySql的连接方法下一篇文章在讲吧 顺便把配置pip的方法也讲了 如果有好的建议可以提出
-
1、判断数据表是否存在方法一:use yourdb; go if object_id(N'tablename',N'U') is not null print '存在' else print '不存在'例子use fireweb; go if object_id(N'TEMP_TBL',N'U') is not null print '存在' else print '不存在'方法二:USE [实例名] GO IF EXISTS (SELECT * FROM dbo.SysObjects WHERE ID = object_id(N'[表名]') AND OBJECTPROPERTY(ID, 'IsTable') = 1) PRINT '存在' ELSE PRINT'不存在'例子:use fireweb; go IF EXISTS (SELECT * FROM dbo.SysObjects WHERE ID = object_id(N'TEMP_TBL') AND OBJECTPROPERTY(ID, 'IsTable') = 1) PRINT '存在' ELSE PRINT'不存在'2、临时表是否存在:方法一:use fireweb; go if exists(select * from tempdb..sysobjects where id=object_id('tempdb..##TEMP_TBL')) PRINT '存在' ELSE PRINT'不存在'方法二:use fireweb; go if exists (select * from tempdb.dbo.sysobjects where id = object_id(N'tempdb..#TEMP_TBL') and type='U') PRINT '存在' ELSE PRINT'不存在'补充介绍:在sqlserver(应该说在目前所有数据库产品)中创建一个资源如表,视图,存储过程中都要判断与创建的资源是否已经存在在sqlserver中一般可通过查询sys.objects系统表来得知结果,不过可以有更方便的方法如下: if object_id('tb_table') is not null print 'exist' else print'not exist'如上,可用object_id()来快速达到相同的目的,tb_table就是我将要创建的资源的名称,所以要先判断当前数据库中不存在相同的资源object_id()可接受两个参数,第一个如上所示,代表资源的名称,上面的就是表的名字,但往往我们要说明我们所要创建的是什么类型的资源,这样sql可以明确地在一种类型的资源中查找是否有重复的名字,如下: if object_id('tb_table','u') is not null print 'exist' else print'not exist'第二个参数 "u" 就表示tb_table是用户创建的表,即:USER_TABLE地首字母简写查询sys.objects中可得到各种资源的类型名称(TYPE列),这里之举几个主要的例子u ----------- 用户创建的表,区别于系统表(USER_TABLE)s ----------- 系统表(SYSTEM_TABLE)v ----------- 视图(VIEW)p ----------- 存储过程(SQL_STORED_PROCEDURE)可使用select distinct type ,type_desc from sys.objects 获得全部信息库是否存在if exists(select * from master..sysdatabases where name=N'库名') print 'exists' else print 'not exists' --------------- -- 判断要创建的表名是否存在 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[表名]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) -- 删除表 drop table [dbo].[表名] GO --------------- -----列是否存在 IF COL_LENGTH( '表名','列名') IS NULL PRINT 'not exists' ELSE PRINT 'exists' alter table 表名 drop constraint 默认值名称 go alter table 表名 drop column 列名 go ----- --判断要创建临时表是否存在 If Object_Id('Tempdb.dbo.#Test') Is Not Null Begin print '存在' End Else Begin print '不存在' End --------------- -- 判断要创建的存储过程名是否存在 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[存储过程名]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) -- 删除存储过程 drop procedure [dbo].[存储过程名] GO --------------- -- 判断要创建的视图名是否存在 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[视图名]') and OBJECTPROPERTY(id, N'IsView') = 1) -- 删除视图 drop view [dbo].[视图名] GO --------------- -- 判断要创建的函数名是否存在 if exists (select * from sysobjects where xtype='fn' and name='函数名') if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[函数名]') and xtype in (N'FN', N'IF', N'TF')) -- 删除函数 drop function [dbo].[函数名] GO if col_length('表名', '列名') is null print '不存在' select 1 from sysobjects where id in (select id from syscolumns where name='列名') and name='表名'
-
一下为SQL server 2012版本。下面都用pageIndex表示页数,pageSize表示一页包含的记录。并且下面涉及到具体例子的,设定查询第2页,每页含10条记录。首先说一下SQL server的分页与MySQL的分页的不同,mysql的分页直接是用limit (pageIndex-1),pageSize就可以完成,但是SQL server 并没有limit关键字,只有类似limit的top关键字。所以分页起来比较麻烦。SQL server分页我所知道的就只有四种:三重循环;利用max(主键);利用row_number关键字,offset/fetch next关键字(是通过搜集网上的其他人的方法总结的,应该目前只有这四种方法的思路,其他方法都是基于此变形的)。要查询的学生表的部分记录方法一:三重循环 思路先取前20页,然后倒序,取倒序后前10条记录,这样就能得到分页所需要的数据,不过顺序反了,之后可以将再倒序回来,也可以不再排序了,直接交给前端排序。还有一种方法也算是属于这种类型的,这里就不放代码出来了,只讲一下思路,就是先查询出前10条记录,然后用not in排除了这10条,再查询。代码实现-- 设置执行时间开始,用来查看性能的 set statistics time on ; -- 分页查询(通用型) select * from (select top pageSize * from (select top (pageIndex*pageSize) * from student order by sNo asc ) -- 其中里面这层,必须指定按照升序排序,省略的话,查询出的结果是错误的。 as temp_sum_student order by sNo desc ) temp_order order by sNo asc -- 分页查询第2页,每页有10条记录 select * from (select top 10 * from (select top 20 * from student order by sNo asc ) -- 其中里面这层,必须指定按照升序排序,省略的话,查询出的结果是错误的。 as temp_sum_student order by sNo desc ) temp_order order by sNo asc ;查询出的结果及时间方法二:利用max(主键)先top前11条行记录,然后利用max(id)得到最大的id,之后再重新再这个表查询前10条,不过要加上条件,where id>max(id)。代码实现set statistics time on; -- 分页查询(通用型) select top pageSize * from student where sNo>= (select max(sNo) from (select top ((pageIndex-1)*pageSize+1) sNo from student order by sNo asc) temp_max_ids) order by sNo; -- 分页查询第2页,每页有10条记录 select top 10 * from student where sNo>= (select max(sNo) from (select top 11 sNo from student order by sNo asc) temp_max_ids) order by sNo;查询出的结果及时间方法三:利用row_number关键字直接利用 row_number() over(order by id) 函数计算出行数,选定相应行数返回即可,不过该关键字只有在SQL server 2005版本以上才有。SQL实现set statistics time on; -- 分页查询(通用型) select top pageSize * from (select row_number() over(order by sno asc) as rownumber,* from student) temp_row where rownumber>((pageIndex-1)*pageSize); set statistics time on; -- 分页查询第2页,每页有10条记录 select top 10 * from (select row_number() over(order by sno asc) as rownumber,* from student) temp_row where rownumber>10;查询出的结果及时间第四种方法:offset /fetch next(2012版本及以上才有)代码实现set statistics time on; -- 分页查询(通用型) select * from student order by sno offset ((@pageIndex-1)*@pageSize) rows fetch next @pageSize rows only; -- 分页查询第2页,每页有10条记录 select * from student order by sno offset 10 rows fetch next 10 rows only ;offset A rows ,将前A条记录舍去,fetch next B rows only ,向后在读取B条数据。结果及运行时间封装的存储过程最后,我封装了一个分页的存储过程,方便大家调用,这样到时候写分页的时候,直接调用这个存储过程就可以了。分页的存储过程create procedure paging_procedure ( @pageIndex int, -- 第几页 @pageSize int -- 每页包含的记录数 ) as begin select top (select @pageSize) * -- 这里注意一下,不能直接把变量放在这里,要用select from (select row_number() over(order by sno) as rownumber,* from student) temp_row where rownumber>(@pageIndex-1)*@pageSize; end -- 到时候直接调用就可以了,执行如下的语句进行调用分页的存储过程 exec paging_procedure @pageIndex=2,@pageSize=10;
-
一、环境准备数据库版本--SQL SERVER 2008R2数据库存放路径:原路径:C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA迁移后路径:D:\SQLSERVER.LDF文件:数据库日志文件.MDF文件:数据库文件登录账户:windwos身份验证:windwos本地账户,具有管理员权限SQL SERVER身份验证:sa账户,具有管理员权限二、设计思路登录SQL SERVER----先备份数据库-----分离需要迁移的数据库-----进入数据库的源路径C盘---------------将数据库两个文件.ldf与.mdf剪切至其他磁盘中----再登录SQL SERVER----附加数据库ps:登录数据库请使用windows身份验证,防止附加数据库后数据库变为只读权限三、操作流程1.登录SQL SERVER,使用SSMS---widows身份验证,本地账户登录2.右键点击一个数据库-----任务------备份数据库。避免突发情况,以防万一!3. 再次右键点击一个数据库-----任务------分离数据库勾选“删除链接”-----勾选“更新统计信息”4.分离后,进入源路径C盘,将两个文件(.ldf与.mdf)剪切至D盘5.再次登录SQL SERVER,继续使用windwos身份验证(因为用SA用户去附加数据库的时候,会让数据库成为只读状态,所以能用windwos身份验证就用本地账户,因为权限的问题)6.右键“数据库”--“附加”“添加”--选择D盘刚才剪切过去的数据库.mdf文件--确定7.完成后刷新就可以查看数据库文件位置变了,且权限,文件任何都完整的迁移过来8.重复操作就可以把所有数据库迁移至其他盘四、如果出现数据库为只读状态因为迁移的时候用的SA用户,所以数据库文件的权限变了,因此变为只读状态,所以刚才一再提醒用windwos本地用户操作!当然也有解决办法:方案一:碰到这中情况一般是使用的sa账户登录的,只要改为Windows身份验证,再附加数据库即可搞定。方案二:使用sa登录SQL Server2008附加数据库,附加之后数据库为只读的,然后点数据库-->“属性”-->“选项”-->“状态”,发现“数据库为只读”这一项为True,改为false。当然,大部分情况下不会成功。会继续报错下图。这种情况下,找到你的数据文件和日志文件,右击“属性”-->“安全”,添加一个“Network Service”账户,然后赋予该账户完全控制的权限即可。再次使用sa登录,附加数据库或者再次将“只读”状态修改即可。
-
SQL Server建表后如何分区?
-
1.进入安装中心:可以参考硬件和软件要求、可以看到一些说明文档2.选择全新安装模式继续安装3.输入产品秘钥:这里使用演示秘钥进行4.在协议中,点击同意,并点击下一步按钮,继续安装5.进入全局规则检查项,这里可能要花费几秒钟,试具体情况而定6.配置更新项,推荐检查更新7.选择安装更新的具体内容8.安装程序文件9.安装规则检查10.安装功能选择11.实例配置,使用默认即可(如果之前安装过,这里需要特别注意下)12.PolyBase配置选择--默认即可13.服务器配置--默认即可14.引擎配置--建议使用混合模式,并记住密码15.Analysis Service配置--推荐使用使用默认16.Reporting Services配置--推荐使用使用默认17.Distributed Replay控制器配置---推荐使用使用默认(添加当前用户)18.Distributed Replay 客户端配置--推荐使用使用默认19.协议授权,接受协议20.最后安装确认页面,会显示所有的安装配置信息21.等待安装进度--这一步会消耗比较长的时间,在虚拟机里面耗时15分钟左右22.继续等待--较耗时23.服务正常安装完毕希望这个教程对大家有所帮助!!晚安!
-
找到想修改的数据库 右键 --> 属性 --> 左侧 选项1.Simple 简单恢复模式,Simple模式的旧称叫”Checkpoint with truncate log“,其实这个名字更形象,在Simple模式下,SQL Server会在每次checkpoint或backup之后自动截断log,也就是丢弃所有的inactive log records,仅保留用于实例启动时自动发生的instance recovery所需的少量log,这样做的好处是log文件非常小,不需要DBA去维护、备份log,但坏处也是显而易见的,就是一旦数据库出现异常,需要恢复时,最多只能恢复到上一次的备份,无法恢复到最近可用状态,因为log丢失了。 Simple模式主要用于非critical的业务,比如开发库和测试库,但是道富这边的SQL Server(即使是生产库)大都采用Simple模式,是因为这边的SQL Server大都用于非critical的业务(critical的数据库大都采用Oracle和DB2),可以忍受少于1天的数据丢失(我们的job每天都会定时备份全库)。如果需要压缩数据库日志(Shrink语句),将数据库模式切换到简单恢复模式后压缩率才是最高的,如果你的数据库在完整恢复模式或大容量日志回复模式下采用日志压缩,压缩后的日志大小并不会很理想。2.Full 完整恢复模式,和Simple模式相反,Full模式的旧称叫”Checkpoint without truncate log“,也就是SQL Server不主动截断log,只有备份log之后,才可以截断log,否则log文件会一直增大,直到撑爆硬盘,因此需要部署一个job定时备份log。Full的好处是可以做point-in-time恢复,最大限度的保证数据不丢失,一般用于critical的业务环境里。缺点就是DBA需要维护log,增加人员成本(其实也就是多了定时备份log这项工作而已)。3.Bulk-logged 大容量日志恢复Bulk-logged模式和full模式类似,唯一的不同是针对以下Bulk操作,会产生尽量少的log: 1) Bulk load operations (bcp and BULK INSERT). 2) SELECT INTO. 3) Create/drop/rebuild index 众所周知,通常bulk操作会产生大量的log,对SQL Server的性能有较大影响,bulk-logged模式的作用就在于降低这种性能影响,并防止log文件过分增长,但是它的问题是无法point-in-time恢复到包含bulk-logged record的这段时间。 Bulk-logged模式的最佳实践方案是在做bulk操作之前切换到bulk-logged,在bulk操作结束之后马上切换回full模式。补存SQL Server 2008 支持三种恢复模式,即简单恢复模式、完整恢复模式和大容量日志恢复模式。1、简单恢复:无日志备份。自动回收日志空间以减少空间需求,实际上不再需要管理事务日志空间。 最新备份之后的更改不受保护。在发生灾难时,这些更改必须重做。 只能恢复到备份的结尾。2、完整恢复:需要日志备份。数据文件丢失或损坏不会导致丢失工作。可以恢复到任意时点(例如应用程序或用户错误之前)。3、大容量日志恢复:需要日志备份。是完整恢复模式的附加模式,允许执行高性能的大容量复制操作。通过使用最小方式记录大多数大容量操作,减少日志空间使用量。如果在最新日志备份后发生日志损坏或执行大容量日志记录操作,则必须重做自该上次备份之后所做的更改。否则不丢失任何工作。可以恢复到任何备份的结尾。不支持时点恢复。其中,如果符合下列任一要求,则使用完整恢复模式: 您必须能够恢复所有数据。 数据库包含多个文件组,并且您希望逐段还原读/写辅助文件组(以及可选地还原只读文件组)。 •您必须能够恢复到故障点。 • 您希望可以还原单个页。 • 您愿意承担事务日志备份的管理开销。因此还原单个数据页是完整恢复模式功能。
-
一,判断文件是否存在 存储过程sys.xp_fileexist 用于判断文件是否存在,参数是文件(file)的路径或目录的路径:exec master.sys.xp_fileexist 'D:\test.txt'该存储过程返回的结果集有一行数据,三个字段,如下图: 二,创建子目录存储过程 sys.xp_create_subdir 用于创建子目录,参数是子目录的路径:exec master.sys.xp_create_subdir 'D:\test'执行存储过程,系统返回消息:Command(s) completed successfully,说明子目录创建成功。三,查看子目录结构存储过程sys.xp_dirtree 用于显示当前目录的子目录,该存储过程有三个参数:directory:第一个参数是要查询的目录;depth :第二个参数是要显示的子目录的深度,默认值是0,表示显示所有的子目录;file :第三个参数是bool类型,指定是否显示子目录中的文件(file),默认值是0,表示不显示任何文件,只显示子目录(directory);exec master.sys.xp_dirtree 'D:\data'该存储过程返回的字段有子目录名称和相对深度,返回的结果中并没有显示子目录的父子关系:四,删除文件存储过程 sys.xp_delete_file 用于删除文件,该存储过程有5个参数:第一个参数是文件类型(File Type),有效值是0和1,0是指备份文件,1是指报表文件;第二个参数是目录路径(Folder Path), 目录中的文件会被删除,目录路径必须以“\”结尾;第三个参数是文件的扩展名(File Extension),常用的扩展名是'BAK' 或'TRN';第四个参数是Date,早于该日期创建的文件将会被删除;第五个参数是子目录(Subfolder),bool类型,0是指忽略子目录,1是指将会删除子目录中的文件;该存储过程并不可以删除所有的文件,系统限制它只能删除特定类型的文件。declare @Date datetime = dateadd(day,-30,getdate()) exec master.sys.xp_delete_file 0,'D:\test\','bak',@Date,0五,查看磁盘驱动的空闲空间存储过程 sys.xp_fixeddrives用于查看磁盘驱动器剩余(free)的空间exec sys.xp_fixeddrives六,执行DOS命令操作文件存储过程sys.xp_cmdshell 用于执行DOS命令,该功能对应SQL Server系统的xp_cmdshell高级选项,默认情况下,该选项是禁用的,执行该存储过程,系统会抛出错误消息:SQL Server blocked access to procedure 'sys.xp_cmdshell' of component 'xp_cmdshell' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'xp_cmdshell' by using sp_configure. For more information about enabling 'xp_cmdshell', search for 'xp_cmdshell' in SQL Server Books Online.因此,在执行该存储过程之前,必须启用xp_cmdshell选项,由于启用该选项有潜在的风险,建议用户在执行代码之后,禁用该选项。1,启用/禁用xp_cmdshell选项xp_cmdshell选项属于系统的高级选项,执行以下代码,允许用户修改高级选项:-- To allow advanced options to be changed. exec sp_configure 'show advanced options', 1; go -- To update the currently configured value for advanced options. reconfigure; go 使用以下代码启用xp_cmdshell选项:-- To enable the feature. exec sp_configure 'xp_cmdshell', 1; go -- To update the currently configured value for this feature. reconfigure; go使用以下代码禁用xp_cmdshell选项:-- To disable the feature. exec sp_configure 'xp_cmdshell', 0; go -- To update the currently configured value for this feature. reconfigure; go2,常用的DOS命令该存储过程使得用户可以通过TSQL命令执行DOS命令,exec sys.xp_cmdshell 'command_string'2.1 建立新文件或增加文件内容格式:ECHO 文件内容>file_name exec master.dbo.xp_cmdshell 'echo abc > D:\share\test.txt'2.2 查看文件内容格式:TYPE file_nameexec master.dbo.xp_cmdshell 'type D:\share\test.txt'2.3 复制文件格式: COPY file_name new_folderexec master.dbo.xp_cmdshell 'copy D:\test\test.txt D:\share\'2.4 显示目录格式:DIR folderexec master.dbo.xp_cmdshell 'dir D:\share\'2.5 创建目录格式:MD folder_nameexec master.dbo.xp_cmdshell 'md D:\share\test\'2.6 删除目录格式:RD folderexec master.dbo.xp_cmdshell 'rd D:\share\test'2.7 删除文件格式:DEL file_nameexec master.dbo.xp_cmdshell 'del D:\share\test.txt'2.8 重命名文件格式:REN [盘符:][路径]〈旧文件名〉〈新文件名〉exec master.dbo.xp_cmdshell 'ren D:\test\test.txt new.txt'2.9 移动文件格式:MOVE file_name new_folderexec master.dbo.xp_cmdshell 'move D:\test\new.txt D:\share\'2.10 切换目录格式:CD[盘符:][路径名][子目录名]
-
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.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 ; GO 2、删除视图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数据类型
-
前言项目中一般分测试环境(QAS),生产环境(PRD),当我们的项目经历了一次周期跨度较长的更新后,当我们发布到生产环境时,首要的任务是将新增的表,字段更新到生产数据库。很多时候,当我们发布更新的时候,已经很难记得做了哪些变更。当然有的人会说,1.EF Code First 有history记录,这是一种办法,可靠么?不可靠。相信即便是用Code First,直接改数据库的肯定不止我一个。2.查看实体类变更记录,这也是一个办法。那如果用的DB First的呢?当然也可以看,就是很麻烦。3.开发过程中,对数据库的变更记下来。这么做过的肯定也不止我一个。手动狗头中午的时候,就想着另外一个项目下个月要更新,改了N多的东西,到时候数据库咋更新呢。就想着写个工具比较两个版本数据库,表名称,字段,字段类型的区别。说干就干(本来想着用EF,DBContext应该可以实现,无奈学艺不精,最终还是回到了ADO.Net)。控制台应用程序,目前只能对比新增,修改(SQl Server)。using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using Microsoft.EntityFrameworkCore; namespace EFGetTable { class Program { static void Main(string[] args) { string prdconnectionstring = "Data Source=localhost;initial catalog=ttPRD;user id=sa;password=password;MultipleActiveResultSets=True"; var prd = GetTableNames(prdconnectionstring); string qasconnectionstring = "Data Source=localhost;initial catalog=ttqas;user id=sa;password=password;MultipleActiveResultSets=True"; var qas = GetTableNames(qasconnectionstring); CompareTable(prd, qas); } public static List<TableInfo> GetTableNames(string connectionstr) { var tableresult = new List<TableInfo>(); string sqlTableName = "Select * From Information_Schema.Tables"; using (SqlConnection connection = new SqlConnection(connectionstr)) { using (SqlCommand cmd = new SqlCommand(sqlTableName, connection)) { try { connection.Open(); SqlDataReader dr = cmd.ExecuteReader();// while (dr.Read()) { // 表名 TableInfo table = new TableInfo(); table.TableName = dr["Table_Name"].ToString(); table.columns.AddRange(GetColumnNamesByTable(dr["Table_Name"].ToString(), connection)); tableresult.Add(table); } connection.Close(); } catch (System.Data.SqlClient.SqlException e) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine(e.Message); connection.Close(); } } return tableresult; } } public static List<CloumnInfo> GetColumnNamesByTable(string tableName, SqlConnection connection) { var Columnresults = new List<CloumnInfo>(); string sqlcolum = $"Select * From Information_Schema.Columns t Where t.Table_Name =\'{tableName}\'"; using (SqlCommand cmd = new SqlCommand(sqlcolum, connection)) { SqlDataReader dr = cmd.ExecuteReader();// while (dr.Read()) { // 表名 CloumnInfo column = new CloumnInfo(); column.CloumnName = dr["Column_name"].ToString(); column.DateType = dr["DATA_TYPE"].ToString() + dr["CHARACTER_MAXIMUM_LENGTH"].ToString(); Columnresults.Add(column); } return Columnresults; } } public static void CompareTable(List<TableInfo> prd, List<TableInfo> qas) { foreach (var p in qas) { var tablequery = prd.AsQueryable().Where(t => t.TableName.Equals(p.TableName)); if (!tablequery.Any()) { Console.WriteLine($"New Created Table {p.TableName}"); continue; } else { var querytable = tablequery.FirstOrDefault(); p.columns.ForEach(c => { var Cloumnquery = querytable.columns.Select(cc => cc.CloumnName).Contains(c.CloumnName); if (!Cloumnquery) { Console.WriteLine($"New add cloumn: {c.CloumnName} on Table {p.TableName}"); } else { var querycloumn = querytable.columns.Where(qt => qt.CloumnName.Equals(c.CloumnName)).FirstOrDefault(); if (!querycloumn.DateType.Equals(c.DateType)) { Console.WriteLine($"DateType Different: cloumn: {c.CloumnName} , {querycloumn.DateType}==>{c.DateType} on Table {p.TableName}"); } } }); } } } } public class TableInfo { public TableInfo() { columns = new List<CloumnInfo>(); } public string TableName { get; set; } public List<CloumnInfo> columns { get; set; } } public class CloumnInfo { public string CloumnName { get; set; } public string DateType { get; set; } } }测试结果学习本就是解决问题的过程,在问题中成长。加油!
-
最近因为要在vs code上连接到sql server数据库,第一次尝试,之前用 java的时候使用jdbc连接过数据库,感觉用vs code连接数据库步骤要简单一些,网上写的博客也不是特别多,就顺便把我的步骤记录下来。第一步,安装mssql扩展先在vs code的扩展里面找到SQL Server(mssql)扩展,并下载安装即可。下载好之后会出现SQL SERVER的版块。(请忽略已经连接好的数据库)第二步,连接到 SQL Server官方文档给出的连接步骤请按照以下步骤创建连接配置文件并连接到 SQL Server。按“Ctrl”+“Shift”+“P”或“F1”打开“命令面板”。键入 sql 以显示 mssql 命令,或键入 sqlcon,然后从下拉列表中选择“MS SQL:连接”。也可直接在扩展里进行连接官方的文字表述有点晦涩,不太好理解的话,可以按照我的操作,如图,点击connection右边的+号即可新建一个连接,会弹出连接的属性配置框。第三步,配置连接属性在弹出的属性配置依此按要连接的数据库情况填写即可服务器名称或 ADO 连接字符串指定 SQL Server 实例名称这里如果是连接本地的数据库的话,直接填localhost即可,其他的可参考引用。使用 localhost 连接到本地计算机上的 SQL Server 实例。 如果要连接到远程 SQL Server,请输入目标 SQLServer 的名称,或它的 IP 地址。 若要连接到 SQL Server 容器,请指定容器主机的 IP 地址。如果需要指定端口,请使用逗号将其与名称分开。 例如,对于侦听端口 1401 的服务器,请输入 ,1401。“数据库名称”(可选)这里可填要使用的数据库,也可不填即为默认数据库。 若要连接到默认数据库,请不要在此处指定数据库名称。(这里我开始填写的时候填错了,后面连接的时候报错了)我这里选择的是数据库TEST。这里我开始因为理解错了数据库名称填错了,遇到了如下的错误。(mssql: Error: Unable to connect using the connection information provided. Retry profile creation?),我在博客上看到有和我遇到一样问题的,把错误提示发出来,方便检索。只要检查每一步的信息无误就不会报这个错误了。3.身份验证类型选择“集成”或“SQL 登录”。或者,可以在此处输入数据库的 ADO 连接字符串。 这里选择第一个SQL Login就好了。4.用户名如果选择了“SQL 登录”,则输入拥有访问服务器上数据库权限的用户名。这里填数据库的用户名就好,如我的:sa5.密码输入指定用户的密码。6.保存密码按“Enter”选择“是”并保存密码。 选择“否”,系统将在每次使用连接配置文件时提示输入密码。7.配置文件名称”(可选)键入连接配置文件的名称,例如 localhost 配置文件。8.配置完成,到这里就可以在vs code里对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 整理完毕后会自动删除这个表。如果不喜欢的话的可以用一个临时的表解决。
上滑加载中
推荐直播
-
华为AI技术发展与挑战:集成需求分析的实战指南
2024/11/26 周二 18:20-20:20
Alex 华为云学堂技术讲师
本期直播将综合讨论华为AI技术的发展现状,技术挑战,并深入探讨华为AI应用开发过程中的需求分析过程,从理论到实践帮助开发者快速掌握华为AI应用集成需求的框架和方法。
去报名 -
华为云DataArts+DWS助力企业数据治理一站式解决方案及应用实践
2024/11/27 周三 16:30-18:00
Walter.chi 华为云数据治理DTSE技术布道师
想知道数据治理项目中,数据主题域如何合理划分?数据标准及主数据标准如何制定?数仓分层模型如何合理规划?华为云DataArts+DWS助力企业数据治理项目一站式解决方案和应用实践告诉您答案!本期将从数据趋势、数据治理方案、数据治理规划及落地,案例分享四个方面来助力企业数据治理项目合理咨询规划及顺利实施。
去报名
热门标签