Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
Home -> Community -> Usenet -> c.d.o.misc -> Accessing Vararray LIMIT in SQL within PL/SQL
Hi,
I try to reduce redundancy. If you change the line with comment "-- ERROR:" to refer to the vararray's LIMIT you get ORA-00904:
LINE/COL ERROR
-------- ----------------------------------------------------------------- 22/5 PL/SQL: SQL Statement ignored 28/32 PL/SQL: ORA-00904: "COMPRESS_STATS"."IND_COLS"."LIMIT": invalid identifier
Using a constant for the max varray length doesn't help, since it cannot be used in the declaration of the varray type. I tried also BULK COLLECT with LIMIT but this is only allowed for FETCH. I can get it to work by using "last_index" but this seems clunky. Is there any other way to get Oracle accept the reference to "COMPRESS_STATS"."IND_COLS"."LIMIT" in the query?
Any ideas? Thank you!
Kind regards
robert
PS: If somebody wonders what this function does: it generates an SQL statement which will output counts of unique occurrences of all combinations of leading columns from an index to help in determining whether compressing this index is a good idea.
CREATE OR REPLACE FUNCTION COMPRESS_STATS(
table_name IN VARCHAR2, index_name IN VARCHAR2, max_columns IN NUMBER DEFAULT NULL, owner IN VARCHAR2 DEFAULT USER)
TYPE column_list IS VARRAY(1000) OF VARCHAR2(100) NOT NULL;
ind_cols column_list; sql_code VARCHAR2(4000); i1 NUMBER; i2 NUMBER; last_index NUMBER; BEGIN
-- get all column names of this index
-- OK: last_index := ind_cols.LIMIT;
SELECT column_name BULK COLLECT INTO COMPRESS_STATS.ind_cols FROM all_ind_columns WHERE index_owner = COMPRESS_STATS.owner AND index_name = COMPRESS_STATS.index_name AND table_name = COMPRESS_STATS.table_name AND column_position <= 1000 -- ERROR: COMPRESS_STATS.ind_cols.LIMIT -- OK: AND column_position <= COMPRESS_STATS.last_index ORDER BY index_name ASC, column_position ASC;
-- did we limit the number of columns to output?
IF max_columns IS NOT NULL AND ind_cols.COUNT > max_columns THEN last_index := max_columns; ELSE last_index := ind_cols.COUNT; END IF;
-- create the SQL statement that will yield stats
-- start with SELECT
sql_code := 'SELECT COUNT(*) "Records"';
-- add all leading lists of column names
FOR i1 IN ind_cols.FIRST .. last_index -- ind_cols.LAST LOOP sql_code := sql_code || ', COUNT(DISTINCT '; FOR i2 IN ind_cols.FIRST .. i1 LOOP IF i2 > ind_cols.FIRST THEN sql_code := sql_code || ' || ''-'' || '; END IF; sql_code := sql_code || '"' || ind_cols(i2) || '"'; END LOOP; sql_code := sql_code || ') "COMPRESS ' || i1 || '"'; END LOOP;
-- add FROM clause
sql_code := sql_code || ' FROM "' || owner || '"."' || table_name || '"'; RETURN sql_code;