2017-05-18 39 views
0

我想創建HANA存儲過程,它執行以下操作:動態SQL

  • 接受表類型的參數。
  • 接受另一個varchar類型的IN參數。
  • 根據第一個輸入參數的列值過濾現有表中的某些行。
  • 嘗試根據第二個輸入參數給出的條件對行進行排序(ORDER BY)行。

下面是我要創建

CREATE PROCEDURE DEMO_PROD_EXAMPLE_DYNAMIC(IN TEMPLIST PRODLISTTYPE,IN ORDERSTRING VARCHAR(200)) 
AS 
BEGIN 
OUTVAR = SELECT * FROM DEMO_PRODS WHERE NAME IN (SELECT NAME FROM :TEMPLIST); 

SELECT * FROM :OUTVAR ORDER BY :ORDERSTRING DESC; 

END; 

我面臨以下障礙存儲過程:

  • 在上述過程中,排序並不發生在所有!如果我硬編碼列名稱,如SELECT * FROM:OUTVAR ORDER BY ID DESC;有用 。
  • 如果我嘗試創建一個像SELECT * FROM'||這樣的動態SQL查詢。 :OUTVAR ||」 ORDER BY BY'||:ORDERSTRING ||'DESC';我得到一個異常,它不允許使用帶連接運算符的varchar和table類型。

如何根據HANA中的動態條件(列名/ s傳遞給過程)對結果集進行排序。

TIA

回答

3

你必須使用EXECUTE IMMEDIATE執行動態SQL語句:

EXECUTE IMMEDIATE 'SELECT NAME FROM DEMO_PRODS ' || :ORDERSTRING || ' DESC'; 

然而,使用動態SQL,你不能使用表類型變量以供選擇。所以你需要找到SELECT * FROM DEMO_PRODS WHERE NAME IN (SELECT NAME FROM :TEMPLIST);的另一個解決方案。使用global temporary table是一個:

INSERT INTO TEMPORARY_TABLE (SELECT * FROM DEMO_PRODS WHERE NAME IN (SELECT NAME FROM :TEMPLIST); 
EXECUTE IMMEDIATE 'SELECT NAME FROM TEMPORARY_TABLE ' || :ORDERSTRING || ' DESC'; 
+0

Thanks!創建一個全局臨時表的作品!但它可能不是一個高效/乾淨的解決方案。是否有其他的選擇避免創建全局/本地臨時表,並且只涉及過程中的局部變量? –

+0

當多個用戶訪問數據庫時,也不會使用全局/本地臨時表太多會導致讀/寫衝突? –

+1

@ShubhaLakshmi:這絕對是一個完美的解決方案,但動態SQL有一定的侷限性。一個是你不能使用表類型變量。但是,應該有多個用戶的問題。在我鏈接的文檔中,可以找到'使表格定義全局可用,而數據僅對當前會話可見。'如果使用選項'ON COMMIT DELETE ROWS'創建表格,則會自動截斷如果您提交交易。通常,我會盡量避免使用動態SQL,並考慮另一種解決方案。如果可能的話,使用XS並在那裏生成查詢。 – rene