2016-12-30 43 views
1

我想从Oracle表中删除记录,然后使用sql命令和参数插入新记录,因为该值来自浏览器。使用Devart EF Drivers for Oracle执行SQL命令使用Devart EF Drivers for Oracle

这是代码:

var tableName = "<myTableName>"; 
context.Database.ExecuteSqlCommand("DELETE :p0", tableName); 

甲骨文抛出 “ORA-00903:无效的表名”。

我也曾尝试:

context.Database.ExecuteSqlCommand("DELETE :p0", new OracleParameter("p0", OracleDbType.VarChar, 200, tableName, ParameterDirection.Input) 

有一些简单的我失踪?

+0

参数不能用于指定表名或列名。顺便说一下,SQL语法是DELETE FROM _tablename_ – Steve

+0

好,那么我该如何做到这一点,以防止SQL注入? DELETE 在SqlDeveloper中工作 – samneric

+0

您不让用户键入表名。您需要提供一张表格列表,并让他/她选择表格名称 – Steve

回答

1

如果您对反弹的ALL_TABLES表,你应该能够防止SQL注入攻击:

private bool TruncateTable(string Schema, string Table) 
{ 
    OracleCommand cmd = new OracleCommand("select count (*) from all_tables " + 
     "where owner = :SCHEMANAME and table_name = :TABLENAME", conn); 
    cmd.Parameters.Add("SCHEMANAME", Schema.ToUpper()); 
    cmd.Parameters.Add("TABLENAME", Table.ToUpper()); 

    if (Convert.ToInt32(cmd.ExecuteScalar()) == 0) 
     return false; 

    cmd.CommandText = string.Format("delete from {0}.{1}", Schema, Table); 
    cmd.Parameters.Clear(); 
    cmd.ExecuteNonQuery(); 

    return true; 
} 

在DevArt,我觉得Add将改为AddWithValues但原本看起来是一样的。

在这种情况下,返回值为false意味着没有这样的表。这一切都以用户有权从相关表格中删除为前提。

此外,如果可能的话,truncatedelete from的不错选择。它快得多,并且重置高水位。我认为你需要成为一个拥有者或拥有“放弃任何表”权限才能做到这一点,但还有其他方法 - 例如,让DBA设置一个存储过程来对某些表进行截断。

+0

干杯。这是避免注射的好方法。我实际上使用EF,所以我使用了反射来确保表格存在于edmx模型中:) – samneric