簡體   English   中英

通過傳遞表名和列名從Oracle表中刪除行

[英]Delete Row from Oracle table by passing table name and column name

我有一個jsp頁面,用戶可以在其中選擇表名稱,列名稱和列值,並希望通過這三個條件從數據庫中刪除所有匹配的行。 有沒有辦法在oracle中傳遞表名,列名和列值以從表中刪除某些行? 任何例子都會對我有所幫助。。謝謝

當您提供表名和列名時,我會擔心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;

注意:這假定您表中的日期列稱為“日期”。 我目前沒有SQL介面,但這應該足夠接近您需要的SQL介面。

如果將p_date_XXXX參數作為VARCHAR2而不是DATE類型傳遞,則需要先將這些值“ TO_DATE”傳遞給動態SQL。

例如

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>);
DELETE FROM table_name WHERE column_name = column_value

問題是您不能在PreparedStatement綁定表或列名,而只能綁定列值。

應該工作(從內存;未測試):

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)
{
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM