2012-01-17 2 views
1
SELECT 
    tbl1.PYU_EMAIL, 
    COUNT(tbl1.PYU_EMAIL) as TOTAL, 
    (SELECT ROWCONCAT('SELECT pyu_id FROM p_survey_invite WHERE pyu_email=' || tbl1.pyu_email) FROM dual) 
FROM p_survey_invite tbl1 
GROUP BY tbl1.pyu_id, tbl1.pyu_email 
ORDER BY total DESC; 

こんにちはすべて、Oracleの連結問題

私は ORA-04054を取得しておく:データベース・リンクDIGITALVIDEOSYSTEMS.NETがエラーに

存在しません。私はrowconcat内tbl1.pyu_emailをCONCATときと思われますtbl1.pyu_emailには@ charがあり、oracleのDB-LINKに反映されます。

@をdbリンクと考えることをoracleにどのように伝えますか?

+0

ROWCONCATは標準SQL(PL/SQLもありません)です。私は、あなたがより良く動作する[この記事の記事](http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php)に記載されている方法を見てみることをお勧めします。 –

+0

@ gumpi:あなたの質問にp_survey_inviteの定義を含めることができますか? –

+0

このROWCONCATの代わりに、おそらくLISTAGGを試してみてください(http://docs.oracle.com/cd/E14072_01/server.112/e10592/functions087.htmを参照してください) – tbone

答えて

4

あなたはあなたの電子メールアドレスの前後に引用符を置く必要があります。

SELECT 
    tbl1.PYU_EMAIL, 
    COUNT(tbl1.PYU_EMAIL) as TOTAL, 
    (SELECT ROWCONCAT('SELECT pyu_id FROM p_survey_invite WHERE pyu_email=''' || tbl1.pyu_email ||'''') FROM dual) 
FROM p_survey_invite tbl1 
GROUP BY tbl1.pyu_id, tbl1.pyu_email 
ORDER BY total DESC; 

あなたは動的にその文字列を実行ROWCONCAT()関数に文字列を渡しています。コードは、varchar2列をDML文字列に連結します。あなたが渡すものを文字列のエスケープ引用符が含まれていない限り(および関数が実行しようとし)、このようなものです:

SELECT pyu_id FROM p_survey_invite WHERE [email protected] 

をそして、それが失敗した理由です。

+1

この実装には多くの問題があります。準最適であり、あなたは自分自身をSQLインジェクションに開放しています(両方ともバインド変数を使用していないためです)。 –

+1

@VincentMalgrat - 動的SQLは、ハードコーディングされた定型文と列の値で構成される文字列を実行します。 SQLインジェクションのスコープがどこにあるかわからない。誰かが悪意のある値をP_SURVEY_INVITEに潜入するアクセス権を持っていれば、彼らがおそらく始めることができるより簡単な悪用がたくさんあります。 – APC

+0

@APC:SQLインジェクションの脆弱性は、悪意のない正当なエントリ(テキストの一部として引用符を含む可能性があります)からエラーが発生する可能性があることも意味します。私は、P_SURVEY_INVITEが定型文/ハードコーディングされた表であることに気づいていませんでした。それでも、私のコメントは一般的な文脈の中にあります。SQLインジェクションを防止し、よりパフォーマンスの高いソリューション(いくつかの文字列集約メソッドが存在します)を使用するほうがよいです。 –