让 oracle 函数知道数据是否为素数。收到警告:创建的函数存在编译错误
For oracle function to know if data is prime or not. Getting Warning: Function created with compilation errors
想要创建一个函数,可以 return 包含质数数据类型的记录
但是收到编译错误警告。 code.I 我是 pl/sql 的初学者,有什么错误。
CREATE OR REPLACE FUNCTION isPrime (num number)
RETURN number
IS
retVal number;
BEGIN
DECLARE
prime_or_notPrime number;
counter number;
retVal:= 1;
prime_or_notPrime:= 1
counter:= 2
WHILE (counter <= num/2) LOOP
IF (mod(num ,counter)= 0) THEN
prime_or_notPrime: = 0
EXIT;
END IF;
IF (prime_or_notPrime = 1 ) THEN
retVal: = 1;
counter: = counter + 1
END IF;
END LOOP;
return retVal;
END;
/
What is the mistake in the code
DECLARE
是 function/procedure 的无效语法。您想在 IS
和 BEGIN
关键字之间声明变量。
- 那么你在
prime_or_notPrime:= 1
和 counter:= 2
之后缺少一个 ;
语句终止符。
- 那么你有:
prime_or_notPrime: = 0
而不是 prime_or_notPrime := 0;
retVal: = 1;
而不是 retVal := 1;
和
counter: = counter + 1
而不是 counter := counter + 1;
(它们在 :
和 =
之间都有一个 space,有些又缺少 ;
) .
- 您从未将
retVal
设置为 1 以外的任何值。
- 您不处理
NULL
个值或小于 2 的值。
修复(和缩进)给出:
CREATE OR REPLACE FUNCTION isPrime (num number)
RETURN number
IS
retVal number;
prime_or_notPrime number;
counter number;
BEGIN
IF NUM IS NULL OR NUM < 2 THEN
RETURN 0;
END IF;
retVal:= 1;
prime_or_notPrime:= 1;
counter:= 2;
WHILE (counter <= num/2) LOOP
IF (mod(num ,counter)= 0) THEN
prime_or_notPrime := 0;
retVal := 0;
EXIT;
END IF;
IF (prime_or_notPrime = 1 ) THEN
counter := counter + 1;
END IF;
END LOOP;
return retVal;
END;
/
注意:prime_or_notprime
变量不控制任何东西,因为一旦您将它设置为 0
,您就会从循环中 EXIT
,因此它永远不会被再次使用。注意到这一点后,您可以去掉最后的 IF
语句并始终递增计数器。
您可以将其简化为:
CREATE OR REPLACE FUNCTION isPrime (
num number
) RETURN number DETERMINISTIC
IS
BEGIN
IF NUM IS NULL OR NUM < 2 THEN
RETURN 0;
END IF;
FOR counter IN 2 .. SQRT(num) LOOP
IF MOD(num, counter) = 0 THEN
RETURN 0;
END IF;
END LOOP;
RETURN 1;
END;
/
您可以考虑改进。例如首先检查 2
作为特例,然后跳过所有其他偶数。
db<>fiddle here
想要创建一个函数,可以 return 包含质数数据类型的记录 但是收到编译错误警告。 code.I 我是 pl/sql 的初学者,有什么错误。
CREATE OR REPLACE FUNCTION isPrime (num number)
RETURN number
IS
retVal number;
BEGIN
DECLARE
prime_or_notPrime number;
counter number;
retVal:= 1;
prime_or_notPrime:= 1
counter:= 2
WHILE (counter <= num/2) LOOP
IF (mod(num ,counter)= 0) THEN
prime_or_notPrime: = 0
EXIT;
END IF;
IF (prime_or_notPrime = 1 ) THEN
retVal: = 1;
counter: = counter + 1
END IF;
END LOOP;
return retVal;
END;
/
What is the mistake in the code
DECLARE
是 function/procedure 的无效语法。您想在IS
和BEGIN
关键字之间声明变量。- 那么你在
prime_or_notPrime:= 1
和counter:= 2
之后缺少一个;
语句终止符。 - 那么你有:
prime_or_notPrime: = 0
而不是prime_or_notPrime := 0;
retVal: = 1;
而不是retVal := 1;
和counter: = counter + 1
而不是counter := counter + 1;
(它们在:
和=
之间都有一个 space,有些又缺少;
) .
- 您从未将
retVal
设置为 1 以外的任何值。 - 您不处理
NULL
个值或小于 2 的值。
修复(和缩进)给出:
CREATE OR REPLACE FUNCTION isPrime (num number)
RETURN number
IS
retVal number;
prime_or_notPrime number;
counter number;
BEGIN
IF NUM IS NULL OR NUM < 2 THEN
RETURN 0;
END IF;
retVal:= 1;
prime_or_notPrime:= 1;
counter:= 2;
WHILE (counter <= num/2) LOOP
IF (mod(num ,counter)= 0) THEN
prime_or_notPrime := 0;
retVal := 0;
EXIT;
END IF;
IF (prime_or_notPrime = 1 ) THEN
counter := counter + 1;
END IF;
END LOOP;
return retVal;
END;
/
注意:prime_or_notprime
变量不控制任何东西,因为一旦您将它设置为 0
,您就会从循环中 EXIT
,因此它永远不会被再次使用。注意到这一点后,您可以去掉最后的 IF
语句并始终递增计数器。
您可以将其简化为:
CREATE OR REPLACE FUNCTION isPrime (
num number
) RETURN number DETERMINISTIC
IS
BEGIN
IF NUM IS NULL OR NUM < 2 THEN
RETURN 0;
END IF;
FOR counter IN 2 .. SQRT(num) LOOP
IF MOD(num, counter) = 0 THEN
RETURN 0;
END IF;
END LOOP;
RETURN 1;
END;
/
您可以考虑改进。例如首先检查 2
作为特例,然后跳过所有其他偶数。
db<>fiddle here