Plsql—如何从函数返回json并将其使用到另一个变量或打印为json结构
我想用返回json结构的函数创建一个包,这是包中的代码: 包装规格 包体 我测试了这段代码,并在json结构被注释后打印出来** 现在,我想从另一个plsql中使用此函数,并希望使用以下代码查看结果: 案例1 但我看不到我想要的结果。我看到这个错误: 错误->案例1: 案例2 第1步: 第2步: 错误->案例2: 独立运行 函数编译正确,没有错误 但当我想使用它时:Plsql—如何从函数返回json并将其使用到另一个变量或打印为json结构,sql,oracle,plsql,oracle-apex,Sql,Oracle,Plsql,Oracle Apex,我想用返回json结构的函数创建一个包,这是包中的代码: 包装规格 包体 我测试了这段代码,并在json结构被注释后打印出来** 现在,我想从另一个plsql中使用此函数,并希望使用以下代码查看结果: 案例1 但我看不到我想要的结果。我看到这个错误: 错误->案例1: 案例2 第1步: 第2步: 错误->案例2: 独立运行 函数编译正确,没有错误 但当我想使用它时: DECLARE SALIDA CLOB; BEGIN SALIDA := otro_get_json(174, '
DECLARE
SALIDA CLOB;
BEGIN
SALIDA := otro_get_json(174, 'my_table_name');
DBMS_OUTPUT.put_line(SALIDA);
END;
/
错误->功能独立:
出了什么问题,我该如何解决
我的函数返回如下内容:
{
"my_table_name": [
{
"created": "2020-06-04T08:10:09.000000000Z",
"created_by": "APEX_APP",
"updated": "2020-06-04T10:10:09.295632000Z",
"updated_by": "APEX_APP",
"id": 174,
"text": "ALL",
"part": 2770,
"code": 2212,
"date": "2017-01-01T00:00:00.000000000Z",
"percentage": -4.98
}
]
}
但我需要查看或打印SALIDA变量
非常感谢为了复制您的错误,我将varchar2的大小减少到100,用于v_stmt
create or replace function get_emp(p_no in number,p_table_name in varchar2) return clob is
--declare
v_stmt VARCHAR2(100);
l_sep varchar2(1) := chr(10);
l_tab varchar2(1) := chr(9);
up_column VARCHAR2(50);
low_column VARCHAR2(50);
cur_asc SYS_REFCURSOR;
Vcdogcur SYS_REFCURSOR;
id_ccd number:=p_no;
--id_ccd number:= 7369;
first boolean := true;
-- json_clob clob;
begin
v_stmt := 'select *';
open cur_asc for
SELECT column_name as up_column
,lower(column_name) as low_column
FROM USER_TAB_COLUMNS
WHERE table_name = upper('p_table_name');
loop
FETCH cur_asc
INTO up_column, low_column;
EXIT WHEN cur_asc%NOTFOUND;
if not first then
v_stmt := v_stmt || ',';
end if;
first := false;
v_stmt := v_stmt || l_sep || l_tab ||up_column || ' as ' || low_column;
END LOOP;
--v_stmt := v_stmt || l_sep || 'from my_table' || l_sep ||'where id = ' || id_ccd || ';';
v_stmt := v_stmt || l_sep || 'from '||p_table_name|| l_sep ||'where empno = ' || id_ccd;
--v_stmt := v_stmt || l_sep || 'from my_table' || l_sep ||'where id = ' || id_ccd;
CLOSE cur_asc;
DBMS_OUTPUT.PUT_LINE('salida: ' || v_stmt || 'length of v_stmt: ' || to_char(length(v_stmt)));
open Vcdogcur for v_stmt;
APEX_JSON.initialize_clob_output;
APEX_JSON.open_object;
APEX_JSON.write(p_table_name, Vcdogcur);
APEX_JSON.close_object;
-- DBMS_OUTPUT.put_line(APEX_JSON.get_clob_output);
return APEX_JSON.get_clob_output;
APEX_JSON.free_output;
end;
SQL> select get_emp(7369,'emp') from dual;
ERROR:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SCOTT.GET_EMP", line 34
no rows selected
现在在增加varchar2大小之后
SQL> select get_emp(7369,'emp') from dual;
GET_EMP(7369,'EMP')
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{
"emp":[
{
"EMPNO":7369
,"ENAME":"SMITH"
,"JOB":"CLERK"
,"MGR":7902
,"HIREDATE":"1980-12-17T00:00:00Z"
,"SAL":800
,"DEPTNO":20
}
]
}
注意:-在关闭当前asc后添加长度;如果您好奇的话,可以找出v_stmt的长度。您的匿名pl/sql块没有问题,但是某个变量导致了错误,不确定它是否与您的函数相关。检查行ORA-06512:en MIBDES.HOMESERVER_UTILS,línea 48是否创建了包规范?@Sam,我期待另一种答案,我也收到了这个消息,但我不知道该怎么办。@Kumar,是的,我更新了我的问题,但是用同样的错误尝试创建没有包体的独立函数并执行它,看看它是否有效。在我的情况下,为了使它有效,我将最大大小设置为varchar2->varchar232767,现在它可以工作了。谢谢@Kumar
create table temp_json (
json_data blob not null
);
alter table temp_json
add constraint temp_data_json
check ( json_data is json );
DECLARE
SALIDA CLOB;
BEGIN
insert into temp_json (JSON_DATA) values (mibdes.homeserver_utils.get_json(174, 'my_table_name'));
END;
/
Informe de error -
ORA-06502: PL/SQL: error : buffer de cadenas de caracteres demasiado pequeño numérico o de valor
ORA-06512: en "my_schema.my_utils", línea 48
ORA-06512: en línea 14
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
CREATE OR REPLACE FUNCTION otro_get_json (id_row IN NUMBER,
table_name IN VARCHAR2) RETURN CLOB
IS
--json_clob CLOB;
v_stmt VARCHAR2(1000);
l_sep VARCHAR2(1) := Chr(10);
l_tab VARCHAR2(1) := Chr(9);
up_column VARCHAR2(50);
low_column VARCHAR2(50);
cur_asc SYS_REFCURSOR;
vcdogcur SYS_REFCURSOR;
--id_ccd NUMBER;
first BOOLEAN := TRUE;
BEGIN
--id_ccd := id_row;
v_stmt := 'select ';
OPEN cur_asc FOR
SELECT column_name AS up_column,
Lower(column_name) AS low_column
FROM user_tab_columns
WHERE table_name = Upper(table_name);
LOOP
FETCH cur_asc INTO up_column, low_column;
EXIT WHEN cur_asc%NOTFOUND;
IF NOT first THEN
v_stmt := v_stmt
|| ',';
END IF;
first := FALSE;
v_stmt := v_stmt
|| l_sep
|| l_tab
||up_column
|| ' as "'
|| low_column
|| '"';
END LOOP;
v_stmt := v_stmt
|| l_sep
|| 'from '
|| table_name
|| l_sep
||'where id = '
|| id_row;
--dbms_output.Put_line(v_stmt);
CLOSE cur_asc;
OPEN vcdogcur FOR v_stmt;
apex_json.initialize_clob_output;
apex_json.open_object;
apex_json.WRITE(table_name, vcdogcur);
apex_json.close_object;
--dbms_output.Put_line(apex_json.get_clob_output);
--json_clob := APEX_JSON.get_clob_output;
--APEX_JSON.free_output;
--CLOSE Vcdogcur;
--return json_clob;
RETURN apex_json.get_clob_output;
END;
/
DECLARE
SALIDA CLOB;
BEGIN
SALIDA := otro_get_json(174, 'my_table_name');
DBMS_OUTPUT.put_line(SALIDA);
END;
/
Informe de error -
ORA-06502: PL/SQL: error : buffer de cadenas de caracteres demasiado pequeño numérico o de valor
ORA-06512: en "my_schema.OTRO_GET_JSON", línea 34
ORA-06512: en línea 10
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
{
"my_table_name": [
{
"created": "2020-06-04T08:10:09.000000000Z",
"created_by": "APEX_APP",
"updated": "2020-06-04T10:10:09.295632000Z",
"updated_by": "APEX_APP",
"id": 174,
"text": "ALL",
"part": 2770,
"code": 2212,
"date": "2017-01-01T00:00:00.000000000Z",
"percentage": -4.98
}
]
}
create or replace function get_emp(p_no in number,p_table_name in varchar2) return clob is
--declare
v_stmt VARCHAR2(100);
l_sep varchar2(1) := chr(10);
l_tab varchar2(1) := chr(9);
up_column VARCHAR2(50);
low_column VARCHAR2(50);
cur_asc SYS_REFCURSOR;
Vcdogcur SYS_REFCURSOR;
id_ccd number:=p_no;
--id_ccd number:= 7369;
first boolean := true;
-- json_clob clob;
begin
v_stmt := 'select *';
open cur_asc for
SELECT column_name as up_column
,lower(column_name) as low_column
FROM USER_TAB_COLUMNS
WHERE table_name = upper('p_table_name');
loop
FETCH cur_asc
INTO up_column, low_column;
EXIT WHEN cur_asc%NOTFOUND;
if not first then
v_stmt := v_stmt || ',';
end if;
first := false;
v_stmt := v_stmt || l_sep || l_tab ||up_column || ' as ' || low_column;
END LOOP;
--v_stmt := v_stmt || l_sep || 'from my_table' || l_sep ||'where id = ' || id_ccd || ';';
v_stmt := v_stmt || l_sep || 'from '||p_table_name|| l_sep ||'where empno = ' || id_ccd;
--v_stmt := v_stmt || l_sep || 'from my_table' || l_sep ||'where id = ' || id_ccd;
CLOSE cur_asc;
DBMS_OUTPUT.PUT_LINE('salida: ' || v_stmt || 'length of v_stmt: ' || to_char(length(v_stmt)));
open Vcdogcur for v_stmt;
APEX_JSON.initialize_clob_output;
APEX_JSON.open_object;
APEX_JSON.write(p_table_name, Vcdogcur);
APEX_JSON.close_object;
-- DBMS_OUTPUT.put_line(APEX_JSON.get_clob_output);
return APEX_JSON.get_clob_output;
APEX_JSON.free_output;
end;
SQL> select get_emp(7369,'emp') from dual;
ERROR:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SCOTT.GET_EMP", line 34
no rows selected
SQL> select get_emp(7369,'emp') from dual;
GET_EMP(7369,'EMP')
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{
"emp":[
{
"EMPNO":7369
,"ENAME":"SMITH"
,"JOB":"CLERK"
,"MGR":7902
,"HIREDATE":"1980-12-17T00:00:00Z"
,"SAL":800
,"DEPTNO":20
}
]
}