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;