如何使用EXECUTE IMMEDIATE语句更正PL/SQL脚本中的ORA-00904错误?
下面是PL/SQL脚本,用于确定该表是否存在,然后删除/创建该表。如果该表不存在,请创建该表。因此,当我运行脚本时,我收到以下消息: ORA-00904:“E”:无效标识符 我认为语法是准确的,双引号“E”是正确的,但显然不是。请告知 谢谢如何使用EXECUTE IMMEDIATE语句更正PL/SQL脚本中的ORA-00904错误?,sql,oracle,Sql,Oracle,下面是PL/SQL脚本,用于确定该表是否存在,然后删除/创建该表。如果该表不存在,请创建该表。因此,当我运行脚本时,我收到以下消息: ORA-00904:“E”:无效标识符 我认为语法是准确的,双引号“E”是正确的,但显然不是。请告知 谢谢 DECLARE l_cnt NUMBER; BEGIN SELECT COUNT(*) INTO l_cnt FROM dba_tables WHERE owner = 'ABCD' AND table_name
DECLARE
l_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO l_cnt
FROM dba_tables
WHERE owner = 'ABCD'
AND table_name = 'SEC_REC_TEMP';
IF( l_cnt > 0 )
THEN
EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp';
EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = "E"
GROUP BY is.inv_num';
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = "E"
GROUP BY is.inv_num';
END IF;
END;
/
首先,删除并重新创建表的PL/SQL脚本非常可疑。例如,您真的确定不想创建一个只需定期刷新的物化视图吗?在PL/SQL中执行DDL几乎总是一种糟糕的方法。如果您能解释您试图解决的业务问题,我们可能会为您提供更好的技术解决方案 其次,如果要在PL/SQL中转义字符串中的单引号,则需要使用两个连续的单引号。没有一个双引号字符
DECLARE
l_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO l_cnt
FROM dba_tables
WHERE owner = 'ABCD'
AND table_name = 'SEC_REC_TEMP';
IF( l_cnt > 0 )
THEN
EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp';
EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = ''E''
GROUP BY is.inv_num';
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = ''E''
GROUP BY is.inv_num';
END IF;
END;
或者,您可以使用q引用语法
DECLARE
l_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO l_cnt
FROM dba_tables
WHERE owner = 'ABCD'
AND table_name = 'SEC_REC_TEMP';
IF( l_cnt > 0 )
THEN
EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp';
EXECUTE IMMEDIATE q'[CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = 'E'
GROUP BY is.inv_num]';
ELSE
EXECUTE IMMEDIATE q'[CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = 'E'
GROUP BY is.inv_num]';
END IF;
END;
首先,删除并重新创建表的PL/SQL脚本非常可疑。例如,您真的确定不想创建一个只需定期刷新的物化视图吗?在PL/SQL中执行DDL几乎总是一种糟糕的方法。如果您能解释您试图解决的业务问题,我们可能会为您提供更好的技术解决方案 其次,如果要在PL/SQL中转义字符串中的单引号,则需要使用两个连续的单引号。没有一个双引号字符
DECLARE
l_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO l_cnt
FROM dba_tables
WHERE owner = 'ABCD'
AND table_name = 'SEC_REC_TEMP';
IF( l_cnt > 0 )
THEN
EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp';
EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = ''E''
GROUP BY is.inv_num';
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = ''E''
GROUP BY is.inv_num';
END IF;
END;
或者,您可以使用q引用语法
DECLARE
l_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO l_cnt
FROM dba_tables
WHERE owner = 'ABCD'
AND table_name = 'SEC_REC_TEMP';
IF( l_cnt > 0 )
THEN
EXECUTE IMMEDIATE 'DROP TABLE sec_rec_temp';
EXECUTE IMMEDIATE q'[CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = 'E'
GROUP BY is.inv_num]';
ELSE
EXECUTE IMMEDIATE q'[CREATE TABLE sec_rec_temp
AS
SELECT is.inv_num
FROM abcd.inv_summ is
,abcd.bill_fee bf
WHERE is.inv_num = bf.inv_num
AND trim(bf.fee_type) = 'E'
GROUP BY is.inv_num]';
END IF;
END;
您需要用另一个单引号转义单引号
AND trim(bf.fee_type) = ''E''
您需要用另一个单引号转义单引号
AND trim(bf.fee_type) = ''E''