sql server相关
sql server nolock
在sqlserver 中with(nolock)详解
处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAST 。有关 NOLOCK 和 READPAST的一些技术知识点:
对于非银行等严格要求事务的行业,搜索记录中出现或者不出现某条记录,都是在可容忍范围内,所以碰到死锁,应该首先考虑,我们业务逻辑是否能容忍出现或者不出现某些记录,而不是寻求对双方都加锁条件下如何解锁的问题。
NOLOCK 和 READPAST 都是处理查询、插入、删除等操作时候,如何应对锁住的数据记录。但是这时候一定要注意NOLOCK 和 READPAST的局限性,确认你的业务逻辑可以容忍这些记录的出现或者不出现:
简单来说:
NOLOCK 可能把没有提交事务的数据也显示出来.
READPAST 会把被锁住的行不显示出来
不使用 NOLOCK 和 READPAST ,在 Select 操作时候则有可能报错误:事务(进程 ID **)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。
下面就来演示这个情况。
为了演示两个事务死锁的情况,我们下面的测试都需要在SQL Server Management Studio中打开两个查询窗口。保证事务不被干扰。
演示一 没有提交的事务,NOLOCK 和 READPAST处理的策略:
查询窗口一请执行如下脚本:
CREATE TABLE t1 (c1 int IDENTITY(1,1), c2 int)
go
BEGIN TRANSACTION
insert t1(c2) values(1)
在查询窗口一执行后,查询窗口二执行如下脚本:
select count(*) from t1 WITH(NOLOCK)
select count(*) from t1 WITH(READPAST)
结果与分析:
查询窗口二依次显示统计结果为: 1、0
查询窗口一的命令没有提交事务,所以 READPAST 不会计算没有提交事务的这一条记录,这一条被锁住了,READPAST 看不到;而NOLOCK则可以看到被锁住的这一条记录。
如果这时候我们在查询窗口二中执行:
select count(*) from t1 就会看到这个执行很久不能执行完毕,因为这个查询遇到了一个死锁。
清除掉这个测试环境,需要在查询窗口一中再执行如下语句:
ROLLBACK TRANSACTION
drop table t1
演示二:对被锁住的记录,NOLOCK 和 READPAST处理的策略
这个演示同样需要两个查询窗口。
请在查询窗口一中执行如下语句:
CREATE TABLE t2 (UserID int , NickName nvarchar(50))
go
insert t2(UserID,NickName) values(1,'郭红俊')
insert t2(UserID,NickName) values(2,'蝈蝈俊')
go
BEGIN TRANSACTION
update t2 set NickName = '蝈蝈俊.net' where UserID = 2
请在查询窗口二中执行如下脚本:
select * from t2 WITH(NOLOCK) where UserID = 2
select * from t2 WITH(READPAST) where UserID = 2
结果与分析:
查询窗口二中, NOLOCK 对应的查询结果中我们看到了修改后的记录,READPAST对应的查询结果中我们没有看到任何一条记录。 这种情况下就可能发生脏读
WITH (NOLOCK)
缺点:
1.会产生脏读
2.只适用与select查询语句
优点:
1.有些文件说,加了WITH (NOLOCK)的SQL查询效率可以增加33%。
2.可以用于inner join 语句
脏读: 一个用户对一个资源做了修改,此时另外一个用户正好读取了这条被修改的记录,然后,第一个用户放弃修改,数据回到修改之前,这两个不同的结果就是脏读。
详细内容:
要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑。其实除了index的建立之外,当我们在下SQL Command时,在语法中加一段WITH (NOLOCK)可以改善在线大量查询的环境中数据集被LOCK的现象藉此改善查询的效能。
不过有一点千万要注意的就是,WITH (NOLOCK)的SQL SELECT有可能会造成Dirty Read(脏读)。
例如:
SELECT COUNT(UserID)
FROM EMPLOYEE WITH (NOLOCK)
JOIN WORKING_GROUP WITH (NOLOCK)
ON EMPLOYEE.UserID = WORKING_GROUP.UserID
除了简单的SELECT之外,有JOIN的SELECT语法也是可以使用的。但是DELETE、INSERT、UPDATE这些需要transaction的指令就不行了…
有些文件说,加了WITH (NOLOCK)的SQL查询效率可以增加33%。
加了WITH (NOLOCK)即告诉SQL Server,我们的这段SELECT指令无需去考虑目前table的transaction lock状态,因此效能上会有明显的提升,而且数据库系统的Lock现象会有明显的减少(包含Dead Lock)。
有 一点要特别注意,因为WITH (NOLOCK)不考虑目前table的transaction lock,因此当有某些资料正处于多个phase交易(例如跨多个table的transaction交易-->如提款系统),WITH (NOLOCK)会让目前处理交易process的数据被忽略…
讲白话一点,也就是说当使用NoLock时,它允许阅读那些已经修改但是还没有交易完成的数据。因此如果有需要考虑transaction事务数据的实时完整性时,使用WITH (NOLOCK)就要好好考虑一下。
如果不需考虑transaction,WITH (NOLOCK)或许是个好用的参考。
注1:WITH ( < table_hint > )
指定由查询优化器使用的表扫描、一或多个索引,
或由查询优化器利用此数据表以及为此语句使用锁定模式。
注2:WITH (NOLOCK)相当于READ UNCOMMITTED
主键自增列重新设置种子值
CHECKIDENT ([tabelcheckindent], RESEED, 51) DBCC CHECKIDENT ('table_name', RESEED,new_reseed_value)
SQLServer中GO的注意点
如果只是执行一条语句,有没有GO都一样
如果多条语句之间用GO分隔开就不一样了
每个被GO分隔的语句都是一个单独的事务,一个语句执行失败不会影响其它语句执行。
例如:
首先同时执行下边的语句
select * from sysobjects where id=a
select getdate()
你会发现会报错,并且不会显示任何结果集
而你再执行
select * from sysobjects where id=a
go
select getdate()
go
你会发现尽管同样会报错,但结果集中包含select getdate()的结果。
SQL Server中row_number的用法
ROW_NUMBER()函数将针对SELECT语句返回的每一行,从1开始编号,赋予其连续的编号。在查询时应用了一个排序标准后,只有通过编号才能够保证其顺序是一致的,当使用ROW_NUMBER函数时,也需要专门一列用于预先排序以便于进行编号。
ROW_NUMBER()
说明:返回结果集分区内行的序列号,每个分区的第一行从1开始。
语法:ROW_NUMBER () OVER ([ <partition_by_clause> ] <order_by_clause>) 。
备注:ORDER BY 子句可确定在特定分区中为行分配唯一 ROW_NUMBER 的顺序。
参数:<partition_by_clause> :将 FROM 子句生成的结果集划入应用了 ROW_NUMBER 函数的分区。
<order_by_clause>:确定将 ROW_NUMBER 值分配给分区中的行的顺序。
返回类型:bigint 。
ROW_NUMBER()常用的几种情况
1.使用row_number()函数进行编号,如
select email,customerID, ROW_NUMBER() over(order by psd) as rows from QT_Customer
原理:先按psd进行排序,排序完后,给每条数据进行编号。
2.在订单中按价格的升序进行排序,并给每条记录进行排序代码如下:
select DID,customerID,totalPrice,ROW_NUMBER() over(order by totalPrice) as rows from OP_Order
3.统计出每一个各户的所有订单并按每一个客户下的订单的金额 升序排序,同时给每一个客户的订单进行编号。这样就知道每个客户下几单了。
如图:
代码如下:
select ROW_NUMBER() over(partition by customerID order by totalPrice) as rows,customerID,totalPrice, DID from OP_Order
4.统计每一个客户最近下的订单是第几次下的订单。
删除日志:
收缩日志文件大小(单位是M)
DBCC SHRINKFILE (N'RYRecordDB_Log' , 11, TRUNCATEONLY)
https://www.cnblogs.com/ljhdo/p/5748922.html
sql DEFAULT 和 NULL 不允许作为显式标识值
SQL INSERT INTO错误: DEFAULT 和 NULL 不允许作为显式标识值
错误原因:插入值时自增列插入了值,我的表主键设置为自增列,当插入数据时不允许将数值插入自增列。
如下:
insert into table(id,name,address) ---错误:id为自增列
values(1,'lipang','shandong')
改为:
insert into table(name,address) ---正确
values('lipang','shandong')
select @@identify as id ----返回当前插入数据的标识(或主键)
sql server: identity
列名 数据类型 约束 identity(m,n)
m表示的是初始值,n表示的是每次自动增加的值
如果m和n的值都没有指定,默认为(1,1)
sql server 2012导出结构和数据
数据库名-->右键 任务-->生存脚本
在2012版本中将要编写的脚本数据类型改为架构和数据,就可以把表结构和表数据一起导出了
[MSSQL]帐户当前被锁定,所以用户 sa 登录失败。系统管理员无法将该帐户解锁 解决方法
帐户当前被锁定,所以用户 ‘sa’ 登录失败。系统管理员无法将该帐户解锁’解决方法
如果短时间内不停连接,就会被SQL SERVER误认为是这是攻击,会将此账号锁定。
要用windows身份验证登录,在查询分析器里输入:
ALTER LOGIN sa ENABLE ;
GO
ALTER LOGIN sa WITH PASSWORD = 'password' unlock, check_policy = off,
check_expiration = off ;
GO
- 1
- 2
- 3
- 4
- 5
其中password中修改成sa的登陆密码。
sqlserver
将某种数据类型的表达式显式转换为另一种数据类型。CAST 和 CONVERT 提供相似的功能。
语法
使用 CAST:
CAST ( expression AS data_type )
使用 CONVERT:
CONVERT (data_type[(length)], expression [, style])
参数
expression
是任何有效的 Microsoft® SQL Server™ 表达式。有关更多信息,请参见表达式。
data_type
目标系统所提供的数据类型,包括 bigint 和 sql_variant。不能使用用户定义的数据类型。有关可用的数据类型的更多信息,请参见数据类型。
length
nchar、nvarchar、char、varchar、binary 或 varbinary 数据类型的可选参数。
sqlserver 作业
首先SqlServer的作业(job)是定期执行某个语句或者存储过程的任务,类似于windows里面的执行计划。
作业是在SqlServer代理里面,如下面的截图:
作业是依赖于sql server agent(代理的),一定要开启这个。
以使用企业管理器创建作业,但此处讲的是用SQL语句。 创建作业
- 执行 sp_add_job 创建作业。
- 执行 sp_add_jobstep 创建一个或多个作业步骤。
- 执行 sp_add_jobschedule 创建作业调度。
说明 建议在执行完 sp_add_jobstep 后再执行 sp_add_jobserver,以便最高效率地将作业更改传送给所有涉及的服务器。
因为本地 SQL Server 代理缓存本地作业,所以任何修改都会隐性地强制 SQL Server 代理重新缓存该作业。因为直到调用 sp_add_jobserver 时,SQL Server 代理才缓存作业,所以最后调用 sp_add_jobserver 更为高效。
1、IF ELSE
不能用在SELECT中,只能是块,比如:
IF ...
BEGIN
...
END
ELSE (注意这里没有ELSE IF,要实现只能在下面的块中用IF判断)
BEGIN
...
END
下表列出 SET 与 SELECT 的区别。请特别注意红色部分。
set | select | |
同时对多个变量同时赋值 | 不支持 | 支持 |
表达式返回多个值时 | 出错 | 将返回的最后一个值赋给变量 |
表达式未返回值 | 变量被赋null值 | 变量保持原值 |
SELECT @Index=COUNT(id) FROM #tmpGold
SELECT INTO……
这种方式的语句可以在Table2不存在的时候进行表数据复制,编译器会根据Table1的表结构自动创建Table2,Table2和Table1的结构基本上是一致的,但是如果已经存在Table2,则编译器会报错.
这种方式的语句在Oracle中和MS SqlServer中是有点差别的,,如下:
语句格式:
Oracle:Create Table2 as Select column1,column2……From Table1 或 Create Table2 as Select * From Table1
MS SqlServer:Select column1,column2…… into Table2 From Table1 或 Select * into Table2 From Table1
例:
insert into 表
. 使用insert into,需要先手动创建临时表
1.1 保存从select语句中返回的结果集
create table test_getdate(c1 datetime)
insert into test_getdate select GETDATE()
select * from test_getdate
SQL Server:SELECT INTO 和 INSERT INTO SELECT
做数据库开发的过程中难免会遇到有表数据备份的,而SELECT INTO……和INSERT INTO SELECT…… 这两种语句就是用来进行表数据复制,下面简单的介绍下:
1、INSERT INTO SELECT
语句格式:Insert Into Table2(column1,column2……) Select value1,value2,value3,value4 From Table1 或
Insert Into Table2 Select * From Table1
说明:这种方式的表复制必须要求Table2是事先创建好的
例:
--1.创建表
create TABLE Table1
(
a varchar(10),
b varchar(10),
c varchar(10)
) ; create TABLE Table2
(
a varchar(10),
c varchar(10),
d varchar(10)
);
commit;
--2.创建测试数据
Insert into Table1 values('赵','asds','90');
Insert into Table1 values('钱','asds','100');
Insert into Table1 values('孙','asds','80');
Insert into Table1 values('李','asds',null);
commit;
--3.复制table1数据到table2中
Insert into Table2(a, c, d) select a,b,c from Table1;
commit;
--或,此种方式必须要求table2和table1的列数相等,而且类型兼容
Insert into Table2 select * from table1;
commit;
以上这些sql在oracle和MS SqlServer中的语法是一样的,可以通用.
2、SELECT INTO……
这种方式的语句可以在Table2不存在的时候进行表数据复制,编译器会根据Table1的表结构自动创建Table2,Table2和Table1的结构基本上是一致的,但是如果已经存在Table2,则编译器会报错.
这种方式的语句在Oracle中和MS SqlServer中是有点差别的,,如下:
语句格式:
Oracle:Create Table2 as Select column1,column2……From Table1 或 Create Table2 as Select * From Table1
MS SqlServer:Select column1,column2…… into Table2 From Table1 或 Select * into Table2 From Table1
例:
--Oracle
--1.创建表
create TABLE Table1
(
a varchar(10),
b varchar(10),
c varchar(10)
) ; commit;
--2.创建测试数据
Insert into Table1 values('赵','asds','90');
Insert into Table1 values('钱','asds','100');
Insert into Table1 values('孙','asds','80');
Insert into Table1 values('李','asds',null);
commit;
--3.复制table1数据到table2中
Create Table Table2 as select a,b,c From table1;
Commit;
--或(这两种方式的sql只能应用一次)
Create table table2 as select * From Table1;
Commit;
--删除表
drop table table1;
drop table table2;
commit;
--MS SqlServer
--1.创建表
create TABLE Table1
(
a varchar(10),
b varchar(10),
c varchar(10)
) ; commit;
--2.创建测试数据
Insert into Table1 values('赵','asds','90');
Insert into Table1 values('钱','asds','100');
Insert into Table1 values('孙','asds','80');
Insert into Table1 values('李','asds',null);
commit;
--3.复制table1数据到table2中
Select a,b,c into Table2 From table1;
Commit;
--或(这两种方式的sql只能应用一次)
Select * into table2 From Table1;
Commit;
--删除表
drop table table1;
drop table table2;
commit
变量的声明:
声明变量时必须在变量前加@符号
DECLARE @I INT
变量的赋值:
变量赋值时变量前必须加set
SET @I = 30
isnull:
SQL Serve中的isnull()函数:
isnull(value1,value2)
1、value1与value2的数据类型必须一致。
2、如果value1的值不为null,结果返回value1。
3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。
如果在select中就是isnull可以判断是否是null,如果是给个默认值,isnull("字段名","设定默认的数据")
is NULL
Address IS NOT NULL
-- 查询用户
SELECT @UserID=UserID,@InsurePass=InsurePass, @LogonPass=LogonPass, @Nullity=Nullity, @StunDown=StunDown
FROM AccountsInfo(NOLOCK) WHERE UserID=@dwUserID
-- 查询用户
IF @UserID IS NULL
BEGIN
SET @strErrorDescribe=N'您的帐号不存在或者密码输入有误,请查证后再次尝试!'
RETURN 1
END
is null用来设置默认值
IF @ScoreAmount IS NULL SET @ScoreAmount=0
不要把数值跟null比较,这样也会为null.
执行存储过程:
USE [RYAccountsDB]
GO
DECLARE @return_value int,
@strErrorDescribe nvarchar(127)
EXEC @return_value = [dbo].[GSP_GR_TASKLOAD]
@dwUserID = xxxx,
@strErrorDescribe = @strErrorDescribe OUTPUT
SELECT @strErrorDescribe as N'@strErrorDescribe'
SELECT 'Return Value' = @return_value
GO
当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'xxx' 中的标识列插入显式值。
set identity_insert 表名 ON -- 允许将显式值插入表的标识列中 Sql server事务
ALTER PROCEDURE [dbo].[Proc_Test_commit1]
@result int output, --成功 1; 失败 0
@message nvarchar(20) output
AS
BEGIN
SET NOCOUNT ON begin try
begin tran yy
insert into Test_Commit (b) values (3) insert into Test_Commit (a,b) values (1,3)
set @result=1
commit tran yy
end try
begin catch
set @message= ERROR_MESSAGE()
set @result=0
rollback tran yy
--insert into SYS_Proc_Message([Message]) values(ERROR_MESSAGE())
print ERROR_MESSAGE()
end catch SET NOCOUNT OFF; END
- begin try
- --SQL
- end try
- begin catch
- --sql (处理出错动作)
- end catch
Sql server begin try end try ,begin catch,endcatch 异常捕获机制: 我们将可能会出错的sql 写在begin try...end try 之间,若出错,刚程序就跳到紧接着的begin try...end try 的beign catch...end catch中,执行beign catch...end catch错误处理SQL。try..catch 是可以嵌套的。在begin catch ...end catch中我们可以利用系统提供的下面四个函数得到出错信息:
error_number 返回错误代码
error_serverity 返回错误的严重级别
error_state 返回错误状态代码
error_message 返回完整的错误信息
上面的四个函数在同一个begin catch ...end catch可以在多次使用,值是不变的。
下面是一个简单的小例子。
- begin try
- --SQL
- end try
- begin catch
- --sql (处理出错动作)
- end catch
结果:
-----
error_number error_message error_state error_severity
8134 遇到以零作除数错误。 1 16
-------------------------------------------------------
不受 TRY…CATCH 构造影响的错误
TRY…CATCH 构造在下列情况下不捕获错误:
严重级别为 10 或更低的警告或信息性消息。
严重级别为 20 或更高且终止会话的 SQL Server 数据库引擎任务处理的错误。 如果所发生错误的严重级别为 20 或更高,而数据库连接未中断,则 TRY…CATCH 将处理该错误。
需要关注的消息,如客户端中断请求或客户端连接中断。
sqlserver开启事务并打印错误信息
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION train;
COMMIT TRANSACTION train;
END TRY
BEGIN CATCH ;
PRINT ERROR_MESSAGE()
ROLLBACK TRANSACTION train;
END CATCH;
END;
---------------------
在SQL Server 2018 Management Studio中修改表字段顺序
有时我们可能需要为一个已存在的数据库表添加字段,并且想让这个字段默认排的靠前一些,这时就需要为表字段重新进行排序,默认情况下在Management Studio中调整顺序并保存时会提示“不允许保存更改。您所做的更改要求删除并重新创建以下表。您对无法重新创建的标进行了更改或者启用了“阻止保存要求重新创建表的更改”选项”,这是因为有些对表的修改要求重新创建表,而 SQL Server 默认阻止这样的修改,所以保存不下来。
可以通过取消选项“阻止保存要求重新创建表的更改”即可:
在 Microsoft SQL Server Management Studio 中:
1. 工具->选项->Designers->表设计器和数据库设计器->将“阻止保存要求重新创建表的更改”的选项的勾去掉。
2. 右键单击你要更改的数据表,点选“设计”,然后在表设计器中用鼠标拖动各列的位置,最后保存即可。
SCOPE_IDENTITY的用法
SCOPE_IDENTITY 和 @@IDENTITY 的作用都是取得返回在当前会话中的任何表内所生成的最后一个标识值,简单的说就是在执行一条插入语句之后使用@@IDENTITY的全局变量,取得插入记录的ID号但是有个问题就是,@@IDENTITY是全局的,所以在他的功能会体现在所有作用域,一个操作,一个触发器,一个存储过程叫做一个作用域,这时候如果出现多个作用域的情况的时候,@@IDENTITY所取得的ID号就是最后一个作用域产生的结果。这时候我们要使用SCOPE_IDENTITY方法来作了。SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。
使用方法:select SCOPE_IDENTITY() as ID from [table]select @@IDENTITY as ID from [table]
实例:
sql="SET NOCOUNT ON;insert into [Table](Item) values('"&Item&"')"sql=sql&";select @@IDENTITY as ID from [Table];SET NOCOUNT OFF;" 在插入某些自增表的时候,需要将其打开:
语法:SET IDENTITY_INSERT TableName ON
存储过程:
CREATE PROCEDURE [dbo].[sp_User](@F_Name int) AS
begin tran Insertinto_T_User
Insert into dbo.T_User(F_Name) values(@F_Name)
Select SCOPE_IDENTITY()
--
变量声明带默认值:
变量的声明:
声明变量时必须在变量前加@符号
DECLARE @I INT
变量的赋值:
变量赋值时变量前必须加set
SET @I = 30
声明多个变量:
DECLARE @s varchar(10),@a INT
还可以这样:
DECLARE @xxx DECIMAL(18,2)=0,@yyy DECIMAL(18,2)=0
这样声明就不用 if xx isnull 判断了。
SQL SERVER中正确的下划线总是出现红色波浪线的办法:
新加了表,但是写存储过程总是提示红色:
Microsoft sql server management studio 里点击“编辑”——“IntelliSense”——“刷新本地缓存” 就会发现红色波浪线没了(前提是你的代码没错)。
原因解释:这个表的字段列表,让你选择。但是,当你新建了一个对象的时候, 例如表, 或者你的那个例子,是新建存储过程abc这个时候,数据库那里,已经有存储过程abc 了。但是客户端的缓存里面, 并没有 存储过程 abc 的信息。 因为内存里面的信息,没有更新。因此,在客户端那里。输入EXEC abc,abc下有红线。将 客户端关闭后,重新打开, 由于客户端 重新加载了 数据库的基础信息。知道了 当前数据库里面,有 一个名字叫 abc 的存储过程因此,就不出红线了。
SQl SERVER复制表的时候要注意,也会复制该表的trigger触发器,如果不需要移除。
SQL Server 中输出字符串并换行的方法
在SQL Server中想输出字符串并换行的方法,示例如下:
print '中国'+char(13)+char(10)+'人民'
declare @a varchar(20)
set @a= 'aaa '+char(13)+char(10)+ 'bbbb '
print @a
---------------------
首先在字符串的前后加单引号;
字符串中的变量以'''+@para+'''在字符串中表示;
若在执行时存在类型转换错误,则应用相应的类型转换函数,对变量进行类型转换(如cast()函数)。
如:
在将 varchar 值 '@xxx' 转换成数据类型 int 时失败。
print abc
这个abc必须是一个字符串类型的变量,不能是其他类型。
所以必须要转化:
Set @s='Select * From dbo.Categories where CategoryID='''+cast(@TestID as varchar)+''''
print @s
用 cast(@TestID as varchar) 的形式进行转化。
set @def= CAST(@abc as int )
Sql Server RowCount
rowcount的作用就是用来限定后面的sql在返回指定的行数之后便停止处理,比如下面的示例,
select * from 表A
这样的查询只会返回表A中的前10条数据。它和 "select top 10 * from 表A" 的作用一样。注意一点,set rowcount 的设置会在整个会话中有效。比如下面的sql示例:
select * from 表A
go
select * from 表B
表A和表B都只会返回前10条数据。
要取消set rowcount的限定,只要设置 set rowcount 0 就可以了。
从上面的示例来看,好像rowcount没有多大的用处,限制查询结果的数据,我们使用top就可以了,而且还不用担心如果忘记取消rowcount的设置而对后面的sql的影响。 但在下面的情况下,rowcount的设置就会给我们带来很大的方便哦。
我们都知道select top 后面不能加参数,只能使用一个具体的int类型的数字。如果我们想实现top后面跟参数的功能,就只有构造sql字符串,然后使用exec来执行了。比如:
declare @sql nvarchar(1000)
set @n=10
set @sql='select top '+cast(@n as varchar(10))+' * from 表A'
exec(@sql)
先不说上面语句中exec的性能,单从sql的可读性上来看就很不友好。但如果我们使用rowcount来解决,就显的很优雅了,因为set rowcount后面是可以使用参数的。示例如下:
set @n=10
set rowcount @n
select * from 表A
注意:set rowcount的限定对修改,删除一样有效。比如下面的示例:
update 表a set qty=10 where id<100
这样,上面语句最多只会修改表a中id<100的前10条数据(假设id<100的数据数量大于10)
删除也是一样
delete from 表a
这样,上面的语句最多只会删除表a中前10条数据。
SQL server 的exist:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/exists-transact-sql?view=sql-server-2017
--声明变量
WHILE EXISTS(SELECT UserID FROM @tempAllUser)
BEGIN
-- 也可以使用top 1
SET ROWCOUNT 1
Exist:
Specifies a subquery to test for the existence of rows.
EXISTS ( subquery )
执行带有参数的存储过程:
执行带有OUTPUT的参数存储过程,必须这样调用: (参数后面必须带有OUTPUT参数)
DECLARE @testvalue int
EXEC sp_test 1,@testvalue output
SELECT @testvalue
https://www.cnblogs.com/zhangchenliang/archive/2013/04/07/3006433.html
SQL SERVER存储过程循环某个表
第一种方法是使用游标:
AS
declare @result VARCHAR(30)--用来处理结果的变量
begin
--声明一个游标
Declare curStudentFee Cursor for
SELECT NAME FROM SYSOBJECTS WHERE XTYPE='P';---查询语句(查询所有用户存储过程名称)
--打开游标
Open curStudentFee
--循环并提取记录
Fetch Next From curStudentFee Into @result--取第一条记录存入@result中
While ( @@Fetch_Status=0 )
begin
print ''''+@result+''''+',';---处理结果
Fetch Next From curStudentFee into @result----下一条
end
--关闭游标
Close curStudentFee
--释放游标
Deallocate curStudentFee
end
exec findName
第二种使用临时表;
/*------------------------编辑区域开始----------------------------------------*/
SET @CountBegin = 1 ----生成账号的开始数
SET @CountEnd = 5000 /*8500*/ ----生成账号的结束数
/*------------------------编辑区域结束----------------------------------------*/
DECLARE @dwUserID INT
DECLARE @tCanStudent TABLE
(
UserID int
,FlagID TINYINT
)
insert @tCanStudent select UserID,0 from AccountsInfo WHERE IsAndroid=1 and userid>=11643
WHILE(@CountBegin <= @CountEnd)
BEGIN
SELECT @dwUserID=0
SELECT TOP 1 @dwUserID=UserID FROM @tCanStudent WHERE flagID=0
IF @@error=0
BEGIN
UPDATE @tCanStudent SET flagID=1 WHERE UserID = @dwUserID
IF NOT EXISTS(SELECT UserID From AndroidLockInfo WHERE UserID=@dwUserID)
INSERT INTO AndroidLockInfo(UserID,AndroidStatus,ServerID,BatchID,LockDateTime) VALUES(@dwUserID,0,0,0,GETDATE());
END
SET @CountBegin = @CountBegin + 1
END
SQL server isnull使用方法
1、isnull(参数1,参数2),判断参数1是否为NULL,如果是,返回参数2,否则返回参数1。
在select的时候可能需要用到,如果一个字段返回null有可能导致程序报错,在这里我们可以用isnull来避免返回null.
SQL SERVER TOP
TOP 子句
TOP 子句用于规定要返回的记录的数目。
对于拥有数千条记录的大型表来说,TOP 子句是非常有用的。
现在,我们希望从上面的 "Persons" 表中选取头两条记录。
我们可以使用下面的 SELECT 语句:
SELECT TOP 2
* FROM Persons
/*********************************************************************************
* Function: WEB_PageView2 *
* Description: *
* Sql2005分页存储过程 *
* Finish DateTime: *
* 2009/1/3 *
* Example: *
* WEB_PageView @Tablename = 'Table1', @Returnfields = '*', *
* @PageSize = 2, @PageIndex = 1, @Where = '', *
* @OrderBy=N'ORDER BY id desc' *
*********************************************************************************/
CREATE PROCEDURE dbo.WEB_PageView
@TableName NVARCHAR(2000), -- 表名
@ReturnFields NVARCHAR(1000) = '*', -- 查询列数
@PageSize INT = 10, -- 每页数目
@PageIndex INT = 1, -- 当前页码
@Where NVARCHAR(1000) = '', -- 查询条件
@OrderBy NVARCHAR(1000), -- 排序字段
@PageCount INT OUTPUT, -- 页码总数
@RecordCount INT OUTPUT -- 记录总数
WITH ENCRYPTION AS
--设置属性
SET NOCOUNT ON
-- 变量定义
DECLARE @TotalRecord INT
DECLARE @TotalPage INT
DECLARE @CurrentPageSize INT
DECLARE @TotalRecordForPageIndex INT
BEGIN
IF @Where IS NULL SET @Where=N''
-- 记录总数
DECLARE @countSql NVARCHAR(4000)
IF @RecordCount IS NULL
BEGIN
SET @countSql='SELECT @TotalRecord=Count(*) From '+@TableName+' '+@Where
EXECUTE sp_executesql @countSql,N'@TotalRecord int out',@TotalRecord OUT
END
ELSE
BEGIN
SET @TotalRecord=@RecordCount
END
SET @RecordCount=@TotalRecord
SET @TotalPage=(@TotalRecord-1)/@PageSize+1
SET @CurrentPageSize=(@PageIndex-1)*@PageSize
-- 返回总页数和总记录数
SET @PageCount=@TotalPage
SET @RecordCount=@TotalRecord
IF @PageCount IS NULL SET @PageCount = 0
IF @RecordCount IS NULL SET @RecordCount = 0
-- 返回记录
SET @TotalRecordForPageIndex=@PageIndex*@PageSize
EXEC ('SELECT *
FROM (SELECT TOP '+@TotalRecordForPageIndex+' '+@ReturnFields+', ROW_NUMBER() OVER ('+@OrderBy+') AS PageView_RowNo
FROM '+@TableName+ ' ' + @Where +' ) AS TempPageViewTable
WHERE TempPageViewTable.PageView_RowNo >
'+@CurrentPageSize)
END
RETURN 0
GO
CREATE PROCEDURE PR_Sum
@a int,
@b int,
@sum int output
AS
BEGIN
set @sum=@a+@b
END
--调用存储过程
declare @sum2 int
exec PR_Sum 1,2,@sum2 output
print @sum2
SQL server允许插入主键
set IDENTITY_INSERT student ON
set IDENTITY_INSERT student OFF
SQL server 清空数据库所有表
利用sysobjects:
sysobjects系统对象表。 保存当前数据库的对象。
use 数据库名(是要删除表的所在的那个数据库的名称)
GO
declare @sql varchar(8000)
while (select count(*) from sysobjects where type='U')>0
begin
SELECT @sql='drop table ' + name
FROM sysobjects
WHERE (type = 'U')
ORDER BY 'drop table ' + name
exec(@sql)
end
declare @trun_name varchar(50)
declare name_cursor cursor for
select ''+name from sysobjects where xtype='U' ----and status > 0
open name_cursor
fetch next from name_cursor into @trun_name
while @@FETCH_STATUS = 0
begin
exec ( 'truncate table '+@trun_name)
fetch next from name_cursor into @trun_name
end
close name_cursor
deallocate name_cursor
sql server相关的更多相关文章
- SQL Server相关书籍
SQL Server相关书籍 (排名不分先后) Microsoft SQL Server 企业级平台管理实践 SQL Server 2008数据库技术内幕 SQL Server性能调优实战 SQL S ...
- Sql Server 相关错误问题及解决方法
1.首当其冲是登陆问题, SQL Server 2008选择Windows身份验证无法登录 (Microsoft Sql Server,错误:18456) 就是在连接SQL Server 2008时, ...
- cmd常用命令 和 sql server相关基础
在Java开发中 ms sql server 接触算是比较少的,本文记录一些ms sql server的基础知识. 1. 为表字段增加索引:create index user_openid on us ...
- SQL Server相关知识和经验的碎片化记录
1.在向服务器发送请求时发生传输级错误 在向服务器发送请求时发生传输级错误. (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接.) ---> Sy ...
- Sql Server相关的性能计数器
OS Memory and Paging 性能计数器: 1.Memory\Availability Mbytes 未使用的物理内存(非页面文件),通常情况下它应该大于100MB 2.Memory\ ...
- PHP连接SQL Server相关配置及说明
关于php怎么连接数据库,大家肯定有不同的看法,有的用wamp,有的用xamp,他们都是集成环境,方便操作.但有时,数据库的类型不同,要连接不同的数据库.今天和大家分享一下如何连接sql2000,服 ...
- phpstudy操作sql server相关经验
1.去官网http://www.phpstudy.net/下载并安装phpstudy 2.修改php.ini配置文件如下: mssql.secure_connection = onextension= ...
- SQL SERVER 相关
while循环 declare @sum int; declare @i int; ; ; ) begin ) begin set @sum=@sum+@i; end ; end select @su ...
- SQL Server ->> 与SQL Server服务配置相关的DMV
1) sys.dm_server_services这个DMV可以告诉我们与当前版本的SQL Server相关的服务的启动状态和最后一次启动的时间,诸如这样的信息. SELECT * FROM sys. ...
随机推荐
- Oracle客户端的安装与远程连接配置
在继续Oracle客户端的安装之前,需要分析一下Oracle客户端与数据库服务器之间的连接机制. 一.Oracle客户端与服务器端的通讯机制 1.Oracle Net协议 如下图所示,Oracle通过 ...
- vue 项目安装sass的依赖包
安装sass的依赖包 npm install --save-dev sass-loader //sass-loader依赖于node-sass npm install --save-dev node- ...
- select cast(round(12.5,2) as numeric(5,2))
http://www.jb51.net/article/74284.htm 解释: round()函数,是四舍五入用,第一个参数是我们要被操作的数据,第二个参数是设置小数四舍五入的精度. )--32. ...
- 线程同步-使用CountDownEvent类
CountDownEvent类:信号类,等待直到一定数量的操作完成. 代码Demo: using System; using System.Threading; Main方法下面加入以下代码片段: p ...
- POJ 3974 - Palindrome - [字符串hash+二分]
题目链接:http://poj.org/problem?id=3974 Time Limit: 15000MS Memory Limit: 65536K Description Andy the sm ...
- 2016年蓝桥杯省赛A组c++第9题(逆序串问题)
/* X星球的考古学家发现了一批古代留下来的密码. 这些密码是由A.B.C.D 四种植物的种子串成的序列. 仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串). 由于年代久远,其中许 ...
- LCA&最小生成树
LCA 经常被用来使用.比如询问树两点之间的距离. 比如树上差分 都是经常被使用的类型.有的时候倍增求LCA的同时还可以优化算法. 这道题呢 求一个严格的最小生成树,当然如果不严格的话如果有重边那么就 ...
- ios开发dismiss所有控制器
-(void)dismissToRootViewController { UIViewController *vc = self; while (vc.presentingViewController ...
- python循环字符转换
pyhon函数传参的时候穿的是引用,而不是实际值,这样可以节省内存 变量名要求:最好是以字母下划线作为变量名,不能和py关键字重复 import getpass提供了平台无关的在命令行下输入密码的方法 ...
- LeetCode 832 Flipping an Image 解题报告
题目要求 Given a binary matrix A, we want to flip the image horizontally, then invert it, and return the ...