OUTPUT INSERTED Id/SCOPE_IDENTITY() 在 C# (ASP.NET Core Razor Pages) SQL 查询中返回 null,在 SQL Server Mana
Posted
技术标签:
【中文标题】OUTPUT INSERTED Id/SCOPE_IDENTITY() 在 C# (ASP.NET Core Razor Pages) SQL 查询中返回 null,在 SQL Server Management Studio 中工作正常【英文标题】:OUTPUT INSERTED Id/SCOPE_IDENTITY() returns null in C# (ASP.NET Core Razor Pages) SQL query, works fine in SQL Server Management Studio 【发布时间】:2019-08-08 17:29:38 【问题描述】:我有以下参数化 SQL 查询,它将数据插入到表中,获取新行的(自动递增的)Id 值,然后将该新值插入到另一个表中:
DECLARE @engId_newtable TABLE(engId INT);
DECLARE @engId_new INT;
INSERT INTO eng (locationTypeId, engNumb, projectId, engTypeId, capacity, cylNo, employeeId, bore, stroke, crankOffset, rodLength, cr, crankThrow, pinOffset, engDesc)
OUTPUT INSERTED.engId INTO @engId_newtable
SELECT a.locationTypeId, @engNumb, b.projectId, c.engTypeId, @capacity, @cylNo, d.employeeId, @bore, @stroke, @crankOffset, @rodLength, @cr, @crankThrow, @pinOffset, @engDesc
FROM dbo.locationType AS a,dbo.project AS b,dbo.engType AS c,dbo.employees AS d
WHERE a.locationType = @locationType AND b.projectCode = @projectCode AND b.engineType = @engineType AND c.engType = @engType AND d.userName = @userName ;
SELECT @engId_new = engId FROM @engId_newtable;
INSERT INTO oil (engId, oilQuantity, oilTypeId)
SELECT @engId_new, @oilQuantity, a.oilTypeId
FROM dbo.oilType AS a
WHERE a.oilManufacturer = @oilManufacturer AND a.oilRange = @oilRange AND a.oilGrade = @oilGrade ;
该查询在 SQL Server Management Studio (SSMS) 中执行时运行良好,但是当我尝试使用我的 ASP.NET Core C# (Razor Pages) 项目运行它时,它失败并出现以下错误:
System.Data.SqlClient.SqlException: '无法将值 NULL 插入 列'engId',表'TestEng.dbo.oil';列不允许空值。 插入失败。声明已终止。'
所以看来OUTPUT INSERTED
命令不起作用。我也尝试过使用SELECT @engId_new = SCOPE_IDENTITY()
,甚至@@IDENTITY
,但它们也返回null并给出相同的错误。
我在项目的其他领域也有类似的查询(使用OUTPUT INSERTED
),它们运行良好。直到今天早些时候,当我们更改运行 SQL 数据库的服务器时,此查询也正常工作 - 也许我需要更改一些数据库/表设置?
非常感谢任何帮助,我真的很茫然。谢谢。
编辑:显示查询的执行方式
查询是以编程方式构建的 - 我知道查询构建函数可以正常工作,因为我的所有其他查询都可以正常工作 - 我尝试执行的查询与此处显示的完全相同(它由查询构建器作为单个字符串返回):
"DECLARE @engId_newtable TABLE(engId INT); DECLARE @engId_new INT; INSERT INTO eng (locationTypeId, engNumb, projectId, engTypeId, capacity, cylNo, employeeId, bore, stroke, crankOffset, rodLength, cr, crankThrow, pinOffset, engDesc) OUTPUT INSERTED.engId INTO @engId_newtable SELECT a.locationTypeId, @engNumb, b.projectId, c.engTypeId, @capacity, @cylNo, d.employeeId, @bore, @stroke, @crankOffset, @rodLength, @cr, @crankThrow, @pinOffset, @engDesc FROM dbo.locationType AS a,dbo.project AS b,dbo.engType AS c,dbo.employees AS d WHERE a.locationType = @locationType AND b.projectCode = @projectCode AND b.engineType = @engineType AND c.engType = @engType AND d.userName = @userName ;SELECT @engId_new = engId FROM @engId_newtable; INSERT INTO oil (engId, oilTypeId) SELECT @engId_new, a.oilTypeId FROM dbo.oilType AS a WHERE a.oilManufacturer = @oilManufacturer AND a.oilRange = @oilRange AND a.oilGrade = @oilGrade ;"
查询执行函数,从razor页面模型调用,查询和连接作为参数传递:
public void ExecuteVoid(SqlConnection con, string query, List<SqlColumn> columns, List<SqlFilter> filters)
SqlCommand cmd = new SqlCommand(query, con);
Parameterize(cmd, columns, filters);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Parameterize
函数只是将所有相关参数添加到查询中。同样,就像查询构建器函数一样,我知道它可以工作,因为我的所有其他查询都按预期执行。
编辑 2:SQL Server Profiler
下图显示了我可以在 SQL Server Profiler 中看到的与该查询相关的所有事件:
查询的所有部分都按预期写出,所有参数都存在,但查询仍然失败。
【问题讨论】:
你可以在 c# 中做到这一点,很可能你只是弄错了。显示代码? SQL 探查器显示哪些查询(SP 语句)和异常? @Arvo SQL 分析器显示事件类RPC:Completed
的单个事件,文本数据为 exec sp_executesql
,然后是查询。编辑:也得到异常Cannot insert the value NULL into column 'engId', table 'TestEng.dbo.oil'; column does not allow nulls. INSERT fails.
在分析器中选择更多事件,例如异常、sp 语句已启动、sp 语句已完成 - 这样您应该会看到更多。并且 - 您在探查器中的查询看起来与应有的完全一样吗?
@Arvo 查看我对该问题的第二次编辑
【参考方案1】:
我发现了问题!我在我的第一个查询中使用HttpContext.Session.GetString
来获取WHERE
子句的值(到eng
表)。我在代码的其他地方更改了字符串的名称,却忘记在查询中更改它。所以,这个问题实际上与 SQL 无关。
我可以说 SQL 服务器探查器对于查找此错误至关重要,因此,如果您在使用 Visual C# 参数化 sql 查询时遇到问题,请查看那里的查询,您可能会突出一些未发现的问题。
【讨论】:
以上是关于OUTPUT INSERTED Id/SCOPE_IDENTITY() 在 C# (ASP.NET Core Razor Pages) SQL 查询中返回 null,在 SQL Server Mana的主要内容,如果未能解决你的问题,请参考以下文章
latex生成pdf 出现missing$ inserted
G.Finding the Radius for an Inserted Circle 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛