Oracle SQL替换变量,替换的范围

Oracle SQL替换变量,替换的范围,sql,oracle-sqldeveloper,substitution,Sql,Oracle Sqldeveloper,Substitution,我一直在思考我能在替换变量中实际投入什么和多少。我们能让它只替换一个“实体”而不是一个命令字符串吗?我发现如果我想替换一个实际的SQL块,它就不起作用(在SqlDeveloper中) 我想知道我怎样才能摆脱这个 /*------test--------------*/ CREATE TABLE Test_Persons ( PersonID int, LastName varchar(255), FirstName varchar(255) ); INSERT INTO

我一直在思考我能在替换变量中实际投入什么和多少。我们能让它只替换一个“实体”而不是一个命令字符串吗?我发现如果我想替换一个实际的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;
(适用于SQL*Plus,但也适用于SQL Developer):

如果定义变量的值扩展到多行(使用SQL*Plus命令连续字符),SQL*Plus将用空格替换每个连续字符和回车

SQLDeveloper的行为实际上稍有不同,将连续字符留在字符串中,这是没有帮助的。但是is也会保留换行符,因此您可以将连续字符从
-
加倍到
-
,以防止它引起问题,因为这将被视为注释;因此,您可以:

define with_clause = '--
with--
#temp_tbl_Test_Persons_FN as--
(--
    select * from #tbl_Test_Persons tp--
    where tp.FIRSTNAME = ''#first_name_input''--
)--
';
但是还有一个更复杂的问题,因为
#with_子句
没有被识别为命令-因为您还没有处于命令替换状态,所以不会发生。您可以通过一个子查询来解决这个问题:

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:零迭代计数”。但是,
&
没有出现这种错误;我没有尝试过任何其他错误。而且您必须返回到单个连接字符。但是即使进行了这些更改,它仍然无法正确地用子句替换
。还不确定原因。)