2017-03-01 38 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次,我在兩次輸入正確的值並按預期​​運行。 我有更多要了解綁定變量,但這是最接近正確的答案呢。 –

相關問題