Oracle 立即执行变量错误:数据类型不一致

问题描述 投票:0回答:1

我有一个脚本,它生成一个动态语句来捕获给定表中每列的空信息和非空信息。

我能够让脚本最初运行,但只收到消息PL/SQL 过程成功完成

经过一些额外的研究,看起来我需要将动态查询结果放入一个单独的变量中,并使用 DBMS_OUTPUT.PUTLINE 显示立即执行语句的实际结果。

这是在循环内部,因此它应该只有一个字符串作为要运行的查询结果,所以我认为 BULK COLLECT INTO 不是正确的选项。 也就是说,如果是的话,有人可以提供一个像样的例子,因为我尝试模仿的失败甚至比我这里的更糟糕。

非常感谢任何建议!

set serveroutput on;

DECLARE
    v_Schema ALL_TAB_COLUMNS.OWNER%TYPE;
    v_Table ALL_TAB_COLUMNS.TABLE_NAME%TYPE;
    v_columnName ALL_TAB_COLUMNS.COLUMN_NAME%TYPE;
    v_columnPosition ALL_TAB_COLUMNS.COLUMN_ID%TYPE;
    v_dataType  ALL_TAB_COLUMNS.DATA_TYPE%TYPE;
    v_sql varchar2(4000);
    v_result varchar2(4000);
    
    CURSOR c1 IS 
    SELECT OWNER, TABLE_NAME, COLUMN_NAME, COLUMN_ID, DATA_TYPE FROM ALL_TAB_COLUMNS WHERE OWNER = '<my_schema>' AND table_name='<my_table>';

BEGIN
    OPEN c1;
      LOOP
        FETCH c1 INTO v_Schema, v_Table, v_columnName, v_columnPosition, v_dataType;
        EXIT WHEN c1%NOTFOUND;
        
        v_sql := 'SELECT  ''' 
        ||  v_Table  || ''' AS TableName '
        ||',''' || v_columnName || ''' AS ColumnName '
        ||',''' || TO_CHAR(v_columnPosition) || ''' AS ColumnPosition '
        ||',COUNT(CASE WHEN ' || v_columnName || ' IS NULL THEN 1 ELSE NULL END) AS CountNulls'
        ||',COUNT(CASE WHEN ' || v_columnName || ' IS NULL THEN NULL ELSE 1 END) AS CountnonNulls '
        ||',COUNT(*) AS TotalRows '
        ||',COUNT(CASE WHEN ' || v_columnName || ' IS NULL THEN 1 ELSE 0 END) / CASE WHEN COUNT(*) <> 0 THEN COUNT(*) ELSE .001 * 100 END AS PercentNull '
        ||',COUNT(CASE WHEN ' || v_columnName || ' IS NULL THEN NULL ELSE 1 END) / CASE WHEN COUNT(*) <> 0 THEN COUNT(*) ELSE 0.1 END * 100 AS PercentNotNull '
        || 'FROM ' || v_Table;
    
        EXECUTE IMMEDIATE v_sql;
    
      END LOOP;
      
    CLOSE c1;

END;
sql oracle oracle-sqldeveloper
1个回答
0
投票

通过从 ALL_TAB_COLUMNS 中进行选择,您还将获得 VIEW 和 MATERIALIZED VIEW,并且查询将在所有处于无效状态的对象上失败,您应该 JOIN 于 ALL_TABLES 并仅过滤那些具有“status = 'VALID'”的对象, 但你仍然会得到MV后面的桌子,...

要返回 EXECUTE IMMEDIATE 的结果,只需添加“INTO list_of_variables_you_need_to_declare”即可。

还要注意,您将获得 Oracle 添加的所有用于处理 JSON 索引、MV 日志、全文索引、错误日志等的表。一般来说,它们的名称包含 1 个或多个“$”,您可能需要将它们过滤掉。 (并且无需重新选择您已经知道的列:table_name、column_name、column_position,...)

在任何情况下,添加异常处理和适当的日志记录将帮助您理解边缘情况。

© www.soinside.com 2019 - 2024. All rights reserved.