立即执行oracle字符串连接问题



我在连接要立即执行的字符串时遇到问题。有人知道下面的陈述有什么问题吗?

EXECUTE IMMEDIATE 'ALTER SESSION SET smtp_out_server = " ||SMTPServer|| " ';

select smtpserver into SMTPServer from mytable;
if(SMTPServer is not null)
then
  EXECUTE IMMEDIATE 'ALTER SESSION SET smtp_out_server = ''||SMTPServer||''';
  --*****above does not work, below does work****
  EXECUTE IMMEDIATE 'ALTER SESSION SET smtp_out_server = ''10.1.1.1''';

从构建所需字符串的角度来看,您缺少了两个单引号。在SMTPServer局部变量

之前需要3个单引号,之后需要4个单引号
'ALTER SESSION SET smtp_out_server = ''' || smtpServer || ''''

就我个人而言,我发现这样做更容易,你声明一个模板(使用q引号语法,因为它嵌入了单引号),调用replace来替换模板值,然后调用EXECUTE IMMEDIATE。虽然代码有点多,但总的来说,它使工作更容易。

l_sql_stmt := q'{ALTER SESSION SET smtp_out_server = '##server##'}';
l_sql_stmt := replace( l_sql_stmt, '##server##', smtpServer );
EXECUTE IMMEDIATE l_sql_stmt;

你确定第二个语句真的有效吗?在没有数据库重启的情况下,不应该修改smtp_out_server。我看到有人说,他们已经能够在运行时使用ALTER SYSTEM成功地修改它,但还没有看到有人尝试使用ALTER SESSION。我会犹豫是否要构建依赖于违背文档的行为的代码。如果您需要在运行时控制您正在使用的SMTP服务器,我强烈建议使用utl_smtp包而不是utl_mail

为EXECUTE IMMEDIATE提供替换参数的语句并不是很好,因为对于优化器来说,每次都是完全不同的语句,因此它为每个语句准备另一个执行计划。你应该在你的EXECUTE IMMEDIATE子句中使用绑定。

的例子:

DECLARE
  SMTPServer mytable.smtpserver%type;
  l_set_smtpserver_stmt VARCHAR2(600) := q'#ALTER SESSION SET smtp_out_server = ':p_smtp_server'#'
BEGIN
  SELECT smtpserver INTO SMTPServer FROM mytable;
  IF SMTPServer IS NOT NULL THEN
  EXECUTE IMMEDIATE l_set_smtpserver_stmt USING SMTPServer;
  END IF;

  EXCEPTION
    -- handle no_data_found exception since you're using select .. into statement
    WHEN NO_DATA_FOUND THEN
        -- handle exception
    WHEN OTHERS THEN
        -- handle exception
END;
/

相关内容

  • 没有找到相关文章

最新更新