【问题标题】:Create simple PL/SQL variable - Use Variable in WHERE clause创建简单的 PL/SQL 变量 - 在 WHERE 子句中使用变量
【发布时间】:2017-07-21 06:20:36
【问题描述】:

感谢观看...

我已经花了好几个小时研究这个问题,我不敢相信在 PL/SQL 中做一些在 TSQL 中很简单的事情会这么难。

我有一个连接 2 个表的简单查询:

     Select DISTINCT
      to_char(TO_DATE('1899123000', 'yymmddhh24')+ seg.NOM_DATE, 'mm/dd/yyyy') AS "Record Date"
    , cd.CODE
    , EMP.ID
    , EMP.SHORT_NAME

    FROM
     EWFM.GEN_SEG seg join EWFM.SEG_CODE cd ON seg.SEG_CODE_SK = cd.SEG_CODE_SK
     join EMP on seg.EMP_SK = EMP.EMP_SK
    where NOM_DATE = vMyDate;

我使用 Toad 日期点并查询 Oracle Exadata 源。生成的查询将被放入 QlikView 或 Tableau 等可视化工具中。我想创建一个简单的变量来使用 WHERE 子句,正如您在代码中看到的那样。

在此示例中,NOM_DATE 是一个整数,例如 42793 (2/27/2017),您可以在第一行“记录日期”中看到。这里没有什么新东西,不是很令人兴奋……直到……我尝试创建一个变量来使查询更加动态。

我尝试了这里发现的各种令人惊讶的示例,但都失败了。如:
declare myDate number(8); Begin myDate := 42793; --Fail ORA-06550 INTO 子句是预期的

variable nomDate NUMBER
DEFINE nomDate = 42793
EXEC : nomDate := ' & nomDate'
...where NOM_DATE = ( & nomDate) ;

--ORA-00900: 无效的 SQL 语句

variable nomDate NUMBER;
EXEC nomDate := 42793;
select count(DET_SEG_SK) from DET_SEG
where NOM_DATE = :nomDate;

--ORA-00900: 无效的 SQL 语句

还有更多……希望你能明白。我花了几个小时研究 stackoverflow 以获得正确答案,但如您所见,我在问您。从像“Var”这样的简单声明到更复杂的“DECLARE, BEGIN, SELECT INTO....”到实际创建函数,使用游标迭代输出......我仍然无法制作一个简单的变量来使用Where 子句。

请解释我的方式的错误。

--Forlorn SQL 开发

【问题讨论】:

  • 首先,我假设您的意思是 PL/SQL,而不是 TSQL。其次,我试过你的第一个例子,我没有看到问题;这个对我有用。所以我认为这一定是非常简单或非常奇怪的事情!您可以剪切/粘贴整个(第一个)示例吗?
  • 在 PL/SQL(一个命名的包/过程/函数等)中,您可以在 declare 部分声明变量,然后在您喜欢的任何地方引用它们。您以declare mydate number(8); 开头的示例工作正常(只需要end;),我看不出它如何给出INTO clause is expected,因为这只适用于select 语句。 variabledefine 语法实际上来自 SQL*Plus 命令行工具,桌面应用程序以各种方式模拟它,因此您可能需要解释您是如何运行它的。
  • 我的猜测是问题不在于变量声明,而是报告输出 - 类似于stackoverflow.com/questions/351489/…
  • BobC: 这是第一个完整的例子 ' declare myDate number(8);开始 myDate := 42793; SELECT DISTINCT to_char(TO_DATE('1899123000', 'yymmddhh24')+ seg.NOM_DATE, 'mm/dd/yyyy') AS "记录日期" , cd.CODE , EMP.ID , EMP.SHORT_NAME , seg.MEMO , seg .AUDIT_INS_DATE FROM EWFM.GEN_SEG seg join EWFM.SEG_CODE cd ON seg.SEG_CODE_SK = cd.SEG_CODE_SK join EMP on seg.EMP_SK = EMP.EMP_SK where NOM_DATE = myDate;结尾; ' 感谢您的关注
  • @mf.cummings。我没有看到你的例子......

标签: oracle plsql


【解决方案1】:

您将带有 getter 和 setter 的变量放在一个包中。

然后使用一个使用包getter的视图

我个人更喜欢使用集合,这样我可以从表中选择 * (package.func(myparam))

【讨论】:

    【解决方案2】:
    VARIABLE vMyDate NUMBER;
    
    BEGIN
      :vMyDate  := 42793;
    END;
    /
    
    -- or
    -- EXEC :vMyDate := 42793;
    
    SELECT DISTINCT
           TO_CHAR( DATE '1899-12-30' + seg.NOM_DATE, 'mm/dd/yyyy') AS "Record Date"
         , cd.CODE
         , EMP.ID
         , EMP.SHORT_NAME
    FROM   EWFM.GEN_SEG seg
           join EWFM.SEG_CODE cd
           ON seg.SEG_CODE_SK = cd.SEG_CODE_SK
           join EMP
           on seg.EMP_SK = EMP.EMP_SK
    WHERE  NOM_DATE = :vMyDate;
    

    【讨论】:

    • 如此接近!我键入它几乎完全省略了 END 之后的 /; (我的印象是 SQL* 命令将行视为一个块)并且它失败了。我再次使用 / 并弹出 2x 绑定变量框,我两次都在其中输入了正确的值,它按预期运行。我还有更多关于绑定变量的知识,但这是最接近正确答案的。
    【解决方案3】:

    由于您使用的是隐式游标,因此您必须选择 INTO 变量。现在我不知道你变量的数据类型,所以我只是在下面这个例子中猜测,但希望你明白这一点。

    另外两件事我应该提到

    1. 您为什么要对您的日期进行 TO_CHAR 处理。只需使用 DATE 数据类型。另外,我认为您的格式掩码也是错误的 1899123000 与 yymmddhh24 不匹配。
    2. 在显式游标中只需要一行;没有行,你得到 NO_DATA_FOUND;不止一个,你会得到 TOO_MANY_ROWS
    Declare 
       myDate number(8) := 42793; 
        /* These 4 variable data types are a guess */
       v_record_date varchar2(8);
       v_cd_code varchar2(10);
       v_emp_id number(4);
       v_emp_short_name varchar2(100);
     BEGIN 
     Select DISTINCT to_char(TO_DATE('1899123000', 'yymmddhh24')
                         + eg.NOM_DATE, 'mm/dd/yyyy') AS "Record Date" 
     , cd.CODE 
     , EMP.ID 
     , EMP.SHORT_NAME 
     INTO v_record_date, v_cd_code, v_emp_id, v_emp_short_name
     FROM EWFM.GEN_SEG seg 
     join EWFM.SEG_CODE cd 
       ON seg.SEG_CODE_SK = cd.SEG_CODE_SK 
     join EMP 
         on seg.EMP_SK = EMP.EMP_SK 
     where NOM_DATE = myDate; 
     END;
     /
    

    【讨论】:

      猜你喜欢
      • 2020-04-16
      • 2016-05-15
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多