如何将列和表名作为参数传递给SQL存储过程

时间:2018-02-04 17:40:44

标签: sql oracle plsql

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;
/

我收到了这个警告:

  

警告:使用编译错误创建的函数

2 个答案:

答案 0 :(得分:3)

首先,intoexecute 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;

您还使用+进行字符串连接。

答案 1 :(得分:1)

如果您创建这样的函数,请确保使用以下内容进行sql注入是安全的。这使用dbms_assert来清理输入,例如&#39 ;; 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;
  /