0
CREATE OR REPLACE FUNCTION getIdFromNameParameter 
    (columnName VARCHAR2, tableName VARCHAR2, whereColumn VARCHAR2, parameterColumn VARCHAR2)
RETURN VARCHAR2
AS
    idCatc VARCHAR2(50);
BEGIN
    execute immediate 'SELECT ' || columnName || ' INTO ' || idCatc || ' FROM ' || tableName || ' WHERE ' || whereColumn || ' = ' ||  parameterColumn;
    RETURN idCatc;
END;
/

I get this warning:

Warning: Function created with compilation errors

5
  • 1
    Regardless of the solution you choose , please please ensure you are not enabling SQL Injection. Scrub all inputs. Use binds. Commented Feb 4, 2018 at 17:52
  • 1
    @KrisRice can u explain more Commented Feb 4, 2018 at 17:56
  • 1
    Why not just pass in a full sql statement at this point? There's already no sql injection protection. Commented Feb 4, 2018 at 17:57
  • 1
    Mobile right now. I’ll post a longer example later when I have a keyboard. Commented Feb 4, 2018 at 17:57
  • 1
    Looks like the real question was "How can I use dynamic SQL to return a value?" Commented Feb 4, 2018 at 17:59

2 Answers 2

4

For one thing, the into is part of execute immediate:

CREATE OR REPLACE FUNCTION getIdFromNameParameter (
    in_columnName VARCHAR2,
    in_tableName VARCHAR2,
    in_whereColumn VARCHAR2,
    in_parameterColumn VARCHAR2)
RETURN VARCHAR2
AS
    idCatc VARCHAR2(50);
BEGIN
    execute immediate 'SELECT ' || in_columnName || ' FROM ' || in_tableName || ' WHERE ' || in_whereColumn || ' = ' ||  in_parameterColumn
    INTO idCatc;
    RETURN idCatc;
END;

You were also using + for string concatenation.

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

2 Comments

this is also work 'execute immediate 'SELECT ' || columnName || ' INTO ' || idCatc || ' FROM ' || tableName || ' WHERE ' || whereColumn || ' = ' || parameterColumn;'
execute immediate 'SELECT ' || in_columnName || ' FROM ' || in_tableName || ' WHERE ' || in_whereColumn || ' = :par' INTO idCatc using in_parameterColumn; would be even better.
3

If you create a function like this, ensure it's safe from sql injection with something like the following. This uses dbms_assert to sanitize the inputs against thing like ';drop table xyz;'

 CREATE OR REPLACE FUNCTION getidfromnameparameter (
        in_columnname        VARCHAR2,
        in_tablename         VARCHAR2,
        in_wherecolumn       VARCHAR2,
        in_parametercolumn   VARCHAR2
    ) RETURN VARCHAR2 AS
        idcatc   VARCHAR2(50);
    BEGIN
        EXECUTE IMMEDIATE 'SELECT '
                         || sys.dbms_assert.qualified_sql_name(in_columnName)
                         || ' FROM '
                         || sys.dbms_assert.sql_object_name(in_tableName)
                         || ' WHERE '
                         || sys.dbms_assert.qualified_sql_name(in_whereColumn)
                         || ' = '
                         || sys.dbms_assert.enquote_literal(in_parametercolumn)
       INTO idcatc;

       RETURN idcatc;
  END;
  /

2 Comments

it's work good how EXECUTE IMMEDIATE work with OPEN curosr FOR SELECT ...
I cannot use this to get an entire column. Is there a way to make the output multi-valued?

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.