Oracle PLSQLは、[閉じ]でグループ化する動的sqlなしでピボットを選択します。
質問
応答する人には、11G R2 Oracle DBMSでピボットオプションを使用してSelect Functionを使用したいと考えています。私たちのクエリは次のようなものです。
select * from
(SELECT o.ship_to_customer_no, ol.item_no,ol.amount
FROM t_order o, t_order_line ol
WHERE o.NO = ol.order_no and ol.item_no in (select distinct(item_no) from t_order_line))
pivot --xml
( SUM(amount) FOR item_no IN ( select distinct(item_no) as item_no_ from t_order_line));
ご覧のとおり、XMLはコメントアウトされています。PivotXMLとして実行すると、XML形式で正しい出力が得られますが、データをフォーマットのピボットデータとして取得する必要がありますが、この文はエラーをスローします。ORA-00936:式が欠落しています
解決策やアイデアは歓迎されます、
よろしくお願いします
--------------ダーティですが、作業プロセスは以下です--------------------------------------------------------------------------
17.01.2011までに手順を更新しました16:39 GMT:
PROCEDURE pr_pivot_item_by_ship_to (
p_location_code IN t_customer.location_code%TYPE,
p_customer_price_group IN t_customer.customer_price_group%TYPE,
p_shipment_date IN t_order.shipment_date%TYPE,
p_fasdat_status IN t_order.fasdat_status%TYPE,
p_order_type IN t_order.order_type%TYPE,
cur_pivot_item_by_ship_to OUT sys_refcursor
)
IS
v_sql VARCHAR2 (15000);
v_pivot_items VARCHAR2 (15000) := '';
v_query_items VARCHAR2 (15000) := '';
v_pivot_orders VARCHAR2 (15000) := '';
v_continue INT := 0;
BEGIN
/*GET ORDER NUMBERS*/
FOR cur_order_loop IN (SELECT DISTINCT (o.NO) AS order_no
FROM t_order o,
vw_customer_with_ship_to_info wwc
WHERE wwc.customer_price_group =
p_customer_price_group
AND wwc.location_code =
p_location_code
AND o.shipment_date = p_shipment_date
AND o.fasdat_status = p_fasdat_status
AND o.order_type = p_order_type
AND wwc.NO = o.customer_no)
LOOP
v_pivot_orders :=
''',''' || TO_CHAR (cur_order_loop.order_no)
|| v_pivot_orders;
v_pivot_orders := LTRIM (v_pivot_orders, ''',''');
END LOOP;
/*USE ORDER NUMBERS TO FIND ITEMS TO PIVOT BY SHIPMENT PLACE*/
FOR cur_loop IN
(SELECT DISTINCT (ol.item_no) AS item_no,
REPLACE
(REPLACE (SUBSTR (i.description, 1, 20), '''',
''),
'"',
' inch'
) AS description
FROM t_order_line ol, t_item i
WHERE ol.item_no = i.NO
AND ol.order_no IN (
SELECT DISTINCT (o.NO) AS order_no
FROM t_order o,
vw_customer_with_ship_to_info wwc
WHERE wwc.customer_price_group =
p_customer_price_group
AND wwc.location_code =
p_location_code
AND o.shipment_date = p_shipment_date
AND o.fasdat_status = p_fasdat_status
AND o.order_type = p_order_type
AND wwc.NO = o.customer_no))
LOOP
v_query_items := ',''' || cur_loop.item_no || '''' || v_query_items;
v_pivot_items :=
','''
|| cur_loop.item_no
|| ''' as "ad_'
|| cur_loop.description
|| '"'
|| v_pivot_items;
END LOOP;
v_query_items := LTRIM (v_query_items, ',');
v_pivot_items := LTRIM (v_pivot_items, ',');
v_sql :=
'select * from
(SELECT wwc.ship_to_customer_no||''-''|| wwc.ship_to_customer_name as "Müst. Adi ('
|| p_order_type
|| ')", ol.item_no,ol.amount
FROM t_order o, t_order_line ol,vw_customer_with_ship_to_info wwc
WHERE o.NO = ol.order_no
and wwc.no = o.customer_no
and ol.order_no in (
(SELECT DISTINCT (o.NO) AS order_no
FROM t_order o,
vw_customer_with_ship_to_info wwc
WHERE wwc.customer_price_group ='''
|| p_customer_price_group
|| '''
AND wwc.location_code =
'''
|| p_location_code
|| '''
AND o.shipment_date = '''
|| p_shipment_date
|| '''
AND o.fasdat_status = '
|| p_fasdat_status
|| '
AND o.order_type = '''
|| p_order_type
|| '''
AND wwc.NO = o.customer_no)
)
and OL.ITEM_NO in ('
|| v_query_items
|| ')
)
pivot
( SUM(amount) FOR item_no IN ('
|| v_query_items --v_pivot_items
|| '))';
--DBMS_OUTPUT.put_line ('TSQL ' || v_sql);
-- OPEN cur_pivot_item_by_ship_to FOR
-- SELECT v_sql
-- FROM DUAL;
BEGIN
OPEN cur_pivot_item_by_ship_to FOR v_sql;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
WHEN OTHERS
THEN
IF SQLCODE = -936
THEN
NULL;
ELSE
pck_helper.pr_log_error
(SQLCODE,
'p_shipment_date:'
|| p_shipment_date
|| ','
|| 'cur_pivot_item_by_ship_to err. :'
|| SQLERRM,
'pr_pivot_item_by_ship_to'
);
END IF;
END;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
WHEN OTHERS
THEN
pck_helper.pr_log_error (SQLCODE,
'p_shipment_date:'
|| p_shipment_date
|| ','
|| SQLERRM,
'pr_pivot_item_by_ship_to'
);
END pr_pivot_item_by_ship_to;
END pkg_report;
解決 2
2011年17.01.2011で編集された手順は汚れていますが、機能しているため、ループカーソルは変更され、より良いERRが変更されます。ダイナミックSQLの処理(現在はありません)は、時間が取れたときに改善しようとします。皆様のご協力ありがとうございます。
他のヒント
私は今私に利用できるOracle11インスタンスを持っていません(私は今利用できます(PIVOT
Oracle 11に新しいです)ので、私は推測することしかできません。私の推測はそれです --
その後、すべてをコメントすることになりました pivot
, 、そして、Oracleはあなたに「失われた式」エラーを与えました。 pivot
. 。コメントしてみましたか xml
それを囲むことによって /*
と */
置く代わりに --
その前に?
たとえば、Javaからこのクエリを実行している場合、次の文字列でSQLを実行しようとした場合、「式が欠落している」エラーが発生することを期待します。
String sql =
"select * from (SELECT o.ship_to_customer_no, ol.item_no,ol.amount " +
"FROM t_order o, t_order_line ol " +
"WHERE o.NO = ol.order_no and ol.item_no in (select distinct(item_no) from t_order_line)) " +
"pivot --xml " +
"( SUM(amount) FOR item_no IN ( select distinct(item_no) as item_no_ from t_order_line))";
このSQL文字列は1つの行に連結されるため、 --
の前に xml
オラクルはクエリの後のすべてを無視します。
編集: :あなたが追加した手順では、私に関係するのはこの部分です(省略):
v_sql := 'begin
select * from ...;
end;';
open DENEME for
select v_sql from dual;
なぜあなたが使用しているのかわかりません BEGIN
と END
以内に v_sql
. 。それらを削除してみてください。
また、SQLステートメント文字列に後続のセミコロンを残さないように注意してください。以下は ORA-00911: invalid character
executeを即時またはそのように実行して実行しようとする場合のエラー:
v_sql := 'select * from dual;'; /* note the semicolon inside the string */
しかし、以下は大丈夫です:
v_sql := 'select * from dual';
最後に、このSQLクエリの結果を文字列としてではなく、このSQLクエリの結果を返したいと思うようです。あなたの交換 open DENEME for ...
以下の声明はあなたが望むことをする必要があります:
open DENEME for v_sql;
編集2: :手順では、dbms_output.put_lineへのコメントアウトコールがあります。ここで生成されたSQLが正しいことを確認しましたか?特に、形成に使用される値はどれもないと確信していますか v_query_items
と v_pivot_items
持ってる '
それらのキャラクター?
使用に問題がある可能性があります PIVOT
動的SQLを使用。ここでOracle 11にアクセスできないので、私は知りません。 SQLをはるかに小さなクエリに簡素化すると、まだエラーが発生しますか? PIVOT
初期化?言い換えれば、シンプルを見つけてください PIVOT
動作するクエリ(たとえば、SQL開発者やそのようなもので正常に実行できます)、次のような手順を作成し、データを取得するかどうかを確認してください。
CREATE OR REPLACE PROCEDURE dynamic_pivot_test(
results OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN results FOR 'SELECT ...'; /* put the PIVOT query here. */
END;
/