C# Dapper使用JSON_VALUE访问SQL Server 2016

6
我想使用JSON_VALUE从我的表中查询数据:
var str = "123";
var value = "Name"
using(var conn = GetMyConnection())
{
   var result = conn.QueryFirstOrDefault<string>(
      @"SELECT [Id] FROM [dbo].[MyTable]
         WHERE JSON_VALUE([JsonColumn], @MyQuery) = @Str",
      new
      {
         MyQuery = $"$.{value}",
         Str = str
      }
   );
}

我在SQL Server中尝试过这个,它可行:

SELECT [Id] FROM [dbo].[MyTable]
WHERE JSON_VALUE([JsonColumn], '$.Name') = '123'

我该如何调整我的代码?


我建议您创建一个存储过程,将您的JSON字符串作为参数传递并在存储过程中处理它。 - Masoud Andalibi
我在本地环境中尝试了这段代码,它可以正常工作。那么问题出在哪里呢? - Serkan Arslan
@sarslan 这样做不起作用,因为 OP 把它作为文字传递,而在 C# 中他试图将其作为变量传递。在 SQL Server 中唯一的方法是使用动态 SQL 或在 C# 代码中构建查询字符串。 - Lukasz Szozda
@lad2025 实际上,我已经尝试了Azure Sql并且它可以工作。你是正确的,因为我没有尝试过sql 2016。 - Serkan Arslan
@sarslan 在我的答案中提到,“在 SQL Server 2017 和 Azure SQL 数据库中,您可以将变量作为路径的值。”Azure 总是领先于本地 :) - Lukasz Szozda
1个回答

9

我在 SQL Server 中尝试了这个,它工作正常。

首先,你遗漏了一个重要的事情:变量与字面量之间的区别。

如果在 SSMS 中使用,它在 SQL Server 2016 上不会起作用:

CREATE TABLE MyTAble(ID INT IDENTITY(1,1), JsonColumn NVARCHAR(MAX));

INSERT INTO MyTable( JsonColumn)
VALUES('{"Name":123}');


-- it will work
SELECT [Id] FROM [dbo].[MyTable]
WHERE JSON_VALUE([JsonColumn], '$.Name') = '123';

-- let''s try your example
DECLARE @Path NVARCHAR(MAX) = '$.Name';
SELECT [Id] FROM [dbo].[MyTable]
WHERE JSON_VALUE([JsonColumn], @Path) = '123';

DBFiddle演示

您将获得:

"JSON_VALUE或JSON_QUERY"的第2个参数必须是字符串常量。


SQL Server 2017+开始,您可以将路径作为变量传递。来自JSON_VALUE

path

指定要提取的属性的JSON路径。有关更多信息,请参阅JSON Path Expressions(SQL Server)。

在SQL Server 2017和Azure SQL Database中,您可以将变量作为路径的值提供。

DbFiddle演示2017


最后,要使其在SQL Server 2016上正常工作,您可以使用连接(而不是参数绑定)构建查询字符串。

警告!这可能会导致严重的安全问题和SQL注入攻击。


1
如果有人遇到这些问题,我想提醒一下:即使我实际上使用的是字符串字面量,在SQL Server 2016上也会出现此错误。问题在于我正在使用强制参数化。因此,对我来说解决方案是暂时切换到简单参数化,运行查询,然后再切换回强制参数化。 - Tom Pažourek
@TomPažourek 很好的观察。 - Lukasz Szozda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接