【问题标题】:pl/sqL add line to file once before for loop using dbms_output.put_linepl/sql 在 for 循环之前使用 dbms_output.put_line 在文件中添加一次
【发布时间】:2021-10-16 18:15:36
【问题描述】:

我有一个从 bash 脚本运行并在磁盘上生成平面文件的脚本。 我需要在循环之前添加一些任意文本

set serveroutput on
whenever sqlerror exit sql.sqlcode;
set echo off
SET VERIFY OFF
set heading off
SET FEEDBACK OFF
set serveroutput on size unlimited
set linesize 300
alter session set current_schema = SCOTT;
ALTER session SET TIME_ZONE='GMT';
BEGIN
FOR policy IN (
SELECT
     "A3"."POLICY_NAME" as policy_name,
     count("A1"."CERT_SERIAL_NUM") as total
FROM
    (
      SELECT POLICY_ID FROM POLICY_DOMAIN_PATH_MAP_TBL
      MINUS
      SELECT POLICY_ID FROM POLICY_DOMAIN_PATH_MAP_TBL WHERE ACTION=1 AND PATH_ID IN (-4,-2)
    ) A0
    join "POLICY_TBL"               "A3"
        on A0.POLICY_ID = "A3"."POLICY_ID"
    left join "CERTIFICATE_TBL"          "A2"
        on "A3"."POLICY_ID" = "A2"."POLICY_ID"
        and "A2"."ISSUE_DATE" >=  CURRENT_TIMESTAMP - (10/1440)
    left join "CERT_STATUS_CHECK_TBL"    "A1"
        on "A1"."CERT_SERIAL_NUM" = "A2"."CERT_SERIAL_NUM"
        AND "A1"."STATUS" = '0'
GROUP BY
    policy_name
order by 2 desc
    )
    LOOP
    dbms_output.put_line('cert{policy=' ||'"' ||policy.policy_name || '"' || ',instance="SCOTT"} ' || policy.total);
    END LOOP;
END;
/

这会产生以下输出:

cert{policy="CUS CAO",instance="SCOTT"} 0
cert{policy="CUS RAX",instance="SCOTT"} 0
cert{policy="COL Application Encryption (SOFT) V1.3",instance="SCOTT"} 0
cert{policy="COL Application Signing (SOFT) V1.2",instance="SCOTT"} 0

我想在循环开始之前添加一行,使文件看起来像这样

# line added
cert{policy="CUS CAO",instance="SCOTT"} 0
cert{policy="CUS RAX",instance="SCOTT"} 0
cert{policy="COL Application Encryption (SOFT) V1.3",instance="SCOTT"} 0
cert{policy="COL Application Signing (SOFT) V1.2",instance="SCOTT"} 0

这个 pl/sql 脚本是从 bash 脚本中调用的。我应该使用 awk 在 bash 中手动添加该行吗?我更喜欢用 sql 来做(如果可能的话)

这是 bash 调用 pl/sql 的部分:

{
$ORACLE_HOME/bin/sqlplus -s /nolog      <<EOF1
connect SCOTT/${DBPASSWD}@${Oracle_sid}
        whenever sqlerror exit sql.sqlcode;
        set echo off
        set heading off
        set serveroutput on
        @cert3.sql
EOF1
} > "${prom_file}"

我尝试在 for 循环之前添加一个开始/结束块:

...
ALTER session SET TIME_ZONE='GMT';
BEGIN
  dbms_output.put_line('# add line');
END;
BEGIN
FOR policy IN (
....
END;
/

但我在主循环中的连接出现错误。

开始

  • 第 4 行出现错误:ORA-06550:第 4 行,第 1 列:PLS-00103:遇到符号“BEGIN” ORA-06550:第 15 行,第 5 列:PLS-00103: 在预期以下情况之一时遇到符号“JOIN”:) , 对于有相交减去顺序的组开始联合在哪里连接

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    您的 PL/SQL 很接近,但您可以将 dbms_output 调用放在现有的 BEGIN..END 匿名块中。

    ...
    ALTER session SET TIME_ZONE='GMT';
    BEGIN
    dbms_output.put_line('# add line');
    FOR policy IN (
    ....
    END;
    /
    

    您遇到的错误是因为当您在 SQL 脚本中有多个匿名块时,您需要在每个块后面加上 / 才能实际执行它。否则它认为第二个块仍然是第一个定义的一部分。所以这也可以:

    ...
    ALTER session SET TIME_ZONE='GMT';
    BEGIN
      dbms_output.put_line('# add line');
    END;
    /
    BEGIN
    FOR policy IN (
    ....
    END;
    /
    

    【讨论】:

      【解决方案2】:

      只需在该块内使用 bash printf 实用程序:

      {
      printf '%s\n' "# line added"                    # <---- added line
      $ORACLE_HOME/bin/sqlplus -s /nolog      <<EOF1
      connect SCOTT/${DBPASSWD}@${Oracle_sid}
              whenever sqlerror exit sql.sqlcode;
              set echo off
              set heading off
              set serveroutput on
              @cert3.sql
      EOF1
      } > "${prom_file}"
      

      由于您已经有了用于创建分组的大括号,因此在开头添加 printf 会将输出添加到 sqlplus 输出之前。

      【讨论】:

        猜你喜欢
        • 2013-07-21
        • 1970-01-01
        • 2016-09-27
        • 1970-01-01
        • 1970-01-01
        • 2011-10-27
        • 1970-01-01
        • 2017-07-30
        • 1970-01-01
        相关资源
        最近更新 更多