为啥插入成功,ExecuteScalar却返回0
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥插入成功,ExecuteScalar却返回0相关的知识,希望对你有一定的参考价值。
insert 方法如下:
public int addUsers(Users users)
int number=-1;
using (SqlConnection conn = new SqlConnection(connString))
SqlCommand objCommand = new SqlCommand("proc_insertUsers", conn);
objCommand.CommandType = CommandType.StoredProcedure;
objCommand.Parameters.Add("@Name", SqlDbType.VarChar).Value = users.Name;
objCommand.Parameters.Add("@Pwd", SqlDbType.VarChar).Value = users.Pwd;
objCommand.Parameters.Add("@Address", SqlDbType.VarChar).Value = users.Address;
objCommand.Parameters.Add("@Phone", SqlDbType.VarChar).Value = users.Phone;
objCommand.Parameters.Add("@Id", SqlDbType.VarChar).Value = users.Id;
conn.Open();
number = Convert.ToInt32(objCommand.ExecuteScalar()); //获取存储过程的返回参数值
conn.Close();
conn.Dispose();
return number;
为什么插入成功了。却返回的是0????
下面是存储过程
ALTER PROCEDURE [dbo].[proc_insertUsers]
@Id varchar(50),
@Name varchar(50),
@Pwd varchar(50),
@Address varchar(50),
@Phone varchar(50)
AS
BEGIN
insert into Users(Id,Name, Pwd, Address, Phone) values(@Id,@Name,@Pwd,@Address,@Phone)
END
数据库中有个cardId,默认允许空。但跟这个关系不大吧?
用ExecuteNonQuery进行插入操作,这个函数返回影响的行数。本回答被提问者采纳
当磁盘使用率高时,使用 SqlCommand.ExecuteScalar() 从序列中选择返回 NULL
【中文标题】当磁盘使用率高时,使用 SqlCommand.ExecuteScalar() 从序列中选择返回 NULL【英文标题】:Select from sequence with SqlCommand.ExecuteScalar() returns NULL when high disk usage 【发布时间】:2018-03-16 16:07:01 【问题描述】:我在生产环境中遇到SqlCommand.ExecuteScalar()
有时会返回NULL
。
我在这里遇到过很多类似的问题,最接近的一个是:SqlCommand.ExecuteScalar returns null but raw SQL does not。但给出的建议与我的情况无关。
代码示例在这里:
using (var connection = new SqlConnection(connectionString))
connection.Open();
using (var command = connection.CreateCommand())
command.CommandText = "SELECT NEXT VALUE FOR Seq_Revision";
command.CommandType = CommandType.Text;
return (long)command.ExecuteScalar(); //<---ExecuteScalar() here returns NULL sometimes
Seq_Revision
这是简单的 MSSQL 序列,如下所示:
CREATE SEQUENCE [dbo].[Seq_Revision]
AS [bigint]
START WITH 0
INCREMENT BY 1
MINVALUE -9223372036854775808
MAXVALUE 9223372036854775807
CACHE 10
GO
而且我很确定它永远不会真正返回 NULL。
当在此代码示例中返回 NULL
时,我也观察到类似的奇怪(不可重复的行为),而我确定 存在具有此 ID 的实体:
NHibernate.ISession.Get<FooEntity>(entityId)
有趣的是,通过这种方法返回 NULL
与 SQL 节点上存在大量磁盘活动(磁盘队列长度 > ~50)的时间范围非常相关。
这可能很重要:我们使用带 2 个节点的 AlwaysON 集群,其中一个节点用于读取模式(连接字符串中的ApplicationIntent=READONLY
)。
MSSQL 版本是:
Microsoft SQL Server 2014 (SP2-CU5) (KB4013098) - 12.0.5546.0 (X64)
Apr 3 2017 14:55:37
Copyright (c) Microsoft Corporation
Enterprise Edition: Core-based Licensing (64-bit) on Windows NT 6.3 <X64> (Build 9600: )
【问题讨论】:
ExecuteScalar
返回null
表示:没有返回行。如果返回的行为空值,则为DBNull.Value
。这没有回答“为什么?”,但它可能是有用的上下文
@MarcGravell,我知道。但是你相信 SELECT NEXT VALUE FOR Seq_Revision 返回 0 行吗?听起来不可能。
我不知道;这是个好问题
NEXT VALUE FOR
不支持只读数据库。请参阅docs.microsoft.com/en-us/sql/t-sql/functions/… 的限制和限制 => 从连接字符串中删除 ApplicationIntent=READONLY
您能否测试这种情况,例如if (command.GetType() == typeof(DBNull))
或者它用InvalidCastException
捕获它,然后检查值或在Thread.Sleep(1000);
之后重试,以排除磁盘的计时问题.也是添加一些日志记录以帮助形成minimal reproducible example 的好地方,我猜它是间歇性的,并且只能在 IO 压力下重现。
【参考方案1】:
我认为问题可能与序列缓存有关。
也许有一些未处理的东西导致缓存中剩余的序列号丢失。
尝试禁用序列中的缓存:
ALTER SEQUENCE [dbo].[Seq_Revision]
NO CACHE
GO
或尝试使用更高的缓存值:
ALTER SEQUENCE [dbo].[Seq_Revision]
CACHE 100
GO
【讨论】:
谢谢,我们会试试这个理论。但这无法解释为什么我有时会从 ISession.Get(id) 获得 NULL,而我确信具有此 ID 的实体确实存在:NHibernate.ISession.Get以上是关于为啥插入成功,ExecuteScalar却返回0的主要内容,如果未能解决你的问题,请参考以下文章
为啥 OleDb ExecuteScalar 方法在查询 COUNT 时返回 Decimal?
返回标识值时的 ExecuteScalar 与 ExecuteNonQuery
ExecuteScalar方法返回值 及 DBnull和NUll的区别
C#中对SQl数据库进行插入操作,有返回受影响的行数,执行结果是“添加成功”但是在数据困中却没有数据