【问题标题】:Oracle Random Number Generator Stored Procedure without using DBMS_RANDOM不使用 DBMS_RANDOM 的 Oracle 随机数生成器存储过程
【发布时间】:2015-08-16 19:18:07
【问题描述】:

我无权访问 DBMS_RANDOM 包,因此我想创建自己的存储过程以在 Oracle 中生成随机数。有谁知道我该怎么做?

提前致谢!

编辑: 我正在尝试从每个州生成一个随机行。这是我的代码:

SELECT Z.* FROM ( 
      SELECT A.*, ROW_NUMBER() OVER (PARTITION BY A.STATE ORDER BY (
          select to_char(systimestamp,'ff') from dual)) AS ROW_ID 
        FROM   STATE_TABLE A ) Z WHERE Z.ROW_ID=1;

每次我运行它时它都会给我相同的行,但我希望它在我每次运行它时给我不同的行。请帮忙?

【问题讨论】:

  • 联系 DBA,向他们索取权限。
  • 改用dbms_crypto 包?当然,您可以查找任意数量的伪随机数生成算法并在 PL/SQL 中实现其中之一。然而,这样做是相当疯狂的——如果 DBA 不想让您访问 dbms_random 包,我很难想象他们为什么希望您构建自己的解决方案效率要低得多,标准要低得多,随机性要低得多。
  • 也许您的 DBA 会让您从 random.org 读取数据? ://
  • “我们希望尽快得到这个,所以我们试图自己创造它。” 这听起来有点矛盾。话虽如此,那个伪随机数生成器必须有多强?它的目的是什么?在许多(如果不是全部)情况下,编写自己的伪随机数生成器是个坏主意——除非你确切地知道你在做什么......
  • 强制 xkcd - xkcd.com/221。这是针对实际项目还是家庭作业?我很难想象你为什么要在真实系统中这样做,或者你如何证明在真实系统中这样做的计算成本是合理的。说您没有时间获得所需的实际权限,因此想编写自己的效率更低的随机数生成器,这使问题更加复杂,这似乎很疯狂。

标签: sql oracle stored-procedures random


【解决方案1】:

如果要从表中选择随机行,可以使用 SAMPLE 子句

SELECT * FROM mytable SAMPLE(4);

这会给你随机选择所有行的 4%。

【讨论】:

    【解决方案2】:

    如果您的 DBA 拒绝让您访问 dbms_random(出于安全原因,我经历过这种情况,但有足够的理由认为最终获得了豁免)您可以创建一个 Java 调用:

    create or replace function my_random return float as
    language java name 'java.lang.Math.random() return double';
    /
    
    select my_random from dual;
    
     MY_RANDOM
    ----------
    .411402327
    

    在您的查询中:

    SELECT Z.* FROM ( 
      SELECT A.*, ROW_NUMBER() OVER (PARTITION BY A.STATE ORDER BY my_random) AS ROW_ID 
      FROM   STATE_TABLE A
    ) Z WHERE Z.ROW_ID=1;
    

    不是说它是理想的,但它是可能的。

    【讨论】:

    • 这太完美了!非常感谢!
    【解决方案3】:

    您可以使用伪生成随机数

    select to_char(systimestamp,'ff') from dual;
    

    【讨论】:

    • 嗯,谢谢!我在我的代码中尝试了这个,但是如果我一次又一次地运行代码,它只会给我相同的行: SELECT Z.* FROM ( SELECT A.*, ROW_NUMBER() OVER (PARTITION BY A.STATE ORDER BY (select to_char(systimestamp,'ff') from dual)) AS ROW_ID FROM STATE_TABLE A) Z WHERE Z.ROW_ID=1;
    • @calgrad - 您必须确保 systimestamp 在调用之间发生变化以获得不同的小数秒数。那就是如果你输入一个查询,Oracle 只会调用一次systimestamp,所以你会为每一行得到相同的“随机数”。您可以创建一个单独的函数,在内部调用 systimestamp 并在每次执行时添加一个 dbms_lock.sleep 调用,以确保您不会只获得一堆单调递增的值。不过那会很慢。
    猜你喜欢
    • 2013-07-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多