首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将SQLExecDirect与预先格式化的查询字符串而不是SQLPrepare+SQLBindParameter+SQLExecute一起使用是否是个坏主意?

将SQLExecDirect与预先格式化的查询字符串而不是SQLPrepare+SQLBindParameter+SQLExecute一起使用是否是个坏主意?
EN

Stack Overflow用户
提问于 2012-02-08 07:12:48
回答 2查看 5.2K关注 0票数 1

好的,乍一看,使用SQLPrepare+SQLBindParameter+SQLExecute必须比使用格式字符串(例如CString::Format)更有效,并将整个查询字符串传递给SQLExecDirect。如果没有,为什么会存在第二个方法(SQLPrepare+SQLBindParameter+SQLExecute)?

但是..。以下是我的想法:司机迟早会有(我怀疑晚些时候,但无论如何.)将参数(我用SQLBindParameter提供给它)转换为字符串表示形式,对吗?(也许不是?)因此,如果我在我的应用程序中进行这种格式化(printf-like格式),我的性能会有任何损失吗?

我怀疑,当连接通过网络时,将参数作为原始数据传递,然后在服务器端格式化它们,可能会减少网络流量,而不是传递预先格式化的查询字符串,但让我们暂时忽略网络流量。如果不是这样,那么在应用程序中使用SQLPrepare+SQLBindParameter+SQLExecute而不是格式化完整的查询字符串,然后使用SQLExecDirect是否会提高性能?

对我来说,使用SQLExecDirect更简单、更方便,所以我需要一个很好的答案,看看我是否应该选择另一种方法。

重要的SQLPrepare+SQLBindParameter+SQLExecute:如果您说SQLPrepare+SQLBindParameter+SQLExecute方法会提供更好的性能,我想知道有多少!我不介意理论上的假设,我想知道它实际值多少钱?我目前的用例不是很密集的数据库,每秒不会有超过100个插入/更新,使用SQLExecDirect可以吗?在什么情况下--如果有的话--我必须使用SQLPrepare+SQLBindParameter+SQLExecute吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-08 08:26:10

如果您重复使用相同的SQL (不包括参数)插入或更新,那么每次SQLPrepare、SQLBindParameter和SQLExecute都会比SQLExecDirect快。考虑:

代码语言:javascript
复制
SQLPrepare("insert into mytable (cola, colb) values(?,?);");
for (n = 0; n < 10000; n++) {
    SQLBindParameter(1, n);
    SQLBindParameter(2, n);
    SQLExecute;
}

代码语言:javascript
复制
for (n = 0; n < 10000; n++) {
    char sql[1000];
    sprintf("insert into mytable (cola, colb) values(%d,%d)", n, n);
    SQLExecDirect(sql);
}

在第一个示例中,语句只准备一次,因此db引擎只需要解析它一次,并计算出一次执行计划。在第二个示例中,每次都传递sql和参数,而SQL每次看起来都不同,因此每次都进行解析。

此外,在第一个示例中,您可以使用参数数组在一次查看SQL_PARAMSET_SIZE中传递多行参数。

请参阅3.1.2插入数据以获得一个有效的示例,并指示您可以节省多少时间。

忽略网络流量,您将只是事后猜测在引擎盖下发生了什么。

附加:关于参数的描述,您似乎认为驱动程序会将它们转换为字符串;绑定参数的另一个优点是可以在一种类型中提供参数,并要求驱动程序将它们作为另一种类型使用。您可能会发现,如果不添加某种类型的转换函数,就无法轻松地将其表示为字符串的参数类型,而这种转换函数可以通过参数避免。

票数 3
EN

Stack Overflow用户

发布于 2012-02-08 08:50:20

是的,这是个坏主意,有两个原因:

  1. 性能 SQLPrepare会导致对SQL语句进行解析,并且取决于该语句的时间。如果在另一台服务器上使用DB,则可能会将它发送给它进行解析。即使解析只需要10%的时间执行整个查询,在执行两次语句时也可以节省时间。当您插入多个行或再次调用"select“时,可能会出现这种情况。 当然,传递的SQL语句必须始终是静态字符串。有些SQL框架甚至可以为您准备语句缓存。我不知道ODBC是否会这么做。如果您想要真正的性能编号,您必须自己度量--每个查询都是不同的(甚至可能也取决于表的内容)。
  2. SQL注入 不管您说什么,使用CString::Format或任何其他方法格式化数据的来源,您都可能面临SQL注入的风险。即使您使用来自源的字符串,有时您或其他人可能会更改您的代码以接受来自外部的数据,然后您就很容易受到SQL注入的影响。如果您需要有关SQL注入的更多信息,只需搜索StackOverflow,我肯定会有一些很好的问题,或者查看下面的图片:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9189158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档