2016-04-23 51 views
1

必要条件は、STUDENTSテーブルから結果をフェッチすることです。 生徒IDとしてゼロが渡された場合、studentidのフィルタリングはこれ以上必要ありません。ORACLEの動的where句

inStudentIdをTO_CHARを使用して文字列に変換し、次いでを好きに供されるように確かに理想的ではない -

PROCEDURE getResults (  
    inStudentId  IN NUMBER, 
    inSectionId  IN NUMBER, 
    inRowLimit  IN NUMBER, 
    outResultsData OUT gphResultsData 
) AS 
    stStudentId VARCHAR2(50) := ''; 
    BEGIN 
    outResultsData := gphResultsData(); 
    IF inStudentId = '0' THEN 
     stStudentId := '%'; 
    ELSE 
     stStudentId := TO_CHAR(inStudentId); 
    END IF; 

    FOR rResults IN (
     SELECT 
     RESULTS.STUDENT_ID, 
     RESULTS.STUDENT_NAME 
     FROM 
     RESULTS 
     WHERE 
     RESULTS.STUDENT_ID LIKE stStudentId AND -- not a good idea 
     RESULTS.SECTION_ID = inSectionId AND 
     ROWNUM <= inRowLimit 
    ) LOOP 
     outResultsData.extend; 
     outResultsData(outResultsData.last).studentId := rResults.STUDENT_ID; 
     outResultsData(outResultsData.last).studentName := rResults.STUDENT_NAME; 
    END LOOP; 

    EXCEPTION 
    WHEN others THEN 
     ... 

Iは、上記溶液が出ています。

は、where句を動的に生成して実行するのが良い方法だと思います。

inStudentIdが

SELECT 
    RESULTS.STUDENT_ID, 
    RESULTS.STUDENT_NAME 
    FROM 
    RESULTS 
    WHERE 
    RESULTS.STUDENT_ID = inStudentId AND 
    RESULTS.SECTION_ID = inSectionId AND 
    ROWNUM <= inRowLimit 

、ゼロでない場合は最高のこの問題を解決する方法上の任意のポインタは素晴らしいものだinStudentId = 0、

SELECT 
    RESULTS.STUDENT_ID, 
    RESULTS.STUDENT_NAME 
FROM 
    RESULTS 
WHERE 
    RESULTS.SECTION_ID = inSectionId AND 
    ROWNUM <= inRowLimit 

場合 - である助けて。

+0

もし望むなら、条件を 'WHERE'節に置くことができます:' RESULTS.SECTION_ID = DECODE(inSecti onId、0、RESULTS.SECTION_ID、inSectionId) ' – Glenn

+0

完全な論理条件を書き出すことが複雑にならないようにするには、DECODEを避けるのが最善です。コードは「自分のために話す」ということは、CarloCeのソリューションのように、維持したり変更したりする方が簡単です。 – mathguy

+0

@OriginalPoster:PL/SQLでこれを行う必要がありますか?これは普通のSQLの仕事のようです。または、追加の処理があり、問題が発生した部分を示しただけですか? – mathguy

答えて

0

CREATE TYPE gphResult IS OBJECT(
    student_id INT, 
    student_name VARCHAR2(50) 
); 
/

CREATE TYPE gphResultsData IS TABLE OF gphResult; 
/

その後、あなたはこのようなBULK COLLECT INTO使用してループを回避できます。

PROCEDURE getResults (  
    inStudentId  IN NUMBER, 
    inSectionId  IN NUMBER, 
    inRowLimit  IN NUMBER, 
    outResultsData OUT gphResultsData 
) AS 
    stStudentId VARCHAR2(50) := ''; 
    BEGIN 
    SELECT gphResult(STUDENT_ID, STUDENT_NAME) 
    BULK COLLECT INTO outResultsData 
    FROM RESULTS 
    WHERE (inStudentId = 0 OR student_id = inStudentId) 
    AND SECTION_ID = inSectionId 
    AND ROWNUM  <= inRowLimit; 
    EXCEPTION 
    WHEN others THEN 
     ... 
+0

ランダムな匿名のdownvoterはコメントしますか? – MT0

1

私はそれを行うための最も簡単な方法は、次のようだと思う:

あなたはタイプを持っていると仮定すると
PROCEDURE getResults (  
    inStudentId  IN NUMBER, 
    inSectionId  IN NUMBER, 
    inRowLimit  IN NUMBER, 
    outResultsData OUT gphResultsData 
) AS 
    BEGIN 
    outResultsData := gphResultsData(); 
    FOR rResults IN (
     SELECT 
     RESULTS.STUDENT_ID, 
     RESULTS.STUDENT_NAME 
     FROM 
     RESULTS 
     WHERE 
     (RESULTS.STUDENT_ID = inStudentId OR inStudentId = 0) AND 
     RESULTS.SECTION_ID = inSectionId AND 
     ROWNUM <= inRowLimit 
    ) LOOP 
     outResultsData.extend; 
     outResultsData(outResultsData.last).studentId := rResults.STUDENT_ID; 
     outResultsData(outResultsData.last).studentName := rResults.STUDENT_NAME; 
    END LOOP; 

    EXCEPTION 
    WHEN others THEN 
     ... 
+0

また、より単純な、 'WHERE inStudentId IN(0、RESULTS.STUDENT_ID)AND'(など) – mathguy