【问题标题】:Generate random ROWID生成随机 ROWID
【发布时间】:2015-06-09 19:03:45
【问题描述】:

我正在尝试创建一个随机 ROWID 用于测试目的。我知道这不是要走的路,但是由于我还没有数据,所以我只需要保证在插入 ROWID 的“值”时(使用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 在 [-2^^31, 2^^31) 中生成整数。
  • DBMS_RANDOM.VALUE 生成 [0,1) 中的数字,精度为 38 位。

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

【问题讨论】:

  • 您不能创建“随机 ROWID” - ROWID 是表空间内一行的物理位置。您打算如何处理可能甚至不指向有效行的随机位置?或者可能是来自不同表的一行?您要解决的根本问题到底是什么?
  • 从真实表中获取随机行的真实 ROWID 不是更容易吗(例如 SYS.OBJ$,如果您还没有自己的数据)? (无论如何,存储 ROWID 似乎很奇怪;but is usually safe
  • 我有一个类型,其中一个属性是 rowid。该 rowid 值将被插入到表中。我只需要一个随机的 ROWID 值,这样它就可以“通过”ROWIDTOCHAR 函数。谢谢亚历克斯。我会试试的,把它做成一个遮阳篷,这样我就可以接受了。我知道这很奇怪,但我不是设计架构的人:x

标签: oracle random plsql rowid


【解决方案1】:

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

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

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

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


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

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 开始而不是那些)。

正如 David Aldridge 所说,其中一些参数会有限制(您可以从 documentation 推断出这些参数,但除此之外它们没有经过验证;并且重复运行会给出不同的值:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      此函数不检查结果数字是否真正寻址到特定数据段中的有效行。

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

      select * from t sample(5);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-21
        • 2023-01-03
        • 1970-01-01
        • 1970-01-01
        • 2012-09-29
        • 1970-01-01
        相关资源
        最近更新 更多