mysql

How to JSON_INSERT a path with the value of a SELECT in MYSQL?


I have a json field custom_fields and want to insert a new path with the integer-converted value of another path in the same json field. Selecting the integer value is working for its own, but not in JSON_INSERT. How can i do this?

UPDATE product_translation
SET custom_fields = JSON_INSERT(custom_fields, '$."sorting"', SELECT CAST(JSON_EXTRACT(custom_fields, '$."product_attr4"') AS SIGNED) FROM product_translation)
WHERE JSON_CONTAINS_PATH(custom_fields, '$."product_attr4"')

Edit:
@Barmar's hint to use JSON_UNQUOTE() brought me a litte further: Using it in the UPDATE statement, causes SQL-Fehler (1292): Truncated incorrect INTEGER value: '15b'. Doing

SELECT JSON_VALUE(custom_fields, '$."product_attr4"') AS attr4, CAST(JSON_EXTRACT(custom_fields, '$."product_attr4"') AS SIGNED) AS attr4int FROM product_translation
WHERE JSON_SEARCH(custom_fields, 'one', '15b')

shows 16 rows with

attr4 attr4int
15b 15

but 16x warnings: Warnung: (3156) Invalid JSON value for CAST to INTEGER from column json_extract at row 1 (to 16)

If I do

SELECT JSON_VALUE(custom_fields, '$."product_attr4"') AS attr4, CAST(JSON_UNQUOTE(JSON_EXTRACT(custom_fields, '$."product_attr4"')) AS SIGNED) AS attr4int FROM product_translation
WHERE JSON_SEARCH(custom_fields, 'one', '15b')

with the same output, but following warnings Warnung: (1292) Truncated incorrect INTEGER value: '15b' If I do

SELECT JSON_EXTRACT(custom_fields, '$."migration_AQ-SW5_product_attr4"') AS attr4, CAST(JSON_EXTRACT(custom_fields, '$."migration_AQ-SW5_product_attr4"') AS SIGNED) AS attr4int FROM product_translation
WHERE JSON_CONTAINS_PATH(custom_fields, 'one', '$."migration_AQ-SW5_product_attr4"') 

no warnings are shown and the output is as expected.

Sample data in custom_fields:

        {  
    "product_attr1": "7003868041, 700.3.86.804.1", 
    "product_attr2": "0", 
    "product_attr3": "0", 
    "product_attr4": "15b", 
    "product_attr6": 0, 
    "product_attr7": 1, 
    "product_attr8": 0, 
    "product_attr9": 0, 
    "product_attr10": 0, 
    "product_attr13": "0", 
    "setarticle_discount_type": 0, 
    "setarticle_discount_value": 0.0, 
    "setarticle_is_set_article": 0, 
    "setarticle_discount_automatically": 0,
"setarticle_calculate_price_automatically": 0
    }
> mysql --version    
mysql  Ver 8.0.42-33 for Linux on x86_64 (Percona Server (GPL), Release '33', Revision '9dc49998')

Solution

  • As Barmar mentioned: '15b' cannot be converted to an integer. The SELECT is done, but with a warning. The UPDATE leads to an error. I have to cut of the 'b' before. My field contains 2 patterns of not convertable strings: '15b' or '02, 03'. I am only interested in the digits at the begin: '15b' => 15, '02, 03' => 2. So I had to cut of everthing behind:

    UPDATE product_translation
    SET custom_fields = JSON_INSERT(custom_fields, '$."sorting"', CAST(REGEXP_SUBSTR(JSON_EXTRACT(custom_fields, '$."product_attr4"'), '[0-9]+') AS SIGNED))
    WHERE JSON_CONTAINS_PATH(custom_fields, 'one', '$."product_attr4"')