SELECT不会将数据存储在PL/SQL变量中

huangapple go评论58阅读模式
英文:

SELECT isn't storing data in PL/SQL variables

问题

好的,这是翻译好的部分:

"Okay, so once again I did a script in which I need to store some data into PL/SQL variables. Now for some reason I can't store said data. I tried the query by itself without INTO statement to prove if the query was wrong by any means and I get the result I expected. But once I get to the anonymous block with INTO isn't working and the output says that there was no data found.

Here is the script."

(代码部分,无需翻译)

"Here I'll put the data types of both PROPIEDAD and TIPO_PROPIEDAD in case someone wants to help me with this.

PROPIEDAD:"

(代码部分,无需翻译)

"TIPO_PROPIEDAD:"

(代码部分,无需翻译)

"And also, I'll put the error in here."

(代码部分,无需翻译)

"Also, when I run the query without bind variables as a normal query it does find data:"

(代码部分,无需翻译)

"Result:"

(代码部分,无需翻译)

英文:

Okay so once again I did a script in which I need to store some data into PL/SQL variables. Now for some reason I can't store said data. I tried the query by itself without INTO statement to prove if the query was wrong by any means and I get the result I expected. But once I get to the anonymous block with INTO isn't working and the output says that there was no data found.

Here is the script.

SET SERVEROUTPUT ON;
VAR TP1 VARCHAR2(30);
EXEC TP1 := &TIPO_PROPIEDAD_1;
DBMS_OUTPUT.PUT_LINE(:TP1);
DECLARE
    V_CANT_1 PROPIEDAD.NRO_PROPIEDAD%TYPE;
    V_TOTAL_1 PROPIEDAD.VALOR_ARRIENDO%TYPE;
    V_DESC_1 TIPO_PROPIEDAD.DESC_TIPO_PROPIEDAD%TYPE;
BEGIN
-- CONSULTA 1
    SELECT
        COUNT(PR.NRO_PROPIEDAD),
        SUM(PR.VALOR_ARRIENDO),
        TP.DESC_TIPO_PROPIEDAD
        INTO
            V_CANT_1,
            V_TOTAL_1,
            V_DESC_1
    FROM
        PROPIEDAD PR INNER JOIN TIPO_PROPIEDAD TP
        ON PR.ID_TIPO_PROPIEDAD = TP.ID_TIPO_PROPIEDAD
    WHERE
        TP.ID_TIPO_PROPIEDAD = :TP1
    GROUP BY
        TP.DESC_TIPO_PROPIEDAD;
   
    DBMS_OUTPUT.PUT_LINE('RESUMEN DE : ' || V_DESC_1);
    DBMS_OUTPUT.PUT_LINE('TOTAL DE PROPIEDADES : ' || V_CANT_1);
    DBMS_OUTPUT.PUT_LINE('VALOR TOTAL ARRIENDO : ' || V_TOTAL_1);
END;

Here I'll put the data types of both PROPIEDAD and TIPO_PROPIEDAD in case someone wants to help me with this.

PROPIEDAD:

Nombre                  ¿Nulo?   Tipo         
----------------------- -------- ------------ 
NRO_PROPIEDAD           NOT NULL NUMBER(6)       
VALOR_ARRIENDO          NOT NULL NUMBER(7)       
ID_TIPO_PROPIEDAD       NOT NULL VARCHAR2(1)  

TIPO_PROPIEDAD:

Nombre              ¿Nulo?   Tipo         
------------------- -------- ------------ 
ID_TIPO_PROPIEDAD   NOT NULL VARCHAR2(1)  
DESC_TIPO_PROPIEDAD NOT NULL VARCHAR2(30)

And also, I'll put the error in here.

Informe de error -
ORA-01403: No se ha encontrado ningún dato
ORA-06512: en línea 7
01403. 00000 -  "no data found"
*Cause:    No data was found from the objects.
*Action:   There was no data from the objects which may be due to end of fetch.

Also, when I run the query without bind variables as a normal query it does finds data:

    SELECT
        COUNT(PR.NRO_PROPIEDAD),
        SUM(PR.VALOR_ARRIENDO),
        TP.DESC_TIPO_PROPIEDAD
    FROM
        PROPIEDAD PR INNER JOIN TIPO_PROPIEDAD TP
        ON PR.ID_TIPO_PROPIEDAD = TP.ID_TIPO_PROPIEDAD
    WHERE
        TP.ID_TIPO_PROPIEDAD = 'A'
    GROUP BY
        TP.DESC_TIPO_PROPIEDAD;

Result:

COUNT(PR.NRO_PROPIEDAD) SUM(PR.VALOR_ARRIENDO) TP.DESC_TIPO_PROPIEDAD
7	                    3445000	               Casa sin Amoblar

答案1

得分: 2

根据您发布的内容,您错过或忽略了您的脚本会产生的一个早期错误:

EXEC TP1 := &TIPO_PROPIEDAD_1;

应该是

EXEC :TP1 := ''&TIPO_PROPIEDAD_1'';

没有冒号,您对 TP1 的引用将被视为一个本地变量,而不是您声明的绑定变量,您将看到 "PLS-00201: identifier 'TP1' must be declared" 错误(在它提示您输入绑定值之后,这可能让您以为这部分是正常工作的)。这意味着在稍后在您的 where 子句中使用它时,实际的绑定变量仍然为 null,因此没有匹配项。

并且如果没有单引号,它将把替换值 A 视为另一个标识符,而不是字符串,再次绑定变量仍将为 null。

您的 DBMS_OUTPUT.PUT_LINE(:TP1); 调试也会出错,显示 "Unknown command",因为您在 PL/SQL 块外部调用它;您可以使用 PRINT TP1(带冒号或不带冒号!)来代替。

英文:

Based on what you've posted, you've missed or ignored an earlier error your script will produce; this:

EXEC TP1 := &TIPO_PROPIEDAD_1;

should be

EXEC :TP1 := '&TIPO_PROPIEDAD_1';

Without the colon your reference to TP1 will be treated as a local variable rather than the bind variable you declared, and you will see "PLS-00201: identifier 'TP1' must be declared" (after it prompts you for the bind value, which might have made you assume that part was working). That means the actual bind variable is still null when you use it your where clause later, so there are no matches.

And without the single quotes it will treat the substitution value A as another identifier rather than a string, and again the bind variable will still be null.

Your DBMS_OUTPUT.PUT_LINE(:TP1); debug will also error with "Unknown command" as you are calling that outside a PL/SQL block; you can do PRINT TP1 (with or without a colon!) instead.

答案2

得分: 0

代码部分不要翻译。以下是翻译的部分:

这不起作用是因为没有匹配的行,所以会抛出(不言自明的)异常 NO_DATA_FOUND

如果您想输出单行结果,则需要对整个结果集进行汇总:

这将始终返回一行结果,并应输出:

摘要:0
总共物业: 
总租金: 

因为没有匹配的行,所以计数将为 0,没有要进行 SUM 的内容,也没有描述。

另外,您可以处理异常:

英文:

It is not working because there are no matching rows so the (self-explanatory) exception NO_DATA_FOUND is thrown.

If you want to output a single row then aggregate across the entire result-set:

DECLARE
    V_CANT_1 PROPIEDAD.NRO_PROPIEDAD%TYPE;
    V_TOTAL_1 PROPIEDAD.VALOR_ARRIENDO%TYPE;
    V_DESC_1 TIPO_PROPIEDAD.DESC_TIPO_PROPIEDAD%TYPE;
BEGIN
-- CONSULTA 1
  SELECT COUNT(PR.NRO_PROPIEDAD),
         SUM(PR.VALOR_ARRIENDO),
         MAX(TP.DESC_TIPO_PROPIEDAD)
  INTO   V_CANT_1,
         V_TOTAL_1,
         V_DESC_1
  FROM   PROPIEDAD PR INNER JOIN TIPO_PROPIEDAD TP
         ON PR.ID_TIPO_PROPIEDAD = TP.ID_TIPO_PROPIEDAD
  WHERE  TP.ID_TIPO_PROPIEDAD = :TP1;
   
  DBMS_OUTPUT.PUT_LINE('RESUMEN DE : ' || V_DESC_1);
  DBMS_OUTPUT.PUT_LINE('TOTAL DE PROPIEDADES : ' || V_CANT_1);
  DBMS_OUTPUT.PUT_LINE('VALOR TOTAL ARRIENDO : ' || V_TOTAL_1);
END;
/

Which will always return a single row and should output:

> lang-none
> RESUMEN DE : 0
> TOTAL DE PROPIEDADES :
> VALOR TOTAL ARRIENDO :
>

Since there are no matching rows so the count will be 0 and there is nothing to SUM and no description.


Alternatively, you can handle the exception:

DECLARE
    V_CANT_1 PROPIEDAD.NRO_PROPIEDAD%TYPE;
    V_TOTAL_1 PROPIEDAD.VALOR_ARRIENDO%TYPE;
    V_DESC_1 TIPO_PROPIEDAD.DESC_TIPO_PROPIEDAD%TYPE;
BEGIN
-- CONSULTA 1
  BEGIN
    SELECT COUNT(PR.NRO_PROPIEDAD),
           SUM(PR.VALOR_ARRIENDO),
           TP.DESC_TIPO_PROPIEDAD
    INTO   V_CANT_1,
           V_TOTAL_1,
           V_DESC_1
    FROM   PROPIEDAD PR INNER JOIN TIPO_PROPIEDAD TP
           ON PR.ID_TIPO_PROPIEDAD = TP.ID_TIPO_PROPIEDAD
    WHERE  TP.ID_TIPO_PROPIEDAD = :TP1
    GROUP BY
           TP.DESC_TIPO_PROPIEDAD;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      V_CANT_1 := 0;
      V_TOTAL_1 := NULL;
      V_DESC_1 := NULL;
    WHEN TOO_MANY_ROWS THEN
      -- Do something to handle this as well.
      RAISE;
  END;

  DBMS_OUTPUT.PUT_LINE('RESUMEN DE : ' || V_DESC_1);
  DBMS_OUTPUT.PUT_LINE('TOTAL DE PROPIEDADES : ' || V_CANT_1);
  DBMS_OUTPUT.PUT_LINE('VALOR TOTAL ARRIENDO : ' || V_TOTAL_1);
END;
/

fiddle

huangapple
  • 本文由 发表于 2023年3月20日 23:22:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792158.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定