如何更新oracle中TimeStamp的json属性

gj3fmq9x  于 2022-12-20  发布在  Oracle
关注(0)|答案(2)|浏览(189)

我有一个列audit_info与JSON数据在表中:

{
  "AddInfo":{
    "UPN":"abc@abc.com",
    "UserName":"abc@abc.com",
    "TimeStamp":"2021-10-11T15:54:34:4805634Z",
    "Source":"xyz"
  },
  "ChangeInfo":{
    "UPN":"abc@abc.com",
    "UserName":"abc@abc.com",
    "TimeStamp":"2021-10-11T15:54:34:4832421Z",
    "Source":"xyz"
  }
}

我需要将秒小数点的时间戳从:4832421Z更新为.4832421Z
有人能帮帮我吗?

update the_table
  set audit_info=??
n3h0vuf2

n3h0vuf21#

原始问题:

如果在其他地方没有{:},则可以使用replace:

UPDATE table_name
SET audit_info = REPLACE(audit_info, '{:}', '{.}');

fiddle

更新问题:

在更高的Oracle版本中,如果要将路径$.AddInfo.TimeStamp$.ChangeInfo.TimeStamp中的最后一个:更新为.,则可以使用use JSON_TABLE提取时间戳,然后使用简单的字符串函数提取最后一个:之前和之后的组件,然后使用JSON_MERGEPATCH更新特定路径:

MERGE INTO table_name dst
USING (
  SELECT t.ROWID AS rid,
         JSON_OBJECT(
           KEY 'AddInfo' VALUE JSON_OBJECT(
             KEY 'TimeStamp'
             VALUE SUBSTR(addinfo_ts, 1, INSTR(addinfo_ts, ':', -1) - 1)
                   || '.' || SUBSTR(addinfo_ts, INSTR(addinfo_ts, ':', -1) + 1)
           ),
           KEY 'ChangeInfo' VALUE JSON_OBJECT(
             KEY 'TimeStamp'
             VALUE SUBSTR(changeinfo_ts, 1, INSTR(changeinfo_ts, ':', -1) - 1)
                   || '.' || SUBSTR(changeinfo_ts, INSTR(changeinfo_ts, ':', -1) + 1)
           )
         ) AS patch
  FROM   table_name t
         CROSS APPLY JSON_TABLE(
           t.audit_info,
           '$'
           COLUMNS
             addinfo_ts   VARCHAR2(30) PATH '$.AddInfo.TimeStamp',
             changeinfo_ts VARCHAR2(30) PATH '$.ChangeInfo.TimeStamp'
          ) j
) src
ON (src.rid = dst.ROWID)
WHEN MATCHED THEN
  UPDATE
  SET audit_info = JSON_MERGEPATCH(audit_info, src.patch);

然后,对于样本数据,在MERGE之后,表格包含:
| 审计信息|
| - ------|
| {"AddInfo":{"UPN":"abc@abc.com","UserName":"abc@abc.com","TimeStamp":"2021-10-11T15:54:34.4805634Z","Source":"xyz"},"ChangeInfo":{"UPN":"abc@abc.com","UserName":"abc@abc.com","TimeStamp":"2021-10-11T15:54:34.4832421Z","Source":"xyz"}} |
如果您不想担心特定的路径,那么您可以使用正则表达式来匹配时间戳:

UPDATE table_name
SET audit_info = REGEXP_REPLACE(
                   audit_info,
                   '("TimeStamp"\s*:\s*"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}):(\d+Z")',
                   '\1.\2'
                 );

fiddle

zkure5ic

zkure5ic2#

尝试replace,将json字段替换为文本,然后再转换为json,应该是这样的:
update [表的名称] set审计信息= replace(审计信息::文本,“:”,.“”)::jsonb其中....

相关问题