You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用现有to_check_data存储过程实现按ID列过滤HR用户表数据

问题解答

完全可以基于现有代码实现按ID列过滤数据的需求,无需重构核心逻辑,仅需做少量调整即可,同时可以兼容原有查全量数据的调用习惯。

修改要点

  • 新增2个可选入参:p_id_col(指定要过滤的ID列名,默认空)、p_id_val(指定ID的过滤值,默认空)
  • 新增ID列合法性校验:避免传入不存在的列名导致执行报错
  • 调整动态SQL拼接逻辑:两个ID参数都非空时自动拼接WHERE过滤条件
  • 原有列遍历、类型适配、数据输出的逻辑完全复用

修改后完整存储过程代码

CREATE OR REPLACE PROCEDURE to_check_data (
    p_table IN VARCHAR2,
    p_id_col IN VARCHAR2 DEFAULT NULL,
    p_id_val IN NUMBER DEFAULT NULL
) 
IS
    TYPE t_list IS TABLE OF user_tab_columns%rowtype INDEX BY PLS_INTEGER;
    v_array         t_list;
    to_store_column VARCHAR2(32767);
    v_number        NUMBER;
    v_varchar       VARCHAR2(32767);
    v_date          DATE;
    v_cursor        PLS_INTEGER;
    v_count         PLS_INTEGER;
    v_column_name   VARCHAR2(32767);
    v_sql           VARCHAR2(32767);
    v_col_exists    NUMBER;
BEGIN
    -- 校验ID列是否存在
    IF p_id_col IS NOT NULL THEN
        SELECT COUNT(*) INTO v_col_exists
        FROM user_tab_columns
        WHERE table_name = upper(p_table) 
        AND column_name = upper(p_id_col);
        
        IF v_col_exists = 0 THEN
            RAISE_APPLICATION_ERROR(-20001, '错误:表'||p_table||'中不存在列'||p_id_col);
        END IF;
    END IF;

    -- 获取表所有列
    SELECT *
    BULK COLLECT INTO v_array
    FROM user_tab_columns
    WHERE table_name = upper(p_table);

    to_store_column := v_array(1).column_name;
    FOR i IN 2..v_array.count LOOP
        to_store_column := to_store_column || ',' || v_array(i).column_name;
    END LOOP;

    -- 拼接动态SQL,带ID过滤条件
    v_sql := 'select ' || to_store_column || ' from ' || p_table;
    IF p_id_col IS NOT NULL AND p_id_val IS NOT NULL THEN
        v_sql := v_sql || ' WHERE ' || upper(p_id_col) || ' = ' || p_id_val;
    END IF;

    v_cursor := dbms_sql.open_cursor;
    dbms_sql.parse(v_cursor, v_sql, dbms_sql.native);

    -- 定义列映射
    FOR idx IN 1..v_array.count LOOP
        IF v_array(idx).data_type = 'NUMBER' THEN
            dbms_sql.define_column(v_cursor, idx, 1);
        ELSIF v_array(idx).data_type IN ( 'VARCHAR2', 'VARCHAR', 'CHAR' ) THEN
            dbms_sql.define_column(v_cursor, idx, 'Dumy Text', v_array(idx).char_length);
        ELSIF v_array(idx).data_type = 'DATE' THEN
            dbms_sql.define_column(v_cursor, idx, sysdate);
        END IF;

        v_column_name := v_column_name || '  ' || rpad(v_array(idx).column_name, 20);
    END LOOP;

    -- 输出表头
    dbms_output.put_line(v_column_name);
    v_number := dbms_sql.execute(v_cursor);
    
    -- 输出数据行
    WHILE dbms_sql.fetch_rows(v_cursor) > 0 LOOP
        v_column_name := NULL;
        FOR t IN 1..v_array.count LOOP
            IF v_array(t).data_type = 'NUMBER' THEN
                dbms_sql.column_value(v_cursor, t, v_number);
                v_column_name := v_column_name || '  ' || rpad(nvl(to_char(v_number), ' '), 20);
            ELSIF v_array(t).data_type IN ( 'VARCHAR2', 'VARCHAR', 'CHAR' ) THEN
                dbms_sql.column_value(v_cursor, t, v_varchar);
                v_column_name := v_column_name || '  ' || rpad(nvl(to_char(v_varchar), ' '), 20);
            ELSIF v_array(t).data_type = 'DATE' THEN
                dbms_sql.column_value(v_cursor, t, v_date);
                v_column_name := v_column_name || '  ' || rpad(nvl(to_char(v_date), ' '), 20);
            END IF;
        END LOOP;
        dbms_output.put_line(v_column_name);
    END LOOP;

    dbms_sql.close_cursor(v_cursor);
EXCEPTION
    WHEN OTHERS THEN
        IF dbms_sql.is_open(v_cursor) THEN
            dbms_sql.close_cursor(v_cursor);
        END IF;
        RAISE;
END;
/

调用示例

原有全量查询逻辑仍可用

EXEC to_check_data('employees');
EXEC to_check_data('departments');
EXEC to_check_data('countries');
EXEC to_check_data('locations');

新增按ID过滤查询

-- 查询employees表中employee_id为100的记录
EXEC to_check_data('employees','EMPLOYEE_ID',100);
-- 查询departments表中department_id为10的记录
EXEC to_check_data('departments','DEPARTMENT_ID',10);

内容的提问来源于stack exchange,提问作者Aman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 16:36:03