基于函数的返回值过滤MySQL结果集

时间:2010-03-22 12:44:42

标签: mysql stored-procedures

我是一个SQL菜鸟,我需要一些帮助来理解是否有可能的大局,如果是这样的话,如何根据传递的函数的返回值来过滤结果集记录的其中一个领域。

假设我有一个名为“Numbers”的表,只有一个字段:“Value”。

我怎样才能正确指定以下“伪sql”?:

SELECT Value FROM numbers WHERE IsPrime(Value)=true

我可以完成这样的事情,如果是的话,我在哪里/如何存储/存储“IsPrime”?

我正在使用MySQL。

3 个答案:

答案 0 :(得分:1)

我认为您可以找到有关用户定义函数的文档的一些帮助:http://dev.mysql.com/doc/refman/5.1/en/adding-functions.html

答案 1 :(得分:1)

我对用户定义的函数一无所知,但我可以想象,对于计算密集型函数,最好将该值预先计算并存储在数据库的某个地方。

根据数据在数据库中的获取方式,您可能需要客户端计算isPrime(如果客户端是您自己服务器上的Web服务或应用程序,则可以执行此操作),或者可能需要处理每个记录的预定作业isPrime是null或类似的东西。这不是即时的,但对于某些情况来说,这可能已经足够了。

如果仅使用isPrime,您还可以在检索数据时对客户端上的数据进行后处理/过滤。

答案 2 :(得分:1)

我同意extraneon,通常最好将此值存储在数据库中,而不是在where子句中计算它。这样,您可以每行计算一次并索引数据以获得更快的性能。

只要你使用的是MySQL 5.x,我就会推荐一个存储函数,而不是UDF。您可以向数据库添加IS_PRIME类型TINYINT列,在该列上添加索引,然后使用存储的函数计算插入时的值。如果您不想更改插入代码,甚至可以使用before insert触发器计算IS_PRIME值。

存储的函数看起来像这样:

DELIMITER $$

DROP FUNCTION IF EXISTS IS_PRIME $$

CREATE FUNCTION IS_PRIME(P_INT BIGINT) RETURNS TINYINT
BEGIN
  DECLARE V_FACTOR BIGINT;
  DECLARE V_MAX_FACTOR BIGINT;

  SET V_FACTOR := 2;
  SET V_MAX_FACTOR := round(sqrt(P_INT),0);

  WHILE (V_FACTOR <= V_MAX_FACTOR)
  DO
    IF (P_INT % V_FACTOR) = 0
    THEN
      RETURN FALSE;
    END IF;
    SET V_FACTOR := V_FACTOR + 1;
  END WHILE;

  RETURN TRUE;

END $$

DELIMITER ;