【问题标题】:Oracle Issue with retrieving single row when multiple rows returned返回多行时检索单行的Oracle问题
【发布时间】:2016-09-21 15:29:40
【问题描述】:

我花了大约 3 天的时间解决了一个问题。

我有一个包含 6 列的表 (CDKEY):CDKEYSEQ、Userseq、Banned、Communityseq、cdkey、Email。

Banned 始终为 0(此时),除非有人使用 cdkey 登录/注册,否则 Userseq 为 NULL,并且在注册 cdkey 之前,电子邮件为 NULL。

基本上,Userseq 在用户登录之前不会被填写。因此在用户序列值之前总会有一个 email 值。

现在问题:

我正在尝试创建一个存储过程,当有人想要一个 cdkey(他们为其提供电子邮件)时调用它。

该过程首先检查名为 community 的表以确保 Community 存在。

如果社区存在,则该过程应该检查 CDKEY 表中的密钥,该密钥具有正确的社区序列,并且 USERSEQ 和 EMAIL 的值都为 NULL。

显然只使用一个选择查询是行不通的,因为返回的多行符合这些条件。

我尝试使用游标,这让我更进一步。 游标的问题是当我在 WHERE 子句之后有两个条件时,它没有返回任何内容。

这是我当前的程序代码:

create or replace PROCEDURE KEYREGISTRATION(
    PRODUCT_IN IN VARCHAR2 ,
    in_CPUID   IN LONG ,
    in_MACID   IN LONG ,
    in_MACID2  IN LONG ,
    in_HDID    IN LONG ,
    in_PCCores IN LONG ,
    in_PCName  IN VARCHAR2 ,
    in_Email   IN VARCHAR2 ,
    out_cdkey OUT VARCHAR2 ,
    returncode OUT NUMBER )
AS
  CodeSuccess       CONSTANT NUMBER := 0;
  CoreError         CONSTANT NUMBER := 2;
  CodeAlreadyExists CONSTANT NUMBER := 3;
  CodeBadProduct    CONSTANT NUMBER := 4;
  new_cdkey         VARCHAR2(50);
  old_cdkey         VARCHAR2(50);
  acommunitySeq     NUMBER;
BEGIN
acommunitySeq := 0;
new_cdkey := '';
old_cdkey := '';
  SELECT COMMUNITYSEQ INTO acommunityseq FROM COMMUNITY WHERE NAME = PRODUCT_IN;
  returncode   := CodeSuccess;
  /*EXCEPTION
    WHEN NO_DATA_FOUND THEN
      returncode := CodeBadProduct; */
  IF returncode = CodeSuccess THEN
    BEGIN
      SELECT CDKEY INTO old_cdkey FROM CDKEY WHERE EMAIL = in_email;
      returncode := CodeBadProduct;
      out_cdkey  := old_cdkey;
      RETURN;
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
      returncode := CodeSuccess;
    END;
  END IF;
  IF returncode = CodeSuccess THEN
/*SELECT CDKEY into new_cdkey FROM CDKEY WHERE EMAIL = NULL AND COMMUNITYSEQ = acommunityseq; */
   DECLARE
      CURSOR c1
      IS
        SELECT CDKEY FROM CDKEY WHERE COMMUNITYSEQ = acommunityseq AND EMAIL = NULL;
    BEGIN
      OPEN c1;
      FETCH c1 INTO new_cdkey;
      IF ( c1%notfound ) THEN
        returncode := CoreError;
      END IF; 
      UPDATE cdkey SET EMAIL = in_email WHERE CDKEY = new_cdkey;
      INSERT INTO user_hw VALUES( EMAIL = in_email, CPUID = in_cpuid,
      MACID = in_macid, MACID2 = in_macid2, CPUCORES = in_pccores, PCNAME = in_pcname;

      out_cdkey  := new_cdkey;
      returncode := CodeSuccess;

      COMMIT;
      END;
  ELSE
    returncode := CoreError;
    ROLLBACK;
  END IF;
END KEYREGISTRATION;

【问题讨论】:

  • EMAIL = NULL 不行,必须是EMAIL IS NULL
  • INSERT INTO user_hw VALUES( EMAIL = in_email, CPUID = in_cpuid,... 语法无效。应该是INSERT INTO user_hw VALUES( EMAIL, CPUID, ...) values (in_email, in_cpuid, ...)

标签: database oracle stored-procedures cursors


【解决方案1】:

认为查询将不起作用 - 您的理由是“因为查询将返回太多行”。这是不正确的。添加一个 WHERE 子句(或添加到您已有的过滤器),条件为ROWNUM = 1 - 这将返回满足所有其他条件的第一行,处理将结束,您将只得到这一行,没有别的.

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多