生成随机 ROWID

Generate random ROWID

我正在尝试创建一个随机 ROWID 用于测试目的。我知道这不是要走的路,但由于我还没有数据,我只需要保证在插入 ROWID 的 "value" 时(使用 ROWIDTOCHAR 函数)我每次都有不同的字符串。

我一直在阅读 Oracle 文档 DBMS_ROWID,并且找到了一种使用 ROWID_CREATE 函数生成用于测试目的的 ROWID 的方法。

DBMS_ROWID.ROWID_CREATE (
   rowid_type    IN NUMBER, 
   object_number IN NUMBER,
   relative_fno  IN NUMBER,
   block_number  IN NUMBER,
   row_number    IN NUMBER) 
  RETURN ROWID;

我的问题是:有没有办法使用这个函数来实例化一个随机的 ROWID? (好像随机函数生成IN参数)

根据我在 DBMS_RANDOM 页面中阅读的内容

  • DBMS_RANDOM.RANDOM produces integers in [-2^^31, 2^^31).
  • DBMS_RANDOM.VALUE produces numbers in [0,1) with 38 digits of precision.

而且我不确定生成的值是否始终有效以作为 IN 参数并生成 ROWID。我只需要一个有效的 ROWID,这样我就可以使用 ROWIDTOCHAR 函数

我认为该函数非常愚蠢,因为它不会检查特定对象编号是否存在作为生成 ROWID 的一部分。不过,rowid_type 可能并非如此。

当然,许多数字都有上限,但您可以从解释格式的 ROW ID 文档中推断出这些数字。

我认为这更适合 DBA。例如,当您遇到数据文件损坏问题时。 dbv 或语句 alter database dump block 或各种数据库故障转储等工具包含数据库块地址和要传递给此函数的其他数字。所以这可以用来发现数据库中的特定数据。

此函数不检查生成的数字是否真的寻址了特定数据段中的有效行。

如果您想查看一些随机 table 数据,请使用 sample clause:

select * from t sample(5);

您可以从真实 table 中获取随机行的真实 ROWID,而不是生成您自己的随机值(它可能指向也可能不指向实际对象)。如果你没有自己的数据,你可以使用任何你能看到的 table;在 all_tables 中查找最高的 num_rows 值。

例如,您可以使用 SYS.OBJ$,如果您有直接查询的权限:

select rowidtochar(min(rowid)) from SYS.OBJ$ sample(0.001);

调整样本量,这样你总能得到一些数据,但越少越好;你仍然会得到多行,所以 min() 选择一个。当然不能保证每次都得到不同的值,但 dbms_random 也不是,而且 table 足够大应该就足够了。


如果您无法访问适当大的 table,您可以按照您的描述生成随机值:

select rowidtochar(dbms_rowid.rowid_create(
   rowid_type => 1, 
   object_number => ceil(dbms_random.value(0, 1023)),
   relative_fno => ceil(dbms_random.value(0, 1023)),
   block_number => ceil(dbms_random.value(0, 1023)),
   row_number => ceil(dbms_random.value(0, 1023))))
from dual;

对于每个整数值,这是使用重载的 dbms_random.value 函数获取范围内的值,然后使用 ceil 使其成为整数。 (您也可以截断、舍入或转换;零可能不是有效参数,因此您可能需要值范围从 1 开始,而不是从 1 开始)。

正如 David Aldridge 所说,其中一些论点会有局限性(您可以从 documentation 中推断出这些论点,但除此之外它们没有得到验证;并且 运行 反复给出不同的值:

ROWIDTOCHAR(DBMS_R
------------------
AAAAODADcAAAAOfABa
AAAAHTADOAAAANaAEb
AAAAI+ANtAAAAMuAKl
AAAAOdAI2AAAAMiAJ4
AAAADNAFAAAAAJRAIn