2017-03-01 32 views
0

感谢您看...创建简单的PL/SQL变量 - 在使用可变WHERE子句

我已经花了几个小时研究这个,我无法相信这是很难做到的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; 

我用蟾蜍日期点,我查询针对Oracle数据库云服务器源。生成的查询将被放入可视化工具(如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语句

以及更多..希望你明白了。我花了几个小时研究了一个正确答案的计算器,但正如你所看到的,我在问你。从“Var”这样的简单声明到更复杂的“DECLARE,BEGIN,SELECT INTO ....”到实际创建函数,使用游标迭代输出....我仍然无法在一个简单的变量中使用Where子句。

请解释我的方式错误。

--Forlorn SQL开发

+0

首先,我假设你的意思是PL/SQL,而不是TSQL。其次,我试过你的第一个例子,我没有看到问题;这个对我有用。所以我认为这一定是非常简单或非常奇怪的事情!你可以剪切/粘贴你的整个(第一个)例子吗? – BobC

+0

在PL/SQL里(一个命名的包/过程/函数等),你可以在'declare'部分声明变量,然后在任何你喜欢的地方引用它们。你的例子开始声明mydate number(8);'没有问题(只需要一个'end;'),我不明白它是如何给出'INTO子句是预期的',因为它只适用于'select'语句。 'variable'和'define'语法实际来自SQL * Plus命令行工具,它由桌面应用程序以各种方式进行模拟,因此您可能需要解释如何运行它。 –

+0

我的猜测是问题不是变量声明,而是报告输出 - 类似http://stackoverflow.com/questions/351489/is-it-possible-to-output-a-select-state-from-a -pl-sql-block/351752 –

回答

1

由于视图你正在使用一个隐式游标,你必须选择INTO变量。现在我不知道你变量的数据类型,所以我刚才在这个例子中猜到了,但希望你明白这一点。其他

两件事我应该提到

  1. 你为什么TO_CHARing你DATE。只需使用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; 
/
0

你把与getter和setter变量在包中。

然后用采用包吸气

个人而言,我更喜欢使用一个集合,这样我就可以做一个SELECT * FROM表(packagage.func(myparam))

+1

此答案似乎无法解决问题... – BobC

1
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; 
+0

因此关闭!我输入它几乎完全忽略了/之后的END; (我的印象是SQL *命令把这些行当作块),并且失败了。我再次用/和Bind变量框弹出2次,我在两次输入正确的值并按预期​​运行。 我有更多要了解绑定变量,但这是最接近正确的答案呢。 –