我一直在思考我实际上可以在替换变量中投入多少。我们只能用它代替单个“实体”而不是命令字符串吗?我发现如果我想替换实际的SQL块,则无法正常工作(在SqlDeveloper中)。
我想知道如何解决这个问题...
/*------test--------------*/
CREATE TABLE Test_Persons (
PersonID int,
LastName varchar(255),
FirstName varchar(255)
);
INSERT INTO Test_Persons
(PersonID,LastName,FirstName)
values(1,'LN_1','FN_1');
INSERT INTO Test_Persons
(PersonID,LastName,FirstName)
values(2,'LN_2','FN_2');
INSERT INTO Test_Persons
(PersonID,LastName,FirstName)
values(3,'LN_21','FN_2');
commit;
--------------sub-table, worked!---
set define #;
define first_name_input = 'FN_2';
define last_name_input = 'LN_2';
define tbl_Test_Persons = 'Test_Persons';
define temp_tbl_Test_Persons_FN = 'Test_Persons_FN';
with
#temp_tbl_Test_Persons_FN as
(
select * from #tbl_Test_Persons tp
where tp.FIRSTNAME = '#first_name_input'
)
select * from #temp_tbl_Test_Persons_FN tp
where tp.LASTNAME = '#last_name_input';
set define off;
--------------sub-table, replace the entire with clause, does NOT work - 'Invalid value for DEFINE command.'!---
set define #;
define first_name_input = 'FN_2';
define last_name_input = 'LN_2';
define tbl_Test_Persons = 'Test_Persons';
define temp_tbl_Test_Persons_FN = 'Test_Persons_FN2';
define with_clause = '
with
#temp_tbl_Test_Persons_FN as
(
select * from #tbl_Test_Persons tp
where tp.FIRSTNAME = ''#first_name_input''
)
';
#with_clause
select * from #temp_tbl_Test_Persons_FN tp
where tp.LASTNAME = '#last_name_input';
set define off;
答案 0 :(得分:1)
From the documentation(适用于SQL * Plus,但也适用于SQL Developer):
如果已定义变量的值跨越多行(使用SQL * Plus命令延续字符),则SQL * Plus会用空格替换每个延续字符和回车符。
SQL Developer实际上在行为上稍有不同,并且将延续字符留在字符串中,这没有帮助。但是还会留下换行符,因此您可以将连续字符从-
翻倍到--
以阻止它引起问题,然后将其视为注释;所以你可以这样做:
define with_clause = '--
with--
#temp_tbl_Test_Persons_FN as--
(--
select * from #tbl_Test_Persons tp--
where tp.FIRSTNAME = ''#first_name_input''--
)--
';
但是还有一个更复杂的情况,因为#with_clause
未被识别为命令-因为您还没有进入命令替换,所以不会发生。您可以使用子查询来解决这个问题,
select * from (
#with_clause
select * from #temp_tbl_Test_Persons_FN tp
where tp.LASTNAME = '#last_name_input'
);
这不理想。但是,如果执行此操作,脚本输出窗口将显示正在发生的替换,并返回上一行:
old:select * from (
#with_clause
select * from #temp_tbl_Test_Persons_FN tp
where tp.LASTNAME = '#last_name_input'
)
new:select * from (
--
with--
Test_Persons_FN2 as--
(--
select * from Test_Persons tp--
where tp.FIRSTNAME = 'FN_2'--
)--
select * from Test_Persons_FN2 tp
where tp.LASTNAME = 'LN_2'
)
PERSONID LASTNAME FIRSTNAME
---------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 LN_2 FN_2
(此外,有趣的是,如果您使用#
作为替换字符,此方法在SQL * Plus中仍然不起作用-您得到“ ORA-24333:零迭代计数”。它没有得到该错误虽然使用&
;我没有尝试过任何其他方法,但是您必须返回一个串联字符,但是即使进行了这些更改,它仍然不能正确替代with
子句。为什么呢。)