通过传递表名和列名从Oracle表中删除行

时间:2011-09-19 15:13:30

标签: java sql oracle

我有jsp页面,用户选择表名,列名和列值,这三个条件我想从数据库中删除所有匹配的行。有没有办法在oracle中传递表名,列名和列值来从表中删除某些行?任何一个例子都可以帮助我..谢谢

3 个答案:

答案 0 :(得分:2)

当您提供表名和列名时,我担心SQL注入攻击。 您可以创建Oracle函数来删除所需的记录,并在删除行之前测试要满足的某些条件:

CREATE OR REPLACE
FUNCTION delete_record (
   p_table  IN VARCHAR2,
   p_column IN VARCHAR2,
   p_value  IN VARCHAR2
)
RETURN NUMBER
AS
   v_table   user_tables.table_name%TYPE;
   v_columns user_tab_cols.column_name%TYPE;
BEGIN
   -- Check table exists in DB
   SELECT table_name
     INTO v_table
     FROM user_tables
    WHERE table_name = UPPER(p_table);

   -- Check column exists in DB table
   SELECT column_name
     INTO v_colums
     FROM user_tab_cols
    WHERE table_name = UPPER(p_table)
      AND column_name = UPPER(p_column);

   EXECUTE IMMEDIATE 
      'DELETE FROM '||DBMS_ASSERT.SIMPLE_SQL_NAME(p_table)||
      ' WHERE '||DBMS_ASSERT.SIMPLE_SQL_NAME(p_column)||' = :col_value'
     USING p_value;

   RETURN SQL%ROWCOUNT;
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
        -- Either return -1 (error) or log an error etc.
        RETURN -1;
   WHEN others
   THEN
        <Your exception handling here>
END delete_record;
/

这(或类似的东西)将检查数据库中是否存在提供的表和列变量,然后删除记录并返回已删除的记录数。 如果删除的号码有问题,您可以发出回滚语句,如果没有问题,那么您可以发出提交。

当然,如果要提供完全限定的表名(推荐),那么您将使用DBMS_ASSERT.QUALIFIED_SQL_NAME函数而不是DBMS_ASSERT.SIMPLE_SQL_NAME函数。

希望它有所帮助...

编辑:回答杰克关于从日期和日期添加日期的问题。

如果添加两个传递给函数的新条件:

CREATE OR REPLACE
FUNCTION delete_record (
   p_table     IN VARCHAR2,
   p_column    IN VARCHAR2,
   p_value     IN VARCHAR2,
   p_date_from IN DATE,
   p_date_to   IN DATE
)

然后您需要使用以下命令扩展EXECUTE IMMEDIATE:

EXECUTE IMMEDIATE 
  'DELETE FROM '||DBMS_ASSERT.SIMPLE_SQL_NAME(p_table)||
  ' WHERE '||DBMS_ASSERT.SIMPLE_SQL_NAME(p_column)||' = :col_value'||
  ' AND date BETWEEN :date_from AND :date_to'
 USING p_value,
       p_date_from,
       p_date_to;

N.B。假设表中的日期列被称为&#34; date&#34;。 我目前没有在我面前有一个SQL界面,但这应该足够接近你需要它才能使它工作。

如果您将p_date_XXXX参数作为VARCHAR2而不是DATE类型传递,那么您需要&#34; TO_DATE&#34;将它们传递给动态SQL之前的值。

e.g。

EXECUTE IMMEDIATE 
  'DELETE FROM '||DBMS_ASSERT.SIMPLE_SQL_NAME(p_table)||
  ' WHERE '||DBMS_ASSERT.SIMPLE_SQL_NAME(p_column)||' = :col_value'||
  ' AND date BETWEEN :date_from AND :date_to'
 USING p_value,
       TO_DATE(p_date_from, <date_format>),
       TO_DATE(p_date_to, <date_format>);

答案 1 :(得分:1)

DELETE FROM table_name WHERE column_name = column_value

问题是您无法在PreparedStatement中绑定表名或列名,只能绑定列值。

答案 2 :(得分:0)

应该工作(来自内存;未经测试):

Statement stmt = null;

try
{
    stmt = conn.createStatement("DELETE FROM " + tableName + " WHERE " + columnName + " = '" + condition + "'");
    int deleted = stmt.execute();
}
catch (SQLException e)
{
    ... report error
}

try
{
    if (stmt != null)
        stmt.close();
}
catch (SQLException ignore)
{
}