0
CREATE OR REPLACE PROCEDURE STRING_CHECK
    ( QUERY_COND IN VARCHAR2, RESP_CODE OUT VARCHAR2, RESP_MSG OUT VARCHAR2 )
IS
    EM_NAME VARCHAR2(50);
BEGIN
    SELECT EMAIL INTO EM_NAME FROM EMPLOYEES WHERE EMPLOYEE_ID=110 QUERY_COND;
END;

In this simple procedure, QUERY_COND has the string which i want to pass after the where condition as shown below:

DECLARE 
    RESP_CODE VARCHAR2(20) := '000';
    RESP_MSG VARCHAR2(50) := 'SUCCESS';
    QUERY_COND VARCHAR2(100) := 'AND HIRE_DATE BETWEEN ''15-JUN-2003'' AND ''25-MAY-2005''';
BEGIN
    DBMS_OUTPUT.PUT_LINE(QUERY_COND);
    STRING_CHECK(QUERY_COND,RESP_CODE,RESP_MSG);
END;

I just want to know whether this can be done or not. If done, how can I achieve it?

2 Answers 2

1

You can do it with dynamic SQL; for example:

CREATE OR REPLACE PROCEDURE STRING_CHECK(QUERY_COND IN VARCHAR2,RESP_CODE OUT VARCHAR2,RESP_MSG OUT VARCHAR2)
IS
    EM_NAME VARCHAR2(50);
    vSQL    varchar2(1000);
BEGIN
    vSQL := 'SELECT EMAIL FROM EMPLOYEES WHERE EMPLOYEE_ID=110 ' || QUERY_COND;
    --
    execute immediate vSQL into EM_NAME;
END;


DECLARE 
    RESP_CODE VARCHAR2(20):='000';
    RESP_MSG VARCHAR2(50):='SUCCESS';
    QUERY_COND VARCHAR2(100):='AND HIRE_DATE BETWEEN date ''2003-06-15'' AND date ''2005-05-25''';
BEGIN
    DBMS_OUTPUT.PUT_LINE(QUERY_COND);
    STRING_CHECK(QUERY_COND,RESP_CODE,RESP_MSG);
END;

Notice that I changed the way you handle the dates, to avoid impicit conversions without giving a format.

Also, I would not recommend such an approach to build a query based on some parameter; it would be much better to build a static query with some date parameters, avoiding the dynamic SQL.

For example, something like :

CREATE OR REPLACE PROCEDURE STRING_CHECK_2(dateStart IN     date, 
                                           dateEnd   IN     date,
                                           RESP_CODE    OUT VARCHAR2,
                                           RESP_MSG     OUT VARCHAR2
                                           )
IS
    EM_NAME VARCHAR2(50);
BEGIN
    SELECT EMAIL
    into EM_NAME
    FROM EMPLOYEES
    WHERE EMPLOYEE_ID=110
      and HIRE_DATE BETWEEN dateStart and dateEnd;
    --
END;

Of course this has to be refined to handle errors, and the case when not both the dates are given in input, but I would much prefer a static approach with some boolean logic than a dynamic one.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the quick response. This was helpful and working.
I have to pass the whole query not the parameters. Is there anyway to do this other than the dynamic sql?
0

In general, you should not use that method as it opens your code up to all sorts of SQL injection vulnerabilities:

DECLARE 
  RESP_CODE VARCHAR2(20):='000';
  RESP_MSG VARCHAR2(50):='SUCCESS';
  QUERY_COND VARCHAR2(100):=' AND EXISTS( SELECT 1 FROM your_password_table WHERE user_id = ''007'') --';
BEGIN
    DBMS_OUTPUT.PUT_LINE(QUERY_COND);
    STRING_CHECK(QUERY_COND,RESP_CODE,RESP_MSG);
END;

Will return results if there is a password in the table for the user_id of 007 (which is almost certainly not what you wanted the user to be able to do with this query).

Instead, you should know which parameters you want to filter on and accept those:

CREATE OR REPLACE PROCEDURE STRING_CHECK(
  date_start IN  EMPLOYEES.HIRE_DATE%TYPE,
  date_end   IN  EMPLOYEES.HIRE_DATE%TYPE,
  RESP_CODE  OUT VARCHAR2,
  RESP_MSG   OUT VARCHAR2
)
IS
  EM_NAME VARCHAR2(50);
BEGIN
  SELECT EMAIL
  INTO   EM_NAME
  FROM   EMPLOYEES
  WHERE  EMPLOYEE_ID = 110
  AND    ( date_start IS NULL OR date_start <= hire_date )
  AND    ( date_end   IS NULL OR hire_date  <= date_end  );

  -- generate responses
END;
/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.