问题
I'd like to run a query that gets a combination of live data and metadata for a regularly changing list of table names. This is for research & analysis on a large server with 100+ schemas and thousands of tables/views in each. I need help referring to table names dynamically, which I do understand is NOT possible. However...
My googling indicates the solution may be an SQL statement in a text variable, which is then executed by the EXEC statement. But this is DB2/400 v7r3, which is a complex thing (as is its SQL reference on the IBM web site), and I'm having difficulty creating correct syntax.
Here is a basic example of what I wish to do, but of course it does not work:
SELECT TABLE_NAME,
TABLE_TEXT,
( SELECT COUNT(*) FROM TABLE_NAME ) AS ROW_COUNT
-- above line of course does not work
FROM QSYS2.SYSTABLES
WHERE TABLE_SCHEMA = 'ABCDEFGH'
AND TABLE_NAME IN ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'DAILYHT', 'ETC')
I understand I need something like the following, but I cannot figure out the correct statements:
DECLARE @sqltext AS VARCHAR(128)
SELECT TABLE_NAME,
TABLE_TEXT,
( SET @sqltext = 'SELECT COUNT(*) FROM ABCDEFGH.' || TABLE_NAME
EXEC sqltest ) AS ROW_COUNT --this is probably wrong
FROM QSYS2.SYSTABLES
WHERE TABLE_SCHEMA = 'ABCDEFGH'
AND TABLE_NAME IN ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'ETC', 'ETC', 'ETC')
ORDER BY TABLE_NAME
回答1:
Dynamic SQL isn't difficult...
Basically, build your SQL statement into your string variable. Using CONCAT
to include values from other
@sqlStmt = 'Insert into mytable values (''ConstVal'',' concat SomeVar concat ')';
execute immediate @sqlStmt;
The catch is that you have to escape strings, like 'ConstVal' above with double single quotes.
The other catch is that you can't use SELECT
like you are trying to. If you only had one row to return, SELECT INTO
would be an option for a static statement. But isn't supported for dynamic. You have to use a dynamic VALUES INTO
instead.
However, it appears you want to get back multiple rows. In which case, you need to use a cursor. Unfortunately, dynamic cursors are a bit more complex as you have to use the SQL Descriptor.
declare myCursor cursor for myStatement;
set @sqlStmt = 'select ....';
prepare myStatement into mySqlDescriptor from @SqlStmt;
open myCursor;
// done if you are returning the results
// assuming you want to process in your procedure..
// add a loop that does
// fetch next from myCursor into myData;
Having said all that, you don't need any of it to get a row count for a table...the syspartitionstat catalog view already has that info.
select table_name, number_rows
from syspartitionstat
where table_schema = 'ABCDEFGH'
and TABLE_NAME in ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'ETC', 'ETC', 'ETC');
来源:https://stackoverflow.com/questions/53196938/refer-to-table-name-dynamically-in-db2-400-sql-query