FireBird:你如何在if中嵌入一个选择?

时间:2011-09-27 01:06:47

标签: sql stored-procedures if-statement firebird

我对FireBird很新,但我想知道如何使用select语句作为条件标准的一部分。我觉得我已经回到互联网上试图找到一种方法来做到这一点,但还没有提出太多。以下是我试图让它发挥作用。提前感谢您的帮助。

SET TERM ^ ;
ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
IF((SELECT COUNT(*)
    FROM ADDRESSES a
    WHERE a.ADDRESS_TYPE = 'Reserved'
      AND a.ALIVE = 'N'
      AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
      AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
      AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)) > 0)
THEN
  UPDATE 
    ADDRESSES a
  SET
    a.HOST_NAME = :HN,
    a.ADDRESS_TYPE = 'Assigned',
    a.NOTES = :NOTE
  WHERE
    a.SHORT_IP_ADDRESS = :IPADD;
  update_count = 1;
  SUSPEND;
ELSE
  update_count = 0;
  SUSPEND;
END^
SET TERM ; ^

GRANT EXECUTE
ON PROCEDURE sp_test TO  SYSDBA;

1 个答案:

答案 0 :(得分:0)

使用COUNT检查是否有更新记录不是最佳方式,请改用EXISTS,即IF

IF(EXISTS(SELECT 1 FROM ADDRESSES a
    WHERE a.ADDRESS_TYPE = 'Reserved'
      AND a.ALIVE = 'N'
      AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
      AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
      AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
THEN

但是您的返回值update_count似乎存在问题 - 如果执行UPDATE,则返回1,但受该语句影响的实际行数可能是其他值。我建议您使用ROW_COUNT上下文变量。所以你的程序将是

ALTER PROCEDURE sp_test (
IPADD Varchar(32),
HN Varchar(32),
NOTE Varchar(200) )
RETURNS ( update_count integer )
AS
BEGIN
  IF(EXISTS(SELECT 1 FROM ADDRESSES a
    WHERE (a.ADDRESS_TYPE = 'Reserved')
      AND (a.ALIVE = 'N')
      AND (a.HOST_NAME = '' OR a.HOST_NAME is NULL)
      AND (a.DNS_NAME = '' OR a.DNS_NAME is NULL)
      AND (a.SYSTEM_NAME = '' OR a.SYSTEM_NAME is NULL)))
  THEN BEGIN
     UPDATE ADDRESSES a SET
       a.HOST_NAME = :HN,
       a.ADDRESS_TYPE = 'Assigned',
       a.NOTES = :NOTE
     WHERE a.SHORT_IP_ADDRESS = :IPADD;
     update_count = ROW_COUNT;
  END ELSE update_count = 0;
  SUSPEND;
END^