Oracle plsql switch case 和 sqlplus spool

Posted

技术标签:

【中文标题】Oracle plsql switch case 和 sqlplus spool【英文标题】:Oracle plsql switch case and sqlplus spool 【发布时间】:2016-03-31 09:23:11 【问题描述】:

以下查询在 THAN 语句处运行时出错。是否可以在 THAN 语句中使用选择?关于如何使其工作的任何想法?

SET SERVEROUTPUT ON
SET TERMOUT  OFF
SET ECHO     OFF
SET FEEDBACK OFF
SET LINESIZE 140
SET PAGESIZE 0  

exec dbms_output.enable(NULL);

SPOOL C:\test\user.sql

BEGIN

SELECT DISTINCT version,
  CASE
  WHEN version = '12.1.0.2.0' 
  THEN 
     dbms_output.put_line(''select' || 'Alter user ' || username || ' identified by values ' ||  '''EE3FD1E715941451''' || ';''); from DBA_USERS_WITH_DEFPWD;
  ELSE 
     dbms_output.put_line(''select' || 'Alter user ' || username || ' identified by values ' ||  '''Invalid Password''' || ';''); from DBA_USERS_WITH_DEFPWD;
FROM PRODUCT_COMPONENT_VERSION;
END; 

SPOOL OFF

编辑:

正在运行的代码如下所示:

spool c:/test/user.sql

select 'Alter user ' || username || ' identified by values ' ||  '''Invalid Password''' || ';'
   from DBA_USERS_WITH_DEFPWD;

spool off

假脱机输出示例:

Alter user GSMUSER identified by values 'Invalid Password';
Alter user MDSYS identified by values 'Invalid Password';
Alter user OLAPSYS identified by values 'Invalid Password';
Alter user LBACSYS identified by values 'Invalid Password';

该脚本不适用于新的 Oracle 数据库版本。自 Oracle 12.1.0.2.0 起,无法将密码设置为无效密码。我需要为这个问题建立版本识别。所有版本低于 12.1.0.2.0 的 Oracle 数据库都应使用旧脚本处理,密码应设置为“无效密码”。现在所有较新的版本都应该获得某种标准密码。

【问题讨论】:

您不能在 SELECT 语句中使用 DBMS_OUTPUT。您正在混合 SQL 和 PL/SQL。它们是不同的引擎。此外,您的 SELECT 语句实际上没有任何意义。用恰当的语言解释您的要求。 您能否发布一些示例数据和想要的结果? @LalitKumarB 他正在尝试这样做:***.com/questions/36302810/… 你遇到了什么错误? @Sathya 我明白了……他删除了那个问题。 【参考方案1】:

也许你需要这样的东西:

...
DECLARE
    vVersion varchar2(100);
BEGIN    
    /* get the version */
    SELECT DISTINCT version
    into vVersion
    from PRODUCT_COMPONENT_VERSION;
    --
    /* loop through users */
    for i in ( select * from DBA_USERS_WITH_DEFPWD) loop
        /* print a different statement, based on vVersion, for the current user */
        if ( vVersion = '12.1.0.2.0' ) then
            dbms_output.put_line('Alter user ' || i.username || ' identified by values ' ||  '''EE3FD1E715941451''' || ';');
        else
            dbms_output.put_line('Alter user ' || i.username || ' identified by values ' ||  '''Invalid Password''' || ';');
        end if;
    end loop;
END; 
...

【讨论】:

谢谢,这就是我想要做的。执行脚本仍然给我一些问题。它要求我声明版本和用户名。可以通过将 if ( version = '12.1.0.2.0' ) 更改为 if ( vVersion = '12.1.0.2.0' ) 来修复版本。但我无法修复用户名。目前它似乎没有从 DBA_USERS_WITH_DEFPWD 获取用户名。我还没有找到解决这个问题的方法。 需要使用 SET SERVEROUTPUT ON 来获取到 spool 的输出。【参考方案2】:

另一个解决问题的版本没有 PL/SQL 和正确的假脱机:

SET TERMOUT  OFF
SET ECHO     OFF
SET LINESIZE 140
SET FEEDBACK OFF
SET PAGESIZE 0

SPOOL user.sql

SELECT    'alter user ' || username || ' identified by values '''
       || CASE
             WHEN b.version = '12.1.0.2.0' THEN '462368EA9F7AD215'
             ELSE 'Invalid Password'
          END
       || ''';'
  FROM DBA_USERS_WITH_DEFPWD a,
       (SELECT VERSION
          FROM PRODUCT_COMPONENT_VERSION
         WHERE UPPER (product) LIKE '%DATABASE%') b;

SPOOL OFF
@user.sql

【讨论】:

【参考方案3】:

如果不能使用 PL/SQL:

SET TERMOUT  OFF
SET ECHO     OFF
SET LINESIZE 140
SET FEEDBACK OFF
SET PAGESIZE 0

spool user.sql

SELECT    'Alter user '
       || A.USERNAME
       || ' identified by values '
       || '''EE3FD1E715941451'''
       || ';'
  FROM DBA_USERS_WITH_DEFPWD a,
       (SELECT DISTINCT version
          FROM PRODUCT_COMPONENT_VERSION) b
 WHERE version = '12.1.0.2.0'
UNION ALL
SELECT    'Alter user '
       || A.USERNAME
       || ' identified by values '
       || '''Invalid Password'''
       || ';'
  FROM DBA_USERS_WITH_DEFPWD a,
       (SELECT DISTINCT version
          FROM PRODUCT_COMPONENT_VERSION) b
 WHERE version != '12.1.0.2.0';


 spool off
 @user.sql

【讨论】:

以上是关于Oracle plsql switch case 和 sqlplus spool的主要内容,如果未能解决你的问题,请参考以下文章

switch用法

Oracle_PlSql_Nested loop

Java 基础教程 - 使用 switch ... case 制作简易计算器

CASE 语句和 NVL 在 Oracle11G 中提供不同的输出

php switch case 问题

switch case的用法