以下代码生成alter password语句以更改Oracle数据库中的所有标准密码。在版本12.1.0.2.0中,不再可能将其更改为无效的密码值。这就是我必须构建这个switch case结构的原因。 Toad在结尾处对连接构造发出警告(规则5807)。它说“避免使用cartesian查询 - 使用where子句......”。关于“where子句”的所有想法都适用于所有oracle数据库版本?
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 '
|| CHR (39)
|| CASE
WHEN b.version = '12.1.0.2.0' THEN '462368EA9F7AD215'
ELSE 'Invalid Password'
END
|| CHR (39)
|| ';'
FROM DBA_USERS_WITH_DEFPWD a,
(SELECT DISTINCT version
FROM PRODUCT_COMPONENT_VERSION) b;
SPOOL OFF
@user.sql
答案 0 :(得分:2)
Toad只是给你一个警告,说明你正在进行没有JOIN
条件的连接。
在这种情况下,您实际上是这样做的,但其中一个涉及的实体(来自PRODUCT_COMPONENT_VERSION
的查询)应该只返回一个值,因此问题是错误的。
你正在做一个只有1个元素的实体的笛卡尔,所以它是一个笛卡儿,但它不会乘以你的值
答案 1 :(得分:1)
不是使用旧的连接语法(没有连接条件 - 这是Toad警告的内容),您可以使用(ANSI / ISO)SQL-92连接语法并明确声明连接是{{1} }:
CROSS JOIN
由于加入的第二个表只返回一行,所以你不会增加返回的行数,SELECT 'alter user '
|| username
|| ' identified by values '
|| CHR (39)
|| CASE
WHEN b.version = '12.1.0.2.0' THEN '462368EA9F7AD215'
ELSE 'Invalid Password'
END
|| CHR (39)
|| ';'
FROM DBA_USERS_WITH_DEFPWD a
CROSS JOIN
(SELECT DISTINCT version
FROM PRODUCT_COMPONENT_VERSION) b;
不会期望连接条件(所以希望Toad会不必要地抱怨)。
稍微高效的版本(但由于涉及的行数不多,因此很少)将使用:
CROSS JOIN
然后Oracle可以在第一行之后停止从表中读取,而不必执行SELECT version FROM PRODUCT_COMPONENT_VERSION WHERE ROWNUM = 1
操作。
答案 2 :(得分:1)
在我的机器上(具有免费XE版Oracle的笔记本电脑 - 可能是最简单的安排),表PRODUCT_COMPONENT_VERSION有四行,而不是一行。有不同产品的版本,包括Oracle数据库和PL / SQL。在我的机器上,所有四行的版本都是相同的,但我不明白为什么一般应该这样做。
如果它们可能不同,首先你可以忽略告诉你交叉连接不是问题的所有答案,因为你只返回一行。你没有;你可能会返回多行。 SECOND,在您的查询中,为什么要从PRODUCT_COMPONENT_VERSION的所有行返回版本,而不仅仅是Oracle数据库的版本?我想像
这样的东西WHERE PRODUCT LIKE 'Oracle%'
应该可以工作 - 并且您在SELECT子句中不需要DISTINCT。祝你好运!