As Heinz Z. did, I discovered the problem.
One of your function parameters is char
, while you pass the string literal 'ANY'
, which is considered a varchar
. The database engine looks for an overloaded version of the function with varchar
parameters, but doesn't find it.
Solution is either
- changing function parameter to
varchar
or cast parameter to char
in the function call:
SELECT *
FROM TABLE(TESTDAT.FNREPORT(DATE('10/23/2013'),
DATE('10/23/2013'),
CAST('ANY' AS CHAR(3))
)) AS T
If doesn't work, try in any case to remove all parameters from the function and see if they are the culprits. Then you can investigate deeper adding one by one, try to work on dates format, for example you can try to pass current date
instead of 10/23/2013.
Also you must investigate on why it thinks that FNREPORT
is a type and not a function...
I'll put this as an answer as it is easier to comment on.
Generally you need to run RUNSTATS on every table (I'd vote for at least once a week). This tells the optimizer the number of records (and if specified, which I do recommend) the distribution of data across the records. With this information the optimizer can make better decisions regarding access paths.
The optimizer also uses packages as well. REBINDING the packages essentially alters the packages (ie, their access paths) based on the RUNSTATS found.
In your case you could run RUNSTATS on the tables you care about
RUNSTATS ON TABLE <schema>.<table> WITH DISTRIBUTION AND DETAILED INDEXES ALL
If you have a lot of tables, then I'd recommend hunting for them dynamically
--do note syntax is for Unix, having to worry about escape characters and what not.
db2 -tnx "select 'runstats on table ' ||
ltrim(rtrim(tabschema))||'.'||ltrim(rtrim(tabname))
|| ' with distribution and detailed indexes all ;'
from syscat.tables where type = 'T' and ownertype = 'U' and
tabschema not in ('SYSCAT','SYSIBM','SYSIBMADM','SYSPUBLIC','SYSSTAT','SYSTOOLS')
order by tabschema asc" >> runstats.sql
You can then read this in to your database and execute it
db2 -tvf runstats.sql
REBIND
s I find the easiest to do using the db2rbind
utility. It beats having to know all the specific package names. Since we are a small shop I just tend to use the following syntax each time.
db2rbind <my db> -l rebind.log all -r any
If there are errors, you will see it in the log.
So generally you would want to issue the RUNSTATS
first, then issue a COMMIT
to release any locks. Then you can run the REBIND
s through db2rbind
. If you have not run these in a while you may wish to throw a db2 flush package cache dynamic
in between the RUNSTATS
and the db2rbind
.
Best Answer
By default the global temporary tables are created with the option
ON COMMIT DELETE ROWS
. Whatever tool you are using to run your statements must have the autocommit option turned on, so as soon as you issue the INSERT statement it is committed, thus deleting rows in the table.You should either create the table using the
ON COMMIT PRESERVE ROWS
option, or disable autocommit while running your commands and issue an explicitCOMMIT
when you are done. Which option you choose depends on your business logic.