0

我正在为我的应用程序中的搜索字段创建一个查询。该查询使用“like”关键字来检查记录中的各种字段。其中一个字段是未命名的 ([{}, {}]) json 数组。数组中的字段全部匹配。我希望能够在不使用索引的情况下检查数组的每个“Value”属性,即“$[0].value”。原因是数组的大小可能会有所不同。以下是数据示例:

[{
    "MappedFieldName": "Customer",
    "DataType": "string",
    "Value": "Mapco Express"
}, {
    "MappedFieldName": "Invoice Nbr",
    "DataType": "string",
    "Value": "31856174"
}, {
    "MappedFieldName": "Invoice Document Date",
    "DataType": "DateTime",
    "Value": "2018-12-25 00:00:00.000"
}, {
    "MappedFieldName": "Processing Date",
    "DataType": "DateTime",
    "Value": "2019-01-04 00:00:00.000"
}, {
    "MappedFieldName": "Vendor Name",
    "DataType": "string",
    "Value": "Bullseye"
}, {
    "MappedFieldName": "Account Nbr",
    "DataType": "string",
    "Value": "0048219"
}, {
    "MappedFieldName": "Location #",
    "DataType": "string",
    "Value": "7520"
}, {
    "MappedFieldName": "Amount Invoiced",
    "DataType": "decimal",
    "Value": "3580.43"
}, {
    "MappedFieldName": "Amount Processed",
    "DataType": "decimal",
    "Value": "3580.43"
}, {
    "MappedFieldName": "Invoice Start Date",
    "DataType": "DateTime",
    "Value": "2018-04-01 00:00:00.000"
}, {
    "MappedFieldName": "Invoice End Date",
    "DataType": "DateTime",
    "Value": "2018-04-01 00:00:00.000"
}]

SELECT *
FROM [dbo].[Invoice]
WHERE JSON_VALUE(InvoiceData, '$.Value') like '%' + @searchText + '%'

此查询不起作用,因为我没有指定索引,即'$[0].Value'。

4

3 回答 3

0

我想到了。我首先在搜索文本过滤器的记录的 json 字段上使用 OPENJSON,以获取在其中找到文本的 json 数组部分的索引。接下来,我使用 where 子句中的索引来标识数组索引去查查看。处理此问题的代码如下。这将返回在 records json 数组中找到搜索文本的所有记录。

declare @searchText varchar(200) = '004'
declare @searchIndex varchar(10)

SELECT @searchIndex = [key]
FROM OPENJSON((SELECT InvoiceData FROM [dbo].[Invoice])) where Json_Value(value, '$.Value') like '%' + @searchText + '%'

SELECT *
    FROM [dbo].[Invoice]
    WHERE JSON_VALUE(InvoiceData, '$[' + @searchIndex +'].Value') like '%' + @searchText + '%'

这个答案可能会被简化。如果您有一个简化的答案,请随时发布。

于 2019-11-13T01:38:47.843 回答
0

输入是具有固定结构( 和键)的对象数组,JSON因此另一种可能的方法是使用显式模式来返回包含您在子句中定义的列的表。使用这种方法,您可以过滤表格和/或从输入中获取其他信息:JSONMappedFieldNameDataTypeValueOPENJSON()WITHinvoicesJSON

桌子:

CREATE TABLE Invoices (
   InvoiceData nvarchar(max)
)
INSERT INTO Invoices 
   (InvoiceData)
VALUES
   (N'[{ "MappedFieldName": "Customer", "DataType": "string", "Value": "Mapco Express"}, { "MappedFieldName": "Invoice Nbr", "DataType": "string", "Value": "31856174"}, { "MappedFieldName": "Invoice Document Date", "DataType": "DateTime", "Value": "2018-12-25 00:00:00.000"}, { "MappedFieldName": "Processing Date", "DataType": "DateTime", "Value": "2019-01-04 00:00:00.000"}, { "MappedFieldName": "Vendor Name", "DataType": "string", "Value": "Bullseye"}, { "MappedFieldName": "Account Nbr", "DataType": "string", "Value": "0048219"}, { "MappedFieldName": "Location #", "DataType": "string", "Value": "7520"}, { "MappedFieldName": "Amount Invoiced", "DataType": "decimal", "Value": "3580.43"}, { "MappedFieldName": "Amount Processed", "DataType": "decimal", "Value": "3580.43"}, { "MappedFieldName": "Invoice Start Date", "DataType": "DateTime", "Value": "2018-04-01 00:00:00.000"}, { "MappedFieldName": "Invoice End Date", "DataType": "DateTime", "Value": "2018-04-01 00:00:00.000"}]')

陈述:

DECLARE @search nvarchar(max) = '004'
SELECT 
   i.*,
   -- You may include the keys and values from the input JSON:
   j.*
FROM Invoices i
CROSS APPLY OPENJSON(i.InvoiceData) WITH (
   -- You may define only the columns, that you need here:
   [MappedFieldName] nvarchar(100) '$.MappedFieldName',
   [DataType] nvarchar(20) '$.DataType',
   [Value] nvarchar(100) '$.Value' 
) j
WHERE j.[Value] LIKE CONCAT('%', @search, '%')
于 2019-11-13T06:57:30.863 回答
0

查询可以简单地写成如下。当相应的 JSON 列中有一个或多个匹配项时,它将返回 1 个发票:

SELECT *
FROM invoice
WHERE EXISTS (
    SELECT 1
    FROM OPENJSON(invoicedata)
    WITH (
        [Value] NVARCHAR(100) '$.Value'
    )
    WHERE [Value] LIKE '%' + '004' + '%'
)

db<>fiddle 上的演示

于 2019-11-13T07:10:15.750 回答