Sql 在大型insert语句中使用bind变量

Sql 在大型insert语句中使用bind变量,sql,c,oracle,plsql,oracle-call-interface,Sql,C,Oracle,Plsql,Oracle Call Interface,我继承了一个应用程序,它必须从各种类型的文件中读取数据,并使用OCI接口将数据移动到Oracle数据库中。大多数表都有大约40-50列,因此SQLINSERT语句变得相当长 当我继承这段代码时,它基本上通过一系列strcat作为C字符串构建insert语句,然后将其传递给相应的OCI函数来设置和执行该语句。但是,由于大部分数据直接从文件读取到列值中,因此应用程序可以轻松地进行SQL注入。所以我尝试使用绑定变量来解决这个问题 在我能找到的每个示例OCI应用程序中,每个变量都是静态分配和单独绑定的。

我继承了一个应用程序,它必须从各种类型的文件中读取数据,并使用OCI接口将数据移动到Oracle数据库中。大多数表都有大约40-50列,因此SQLINSERT语句变得相当长

当我继承这段代码时,它基本上通过一系列strcat作为C字符串构建insert语句,然后将其传递给相应的OCI函数来设置和执行该语句。但是,由于大部分数据直接从文件读取到列值中,因此应用程序可以轻松地进行SQL注入。所以我尝试使用绑定变量来解决这个问题

在我能找到的每个示例OCI应用程序中,每个变量都是静态分配和单独绑定的。这将导致相当多的样板文件,然而,我想把它简化为某种循环结构。因此,我的解决方案是,为每个表创建一个静态字符串数组,其中包含表列的名称:

const char const *TABLE_NAME[N_COLS] = {
    "COL_1",
    "COL_2",
    "COL_3",
    ...
    "COL_N"
};
还有一个简短的函数,用于将列名转换为占位符:

void makePlaceholder(char *buf, const char *col);
// "COLUMN_NAME" -> ":column_name"
然后我循环遍历每个数组,并将我的值绑定到每个列,在执行时生成占位符。这里的一个潜在问题是,由于每列的类型不同,我将所有内容绑定为
SQLT_STR
(字符串),因此希望Oracle在插入时转换为正确的数据类型

因此,我的问题是:

  • 对于具有大量列/参数的SQL insert语句,使用绑定变量的正确/惯用方法是什么(如果SQL/OCI存在这种情况)?更一般地说,使用OCI生成这种类型的大型insert语句的最佳方法是什么

  • 与构建和使用普通C字符串相比,大量绑定调用在效率上是否有显著的成本

  • 将所有变量绑定为字符串并允许Oracle进行适当的类型转换是否存在风险


  • 提前谢谢

    我不确定这个问题的C方面。我将从DBA的角度给出答案

    问题2: 始终使用绑定变量。它可以防止SQL注入并提高性能


    性能方面经常被程序员忽略。当Oracle接收到SQL时,它会对整个SQL文本进行散列,并查看其内部的执行计划存储库,以查看是否有执行计划。如果使用了绑定变量,则无论变量的值是什么,每次运行查询时SQL文本都是相同的。但是,如果您连接了字符串,您的self-Oracle将对SQL文本进行散列,其中包括(您可能已经放入的)变量的内容,每次都会得到一个唯一的散列。所以,如果你做一个一百万次的查询,如果你使用绑定变量,Oracle将制定一个执行计划,而如果你不使用绑定变量,它将制定一百万个执行计划,并浪费大量资源

    谢谢你的回答。所以如果我理解正确的话,这个性能增强只会在所有列都绑定的情况下应用,对吗?因此,即使选择不绑定多个列中的单个列,也会导致不同的SQL文本,从而否定性能提升?