下面的查询是我尝试运行的PL / SQL的简化版本,仅显示了一般结构。简而言之,我正在尝试从SPECIAL_TABLE
中提取信息到变量c, d
中。
DECLARE
c NUMBER;
d NUMBER;
BEGIN
FOR all_tab IN
(SELECT * FROM all_tables)
LOOP
BEGIN
EXECUTE IMMEDIATE 'SELECT a, d INTO c, d
FROM ' || :name || '.SPECIAL_TABLE WHERE name = '''
:name || ''' AND table_name = ''' || all_tab.table_name || ''';
...
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR OCCURRED');
END;
END;
上面的查询不起作用(上面的查询我的意思是EXECUTE IMMEDIATE
),Oracle声明了905 missing keyword
。据我所知,遵循流程here。请注意,'''
是为了让我可以为'
语句转义一个SELECT
,然后一起完成整个字符串。奇怪的是,我可以按照以下代码操作,并且不会出错:
DECLARE
c NUMBER;
d NUMBER;
BEGIN
FOR all_tab IN
(SELECT * FROM all_tables)
LOOP
BEGIN
EXECUTE IMMEDIATE 'SELECT COUNT(*)
FROM ' || :name || '.SPECIAL_TABLE WHERE name = '''
:name || ''' AND table_name = ''' || all_tab.table_name || ''' INTO c;
...
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('ERROR OCCURRED');
END;
END;
唯一改变的是我正在使用MAX(...)
,并且似乎不再遵循上述超链接中的指定语法。我不确定语法部分以及它为什么能正常工作,因此MAX(...)
将确保仅返回一行。看来这可能是问题的根源,但是当我自己执行SELECT
查询时,它只返回指定了两列的单行。该表的主键为PRIMARY KEY (a, b)
,因此无论如何它都不应返回多个行。
我在这里缺少什么?如何使我的初始语句有效,以将查询结果分配给Oracle 11g中的多个变量?
答案 0 :(得分:6)
您提供的链接用于SELECT INTO
语句。使用EXECUTE IMMEDIATE
选择变量时,您必须遵循EXECUTE IMMEDIATE的规则。
所以代替这个:
EXECUTE IMMEDIATE 'SELECT x FROM myTable INTO y';
^ Incorrect: INTO is inside the string
您必须这样做:
EXECUTE IMMEDIATE 'SELECT x FROM myTable' INTO y;
^ Correct: INTO is an EXECUTE IMMEDIATE keyword
您的查询将如下所示:
EXECUTE IMMEDIATE 'SELECT a, d '
|| 'FROM ' || :name || '.SPECIAL_TABLE '
|| 'WHERE name = ''' || :name || ''' AND table_name = ''' || all_tab.table_name || ''''
INTO c, d;