@@ROWCOUNT 含义

本文深入探讨了SQL语句如何通过设置@@ROWCOUNT来追踪执行过程中影响的行数,包括基本语句、DML语句、查询语句、本地编译存储过程等场景的应用实例。

返回受上一语句影响的行数。 如果行数大于 20 亿,请使用 ROWCOUNT_BIG

Transact-SQL 语句可以通过下列方式设置 @@ROWCOUNT 的值:

  • 将 @@ROWCOUNT 设置为受影响或被读取的行的数目。 可以将行发送到客户端,也可以不发送。

  • 保留前一个语句执行中的 @@ROWCOUNT。

  • 将 @@ROWCOUNT 重置为 0 但不将该值返回到客户端。

执行简单分配的语句始终将 @@ROWCOUNT 值设置为 1。 不将任何行发送到客户端。 这些语句的示例如下:SET @local_variable、RETURN、READTEXT 以及不带查询的 Select 语句,如 SELECT GETDATE() 或 SELECT 'Generic Text'

在查询中进行分配或使用 RETURN 的语句将 @@ROWCOUNT 值设置为受查询影响的行数或查询读取的行数,例如:SELECT @local_variable = c1 FROM t1。

数据操作语言 (DML) 语句将 @@ROWCOUNT 值设置为受查询影响的行数,并将该值返回到客户端。 DML 语句不会将任何行发送到客户端。

DECLARE CURSOR 和 FETCH 将 @@ROWCOUNT 值设置为 1。

EXECUTE 语句保留前一个 @@ROWCOUNT。

USE、SET <选项>、DEALLOCATE CURSOR、CLOSE CURSOR、BEGIN TRANSACTION 或 COMMIT TRANSACTION 等语句将 ROWCOUNT 值重置为 0。

本机编译存储过程保留以前的 @@ROWCOUNT。 本机编译存储过程中的 Transact-SQL 语句不设置 @@ROWCOUNT。 有关详细信息,请参阅本机编译的存储过程简介

示例
 

以下示例执行 UPDATE 语句并使用 @@ROWCOUNT 来检测是否更改了任何行。

 
 
USE AdventureWorks2012;
GO
UPDATE HumanResources.Employee 
SET JobTitle = N'Executive'
WHERE NationalIDNumber = 123456789
IF @@ROWCOUNT = 0
PRINT 'Warning: No rows were updated';
GO

转载于:https://www.cnblogs.com/haore147/p/3902944.html

ALTER PROCEDURE [dbo].[SP_HTTP_CLIENT_REV5] @p_Send VARCHAR(4000), @p_Rev VARCHAR(8000), @P_CODE VARCHAR(100) OUT, @P_MSG VARCHAR(4000) OUT AS /*向wms发送sort 分拣结果回传接口*/ DECLARE @v_Msg VARCHAR(4000) = ''; DECLARE @chuteMsg VARCHAR(8000) = '' DECLARE @JSON VARCHAR(255) = '' DECLARE @Code VARCHAR(255) = '' DECLARE @V_BARCODE VARCHAR(200) = '' DECLARE @Rectype VARCHAR(50) = '' DECLARE @Boxtype VARCHAR(50) = '' DECLARE @BATCH_NO VARCHAR(50) = '' DECLARE @MATNO VARCHAR(50) = '' DECLARE @BoxQuant VARCHAR(50) = '' DECLARE @Port VARCHAR(50) = '' BEGIN SET @p_Send = '' ; SET @Code = (SELECT StringValue from parseJSON(@p_Rev) WHERE name='Code') SELECT @V_BARCODE = Barcode,@Rectype =Rectype, @Boxtype = box_type,@BATCH_NO = batch_no,@MATNO = Matno,@Port = Port FROM OPENJSON(@p_Rev)WITH( Barcode VARCHAR(100) '$.DataINput.Barcode', Rectype VARCHAR(100) '$.Data.Rectype', box_type VARCHAR(100) '$.Data.box_type', batch_no VARCHAR(100) '$.Data.batch_no', Matno VARCHAR(100) '$.Data.Matno', Port VARCHAR(100) '$.Data.Port' ) IF @Code = 'S' BEGIN SET @P_MSG = 'WMS反馈成功' SELECT * FROM WCS_BCR_TRK where BARCODE = @V_BARCODE AND DEAL_FLAG = '0' AND DATEDIFF(MINUTE,CREATE_DATE,GETDATE())<30 order by CREATE_DATE desc IF @@ROWCOUNT = 0 BEGIN INSERT INTO WCS_BCR_TRK(BARCODE,BATCH,MATNO,RecType,Box_Type,[Port],DEAL_FLAG) VALUES(ISNULL(@V_BARCODE,'') ,ISNULL(@BATCH_NO,'') ,ISNULL(@MATNO,''),ISNULL(@Rectype,''),ISNULL(@Boxtype,''),ISNULL(@Port,''),0) END UPDATE WCS_UNSTACKING_LOG SET DEAL_FLAG = 1 WHERE DEAL_FLAG = 7 and BARCODE = @V_BARCODE END ELSE BEGIN SELECT * FROM WORK_LOG WHERE BARCODE='N0081559' AND WCS_TYPE= '拆垛单箱上报反馈' AND SHOW_MSG = 'WMS反馈成功' AND DATEDIFF(MINUTE,CREATE_DATA,GETDATE())<5 order by CREATE_DATA desc IF @@ROWCOUNT > 0 BEGIN SET @P_MSG = 'WMS已反馈成功,再次上报' SELECT * FROM WCS_BCR_TRK where BARCODE = @V_BARCODE AND RecType='2' AND DEAL_FLAG = '0' IF @@ROWCOUNT = 0 BEGIN INSERT INTO WCS_BCR_TRK(BARCODE,BATCH,MATNO,RecType,Box_Type,[Port],DEAL_FLAG) VALUES(ISNULL(@V_BARCODE,'') ,ISNULL(@BATCH_NO,'') ,ISNULL(@MATNO,''),ISNULL(@Rectype,''),ISNULL(@Boxtype,''),ISNULL(@Port,''),0) END UPDATE WCS_UNSTACKING_LOG SET DEAL_FLAG = 1 WHERE DEAL_FLAG = 7 and BARCODE = @V_BARCODE END ELSE BEGIN SET @P_MSG = 'WMS反馈异常' END --UPDATE WCS_UNSTACKING_LOG --SET DEAL_FLAG = 1 --WHERE DEAL_FLAG = 7 and BARCODE = @V_BARCODE END EXEC dbo.SP_WCS_CREATE_WORK_LOG '拆垛单箱上报反馈', @V_BARCODE, NULL, NULL, @p_msg, @p_Rev, '[SP_HTTP_CLIENT_REV5]', @P_CODE, NULL, NULL, NULL, NULL, NULL, @Code, NULL, NULL, NULL, NULL SET @P_MSG = '' END 给改存储过程注释
08-30
<think>我们正在讨论SQL中'@'符号的作用。根据用户提供的引用和问题,我们需要解释SQL中'@'符号的常见用途,特别是它是否用于映射。 在SQL中,'@'符号通常有以下几种用途: 1. **变量声明和引用**(在Transact-SQL中,如SQL Server): - 使用`@`符号作为前缀来声明局部变量,例如:`DECLARE @myVariable INT;` - 然后可以给变量赋值:`SET @myVariable = 10;` - 在查询中使用:`SELECT * FROM Table WHERE Column = @myVariable;` 2. **参数化查询中的参数标识**: - 在参数化查询中,参数通常以`@`为前缀,例如在ADO.NET中,我们使用`@parameterName`作为占位符,然后在命令参数集合中添加参数并赋值。 3. **存储过程和函数的参数**: - 在定义存储过程或函数时,参数名前通常有`@`符号,例如: ```sql CREATE PROCEDURE MyProc @param1 INT, @param2 VARCHAR(50) AS BEGIN -- 过程体 END ``` 4. **在MyBatis等ORM框架中的使用**: - 在MyBatis中,`#{}`和`${}`用于参数替换,但注意`@`并不是MyBatis中用于参数替换的符号。然而,在MyBatis的SQL映射文件中,我们可能会在SQL语句中使用`@`来引用参数(特别是在使用注解方式时,但通常还是使用`#`和`$`)。不过,在MyBatis中,我们通常不会直接使用`@`作为参数占位符,而是使用`#`或`$`。 5. **在JPA的本地查询中**: - 在JPA中,我们可以使用`@Query`注解来定义本地SQL查询,此时在SQL语句中可以使用`:`或`?`作为参数占位符,而不是`@`。但是,如果使用命名参数,则参数名前会加上`:`,例如:`@Query("SELECT u FROM User u WHERE u.name = :name")`。 6. **其他数据库系统中的特殊含义**: - 在MySQL中,`@`符号用于用户变量,例如:`SET @var = 1;`,然后在查询中可以使用`@var`。 - 在PostgreSQL中,`@`符号用于绝对值操作符(但通常使用`ABS()`函数)。 关于映射,在SQL中,`@`符号本身并不直接用于映射。映射通常指的是将数据库列与对象属性关联起来,这通常由ORM框架通过注解或XML配置完成(如JPA中的`@Column`,MyBatis中的`<resultMap>`)。在参数化查询中,`@`符号用于标识参数,然后通过参数名称映射到具体的值。 因此,回答用户的问题:SQL中的`@`符号并不直接用于映射,而是主要用于变量和参数的标识。在参数化查询中,它作为参数的前缀,然后通过参数名称映射到具体的值,但这只是参数传递,而不是对象关系映射(ORM)中的映射。 下面我们根据上述分析给出回答:</think>在 SQL 中,`@` 符号主要用于以下场景,**不直接用于对象-关系映射**,但在参数化查询中起着关键的映射作用: ### 1. **参数化查询中的参数标识符**(最常见用途) - `@` 符号用于标识 SQL 语句中的参数占位符 - 作用:将程序变量安全映射到 SQL 参数 - 示例: ```sql -- 使用 @ 定义参数 INSERT INTO Users (Name, Age) VALUES (@name, @age); ``` 在 C# 中映射参数: ```csharp cmd.Parameters.AddWithValue("@name", userName); cmd.Parameters.AddWithValue("@age", userAge); ``` ### 2. **局部变量声明**(在 T-SQL/SQL Server) - 在存储过程或脚本中定义局部变量: ```sql DECLARE @counter INT = 0; SET @counter = @counter + 1; ``` ### 3. **特殊系统函数**(如 SQL Server) - 访问系统函数和全局变量: ```sql SELECT @@VERSION; -- 获取数据库版本 SELECT @@ROWCOUNT; -- 获取受影响行数 ``` ### 与 ORM 映射符号的区别 | 符号 | 框架 | 用途 | 安全性 | |------|------------|-------------------------------|--------------| | `@` | 原生 SQL | 参数标识/变量声明 | 安全 | | `#{}`| MyBatis | **预编译参数映射** [^1] | 防 SQL 注入 | | `${}`| MyBatis | 字符串直接替换(有风险)[^1] | 不安全 | | `:` | JPA/Hibernate | 命名参数映射 (如 `:name`) | 安全 | ### 关键结论 1. `@` **不是 ORM 映射符号**,而是 SQL 原生参数标识符 2. 在参数化查询中,`@` 实现了**程序变量到 SQL 参数的映射** 3. 相比直接拼接 SQL,使用 `@` 的参数化查询: - ✅ 防止 SQL 注入攻击 - ✅ 自动处理数据类型转换 - ✅ 提高查询性能(执行计划复用) ### 使用示例(C# + SQL Server) ```csharp // 使用 @ 参数的安全查询 using (var cmd = new SqlCommand( "INSERT INTO Orders (Product, Quantity) VALUES (@product, @qty)", conn)) { cmd.Parameters.AddWithValue("@product", "Laptop"); cmd.Parameters.AddWithValue("@qty", 2); cmd.ExecuteNonQuery(); } ``` 建议始终使用 `@` 参数化查询来保证安全性和正确性,避免直接拼接 SQL 字符串[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值