SQL脚本中的分号问题
Posted
技术标签:
【中文标题】SQL脚本中的分号问题【英文标题】:Semicolon issue in SQL script 【发布时间】:2019-06-27 17:15:57 【问题描述】:我需要使用包含分号的存储过程更新列值,这会导致“引用的字符串未正确结束”的问题。
使用 Putty 连接到服务器并使用 SQL Plus 执行命令
尝试使用 /;但它没有工作
update dummy_table
set
col1 = 0, col2 = null, col3 = to_clob(
'declare
source_table varchar2(40) := :par1;
target_table_name varchar2(40) := :par2;
'||'
begin '||'
select * from temp_table;
end;
'||'/'
), col4 = null
where col5 = 'value_1' and col6 = 'value_7';
ER:命令应该成功执行,它应该用给定的值更新 col3
AR:带引号的字符串没有正确结束
【问题讨论】:
@ADyson 我的印象是 OP 试图使用双杠运算符连接以确保在此处生成的col3
SQL 字符串中存在换行符。我觉得使用SET SQLBLANKLINES ON
可能会更好地完成此操作,但我不是这里的专家。
这不是“逃避问题”。是的,'||'
中的第一个单引号结束了字符串文字,但是该字符串文字后面是 ||
连接运算符,然后是一个单引号,该单引号开始另一个字符串文字。 OP 观察到的行为本身不是 SQL 问题,它是 sqlplus 在遇到分号时过早识别语句的结尾。
【参考方案1】:
分号告诉 SQLPlus 你想运行你输入的命令。它不会首先看到您位于带引号的字符串的中间。 要停止此操作,请将您的整个命令包含在其自己的块中,其中分号将被视为该块的一部分,并且不要尝试执行您到目前为止输入的内容。块被 BEGIN 和 END 关键字包围。通过在单独的行中输入句点来告诉 SQLPlus 完成,然后通过输入斜杠来运行该块。
所以,如果您在 SQL*Plus 中输入,它看起来像这样:
BEGIN
update dummy_table
set
col1 = 0, col2 = null, col3 = to_clob(
'declare
source_table varchar2(40) := :par1;
target_table_name varchar2(40) := :par2;
'||'
begin '||'
select * from temp_table;
end;
'||'/'
), col4 = null
where col5 = 'value_1' and col6 = 'value_7';
END;
.
/
【讨论】:
SQLPlus 从什么时候开始在一行中使用.
?
@a_horse_with_no_name 打败了我。请参阅此页面上的“运行 PL/SQL 块”部分:docs.oracle.com/cd/E11882_01/server.112/e16604/…【参考方案2】:
您可以使用以下解决方案中提到的 Oracle 的替代引用机制技术:
UPDATE DUMMY_TABLE
SET
COL1 = 0,
COL2 = NULL,
COL3 = TO_CLOB('declare
source_table varchar2(40) := :par1;
target_table_name varchar2(40) := :par2;
'
|| '
begin '
|| '
select * from temp_table;
end;
'
|| q'#/#'),
COL4 = NULL
WHERE
COL5 = 'value_1'
AND COL6 = 'value_7';
字符串,包含任何特殊的 oracle 保留字符,如果您想将其视为字符串,则需要使用带引号的字符串:q'<Special symbol><Your string><Special symbol>'
。
请参考Oracle文档中的Alternative Quoting Mechanism技术。
【讨论】:
【参考方案3】:SQLPlus 似乎不喜欢行尾的分号,无论它们是否是带引号的字符串的一部分。这有效,它与您的语句相同,但添加了换行符 (CR+LF):
update dummy_table
set
col1 = 0, col2 = null, col3 = to_clob(
'declare
source_table varchar2(40) := :par1;' || chr(10) || chr(13) ||'
target_table_name varchar2(40) := :par2;' || chr(10) || chr(13) ||'
'||'
begin '||'
select * from temp_table;' || chr(10) || chr(13) ||'
end;' || chr(10) || chr(13) ||'
'||'/'
), col4 = null
where col5 = 'value_1' and col6 = 'value_7';
【讨论】:
【参考方案4】:set sqlterminator off
update dummy_table
set
col1 = 0, col2 = null, col3 = to_clob(
'declare
source_table varchar2(40) := :par1;
target_table_name varchar2(40) := :par2;
'||'
begin '||'
select * from temp_table;
end;
'||'/'
), col4 = null
where col5 = 'value_1' and col6 = 'value_7'
/
set sqlterminator on
【讨论】:
您应该编辑您的问题,以便解释您的工作以及它如何解决问题。 为什么这被否决了。它似乎解决了操作的问题(和我的)以上是关于SQL脚本中的分号问题的主要内容,如果未能解决你的问题,请参考以下文章