问题描述
"users":"John","Level":"1","list":[
{"id":"1","price1":"100.50","price2":"90.50"},{"id":"2","price1":"100.60","price2":"80.50"},"price1":"105.50","price2":"700.50"}
]}
对于信息 JSON 没有义务,但它对我来说似乎是最简单的。但也许创建一个 POSTGRES 类型可以工作。
如果我使用 JSON 或 PostGres 类型,那么如何处理对象。
CREATE OR REPLACE FUNCTION MYFUNCTION(myobject JSON ? CREATE TYPE ? )
RETURNS TABLE (
"OK" BOOLEAN,"NB" VARCHAR
)
AS $$
DECLARE
BEGIN
-- I would like to get for each object in the list the price1 and price2 to
compare them.
END; $$
LANGUAGE 'plpgsql';
解决方法
问题的关键似乎是如何从 json 对象中提取值。这是一种方式:
select * from json_to_recordset('{
"users":"John","Level":"1","list":[
{"id":"1","price1":"100.50","price2":"90.50"},{"id":"2","price1":"100.60","price2":"80.50"},"price1":"105.50","price2":"700.50"}
]}'::json->'list') as foo(id int,price1 numeric,price2 numeric);
使用 json 变量代替文字字符串:
select * from json_to_recordset(jsonvariable->'list') as foo(id int,price2 numeric)
注意。您提供的 json 对象不合法。缺少一些逗号。我还建议您使用 jsonb 而不是 json。
编辑:这是一个关于如何在 plpgsql 函数中使用它的骨架:
create or replace function func(jsonvariable json) returns table (ok boolean,nb text) as
$BODY$
declare
r record;
begin
for r in (select * from json_to_recordset(jsonvariable->'list') as foo(id int,price2 numeric)) loop
--- DO THINGS
ok:=(r.price1>r.price2);
nb:='this is text returned';
return next;
end loop;
end;
$BODY$
language plpgsql;
,
无需使用循环处理 JSON ARRAY。您可以使用 #!/usr/bin/env python3
import os
import subprocess
import sys
def execute_git_command(*args):
arguments = ['git']
for arg in args:
arguments.append(arg)
git_command = subprocess.Popen(arguments,stdout=PIPE,stderr=PIPE)
git_stdout,git_stderr = git_command.communicate()
if git_command.returncode != 0:
sys.stderr.write(
'Git command "{0}" failed with code {2}. Reason: {1}'.format(' '.join(arguments),git_stderr.decode(),git_command.returncode))
exit()
return git_stdout.decode()
def just_execute_git_command(*args):
arguments = ['git']
for arg in args:
arguments.append(arg)
git_command = subprocess.Popen(arguments,git_stderr = git_command.communicate()
return git_stdout.decode()
if len(sys.argv) != 4:
print("Usage: {0} previous_upstream_commit new_upstream_commit our_commit_for_merge".format(sys.argv[0]))
exit()
old_upstream_commit = sys.argv[1]
new_upstream_commit = sys.argv[2]
our_commit_to_merge = sys.argv[3]
PIPE = subprocess.PIPE
print("Trying to merge commit id {0} to {1}".format(our_commit_to_merge,new_upstream_commit))
changed_by_us = execute_git_command('diff','--name-only',old_upstream_commit + ".." + our_commit_to_merge,'--','./',':(exclude)./some/folders/to/exclude/*')
affected_files = set()
for line in changed_by_us.splitlines():
affected_files.add(line)
print("{0} files affected by our changes".format(len(affected_files)))
print("Checkingout commit id " + new_upstream_commit)
execute_git_command('checkout',new_upstream_commit)
execute_git_command('submodule','sync','--recursive')
execute_git_command('submodule','update','--init','--recursive')
print("Creating new branch for it upstream_merge_" + new_upstream_commit)
just_execute_git_command('checkout','-b',"upstream_merge_" + new_upstream_commit)
just_execute_git_command('merge',our_commit_to_merge)
gitBranch = execute_git_command('branch','--show-current')
print("Commit {0} merged to branch {1}".format(our_commit_to_merge,gitBranch))
mergeAffectedFiles = execute_git_command('ls-files')
if len(mergeAffectedFiles.splitlines()) > 0:
print("Will checkout files not affected by ours changes in upstream favor")
for full_path in mergeAffectedFiles.splitlines():
# print(conflictingFile)
# full_path = conflictingFile
# filename = os.path.basename(full_path)
if full_path not in affected_files:
just_execute_git_command('reset','--hard',full_path)
mergeAffectedFiles = execute_git_command('ls-files','--unmerged')
print("{0} conflicting files left for manual resolution.".format(len(mergeAffectedFiles.splitlines())))
或 JSONB_ARRAY_ELEMENTS
来满足您的要求,如下所示:
使用 JSONB_TO_RECORDSET
JSONB_TO_RECORDSET
使用 JSONB_ARRAY_ELEMENTS
CREATE OR REPLACE FUNCTION MYFUNCTION(myobject JSONB)
RETURNS TABLE (ok BOOLEAN,nb VARCHAR)
AS
$$
BEGIN
return query
select
price1>price2,-- you can change the condition here
id::varchar -- you can change the value as per your requirement
from jsonb_to_recordset(myobject ->'list') as x(id int,price2 numeric);
END;
$$
LANGUAGE 'plpgsql';