PL/SQL 函数是 "stuck"
PL/SQL function is "stuck"
我有以下简单的 PL/SQL 函数,如果我执行脚本,它会编译而不会出现任何错误。但是,当我调用该函数时,它没有输出或错误并且没有结束。
函数:
CREATE OR REPLACE FUNCTION columns_of_table(table_name_given in varchar)
return varchar
is
to_return varchar(999) := '';
CURSOR col_cursor IS SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM user_tab_columns WHERE TABLE_NAME = table_name_given;
tab_name user_tab_columns.table_name%TYPE;
col_name user_tab_columns.COLUMN_NAME%TYPE;
data_type user_tab_columns.data_type%TYPE;
BEGIN
OPEN col_cursor;
LOOP
FETCH col_cursor into tab_name, col_name, data_type;
to_return := col_name || ' ' || data_type || ', ';
END LOOP;
to_return := SUBSTR(to_return, 1, LENGTH(to_return) - 2);
CLOSE col_cursor;
return to_return;
END;
/
添加函数并在 PLUS 中执行 SQL:
SQL> @H:\DBI\Script.sql
Funktion wurde erstellt.
SQL> select columns_of_table('rezl') from user_tables;
之后没有任何反应,也没有出现新的输入提示。
您编写了一个无限循环。
使用显式游标进行 row-by-row 处理几乎总是一个糟糕的设计决策。隐式游标的步骤要少得多(错误来源要少得多)并且通常更容易阅读。
CREATE OR REPLACE FUNCTION columns_of_table(table_name_given in varchar)
return varchar
is
to_return varchar(999) := '';
BEGIN
FOR col IN (SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM user_tab_columns
WHERE TABLE_NAME = table_name_given)
LOOP
to_return := col.column_name || ' ' || col.data_type || ', ';
END LOOP;
to_return := SUBSTR(to_return, 1, LENGTH(to_return) - 2);
return to_return;
END;
如果出于某种原因确实需要使用显式游标,则需要有一个显式 exit
语句
LOOP
FETCH col_cursor into tab_name, col_name, data_type;
EXIT WHEN col_cursor%NOTFOUND;
to_return := col_name || ' ' || data_type || ', ';
END LOOP;
当然,您也可以用更简单的 listagg
语句
代替手动循环
select listagg( column_name || ' ' || data_type, ', ' )
from user_tab_columns
where table_name = table_name_given;
我有以下简单的 PL/SQL 函数,如果我执行脚本,它会编译而不会出现任何错误。但是,当我调用该函数时,它没有输出或错误并且没有结束。
函数:
CREATE OR REPLACE FUNCTION columns_of_table(table_name_given in varchar)
return varchar
is
to_return varchar(999) := '';
CURSOR col_cursor IS SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM user_tab_columns WHERE TABLE_NAME = table_name_given;
tab_name user_tab_columns.table_name%TYPE;
col_name user_tab_columns.COLUMN_NAME%TYPE;
data_type user_tab_columns.data_type%TYPE;
BEGIN
OPEN col_cursor;
LOOP
FETCH col_cursor into tab_name, col_name, data_type;
to_return := col_name || ' ' || data_type || ', ';
END LOOP;
to_return := SUBSTR(to_return, 1, LENGTH(to_return) - 2);
CLOSE col_cursor;
return to_return;
END;
/
添加函数并在 PLUS 中执行 SQL:
SQL> @H:\DBI\Script.sql
Funktion wurde erstellt.
SQL> select columns_of_table('rezl') from user_tables;
之后没有任何反应,也没有出现新的输入提示。
您编写了一个无限循环。
使用显式游标进行 row-by-row 处理几乎总是一个糟糕的设计决策。隐式游标的步骤要少得多(错误来源要少得多)并且通常更容易阅读。
CREATE OR REPLACE FUNCTION columns_of_table(table_name_given in varchar)
return varchar
is
to_return varchar(999) := '';
BEGIN
FOR col IN (SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE
FROM user_tab_columns
WHERE TABLE_NAME = table_name_given)
LOOP
to_return := col.column_name || ' ' || col.data_type || ', ';
END LOOP;
to_return := SUBSTR(to_return, 1, LENGTH(to_return) - 2);
return to_return;
END;
如果出于某种原因确实需要使用显式游标,则需要有一个显式 exit
语句
LOOP
FETCH col_cursor into tab_name, col_name, data_type;
EXIT WHEN col_cursor%NOTFOUND;
to_return := col_name || ' ' || data_type || ', ';
END LOOP;
当然,您也可以用更简单的 listagg
语句
select listagg( column_name || ' ' || data_type, ', ' )
from user_tab_columns
where table_name = table_name_given;