在mysql中反序列化数据

js81xvg6  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(247)

在mysql中有没有不使用php,只使用sql语言反序列化数据的方法?
使用woocommerce插件将购物车项目序列化存储在数据库中。目标是对cart表进行查询并获取cart项,然后将结果发送到api。购物车项目作为序列化数据存储在表中,如下所示:

a:1:{s:4:"cart";a:2:{s:32:"76dc611d6ebaafc66cc0879c71b5db5c";a:11:{s:3:"key";s:32:"76dc611d6ebaafc66cc0879c71b5db5c";s:10:"product_id";i:128;s:12:"variation_id";i:0;s:9:"variation";a:0:{}s:8:"quantity";i:1;s:9:"data_hash";s:32:"b5c1d5ca8bae6d4896cf1807cdf763f0";s:13:"line_tax_data";a:2:{s:8:"subtotal";a:0:{}s:5:"total";a:0:{}}s:13:"line_subtotal";d:500;s:17:"line_subtotal_tax";i:0;s:10:"line_total";d:500;s:8:"line_tax";i:0;}s:32:"65ded5353c5ee48d0b7d48c591b8f430";a:6:{s:3:"key";s:32:"65ded5353c5ee48d0b7d48c591b8f430";s:10:"product_id";i:132;s:12:"variation_id";i:0;s:9:"variation";a:0:{}s:8:"quantity";i:1;s:9:"data_hash";s:32:"b5c1d5ca8bae6d4896cf1807cdf763f0";}}}

在在线工具中反序列化后,我得到了以下结构:

Array
  (
   [cart] => Array
    (
        [76dc611d6ebaafc66cc0879c71b5db5c] => Array
            (
                [key] => 76dc611d6ebaafc66cc0879c71b5db5c
                [product_id] => 128
                [variation_id] => 0
                [variation] => Array
                    (
                    )

                [quantity] => 1
                [data_hash] => b5c1d5ca8bae6d4896cf1807cdf763f0
                [line_tax_data] => Array
                    (
                        [subtotal] => Array
                            (
                            )

                        [total] => Array
                            (
                            )

                    )

                [line_subtotal] => 500
                [line_subtotal_tax] => 0
                [line_total] => 500
                [line_tax] => 0
            )

        [65ded5353c5ee48d0b7d48c591b8f430] => Array
            (
                [key] => 65ded5353c5ee48d0b7d48c591b8f430
                [product_id] => 132
                [variation_id] => 0
                [variation] => Array
                    (
                    )

                [quantity] => 1
                [data_hash] => b5c1d5ca8bae6d4896cf1807cdf763f0
            )

      )

  )

每个对象属性都需要被访问并存储在列中,然后将查询结果发送到api。
如何用sql语言反序列化这些数据?

b4wnujal

b4wnujal1#

我一直在努力解决一个类似的问题:反序列化和序列化表wp\u postemta中的数据,对其中的某些部分进行搜索和替换(我正在翻译woocommerce网站,我更喜欢在mysql中完成这一切,而不是使用php)。在我的例子中,搜索和替换总是发生在第四个s元素上。我为此制定了一个计划。它可能不适合您的具体用例,但可能已经足够接近您的需求:

CREATE DEFINER=`strompf`@`localhost` PROCEDURE `replace_serial`(
        in table_name_in            tinytext,   # Source table name
        in col_serial_data_src_in   tinytext,   # Column with source serialised data
        in col_serial_data_dst_in   tinytext,   # Column with destination serialised data
        in col_src_in               tinytext,   # Column with source text strings
        in col_dst_in               tinytext    # Column with desination text string
    )
BEGIN

# 

# Find-and-replace in element s4 within serialised content

################################################################################ 

# 

# * This sproc "replace_serial" needs as input pointers to a table

# ("pointer table") with the following columns:

# * Column with the source serialised data

# * Column for storing the updated serialised data

# * Column with find-string

# * Column with replace-strings

# * It can be any table: The arguments for replace_serial() contains the name

# of this table and the names of those four columns

# * Internally, data from this input-table is copied to temporary table

# "serial_tmp"

# * The designated serialised data is decomposed into several fields (again,

# in table "serial_tmp") - Currently, this sproc only works for serialised

# data with 1 a-element, followed by 6 s-elements. This sproc has not been

# tested with other configurations

# * Find-and-replace is only performed on element s4 (=the 4th s-element)

# * Subsequently, the new length of s4 is calculated, and the serialised string

# is written to the designated column in the "pointer table"

# * Subsequently, it's up to the programmer to process the resulting data in

# the pointer table

# * This approach with a "pointer table" works really well: Easy to grasp,

# flexible and easy to debug. It's especially handy for debugging or further

# processing that the output is in a separate column from the input.

# * Copyright Jeroen Strompf - De Vliegende Brigade - 2021.03.09

# 

# 

# History

######################################## 

# 

# * 2021.03.09: Created, tested and pushed to "bal_dwh_org"

# 

# 

################################################################################ 

# Define working table "serial_tmp"

################################################################################ 

# 

drop table if exists 
    serial_tmp;
create temporary table
    serial_tmp
    (
        serial_data_src     varchar(255)    comment "Actual serialised data",   
        serial_data_dst     varchar(255)    comment "Resulting serialised data. This is a separate field, to make debugging easier",
        find_string         varchar(255)    comment "String to be found within serial_data_src",
        replace_string      varchar(255)    comment "Replacement string for within serial_data_src, resulting in serial_data_dst",

        a_len           smallint,
        a_string        varchar(255)    comment "The string within the accolade",
        s1              varchar(255)    comment "Complete s-part, including length statement and string",
        s2              varchar(255),
        s3              varchar(255),
        s4              varchar(255)    comment "Complete s4-string",
        s4_len_src      smallint        comment "Original length of s4",
        s4_string_src   varchar(255)    comment "Original s4 string",
        s4_len_dst      smallint        comment "New length",
        s4_string_dst   varchar(255)    comment "New string",
        s5              varchar(255),
        s6              varchar(255)
    );

################################################################################ 

# Copy working data to working table

################################################################################ 

# 

set @ddl=concat
(
    "insert into serial_tmp 
    (
        serial_data_src,
        find_string,
        replace_string
    )
    select ",
        col_serial_data_src_in, ", ",
        col_src_in, ", ",
        col_dst_in, " ",
    "from ",
        table_name_in, ";"
);

prepare stmt from @ddl;
execute stmt;
deallocate prepare stmt;

################################################################################ 

# Decompose serialsed data

################################################################################ 

# 

# Leading a-field

######################################## 

# 

update
    serial_tmp
set
    a_len       = substring_index(substring_index(serial_data_src, ":", 2), ":", -1),
    a_string    = substring_index(substring_index(serial_data_src, "}",1), "{", -1);

# Complete s-fields

######################################## 

# 

update
    serial_tmp
set
    s1 = substring_index(a_string, ";", 1),
    s2 = substring_index(substring_index(a_string, ";", 2), ";", -1),
    s3 = substring_index(substring_index(a_string, ";", 3), ";", -1),
    s4 = substring_index(substring_index(a_string, ";", 4), ";", -1),
    s5 = substring_index(substring_index(a_string, ";", 5), ";", -1),
    s6 = substring_index(substring_index(a_string, ";", 6), ";", -1);

# Further decompose s4

######################################## 

# 

update
    serial_tmp
set
    s4_len_src      = substring_index(substring_index(s4, ":", 2), ":", -1),
    s4_string_src   = substring_index(substring_index(s4, '"', 2), '"', -1);

################################################################################ 

# Find-and-replace

################################################################################ 

# 

# Finally! The heart of the matter

# 

update
    serial_tmp
set
    s4_string_dst   =   replace(s4_string_src, find_string, replace_string),
    s4_len_dst      =   length(s4_string_dst);

################################################################################ 

# Reassemble

################################################################################ 

# 

update
    serial_tmp
set
    serial_data_dst = concat
    (
        "a:",a_len, ":",
        "{",
            s1, ";", s2, ";", s3, ";",
            "s:",s4_len_dst,":",
            char(34),
                s4_string_dst,
            char(34),
            ";", s5, ";", s6, ";",
        "}"
    );

################################################################################ 

# Copy results back to the original input table

################################################################################ 

# 

# * Fill in the result in column "col_serial_data_dst_in"

# 

set @ddl2=concat
(
    "update ", table_name_in, " 
    join 
       serial_tmp
       on
       serial_tmp.serial_data_src = ", table_name_in, ".",col_serial_data_src_in," 
    set
       ",table_name_in, ".",col_serial_data_dst_in, " = serial_tmp.serial_data_dst;"
);

prepare stmt from @ddl2;
execute stmt;
deallocate prepare stmt;

END
olhwl3o2

olhwl3o22#

serialize php函数将数据结构序列化为php特有的字符串表示形式,并可以使用unserialize将其反转为php对象。
mysql不知道php序列化是什么。你不能只使用sql。

相关问题