0

我正在使用 asp.net 开发网站。

我有一种情况,我需要根据使用 SQL 的界面中的复选框驱动的几种过滤机制来查询表。所以过滤器可能有几种组合。所以最后我发现这可以通过使用动态 sql 查询来实现。所以我写了一个存储过程,然后在生成正确的查询后将查询从应用程序传递给存储过程。

我的示例存储过程将是这样的

CREATE PROCEDURE usp_dynamic(IN query_one VARCHAR(500))
BEGIN
    SET @s = CONCAT('SELECT col1,col2 FROM test_table where',query_one );
    PREPARE stmt FROM @s;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END

所以我有几个问题

1)这安全吗?我的意思是它会导致sql注入吗?

2)存储过程总是编译为最佳查询计划。那么动态查询会导致每次得到查询时重新编译SP,对吗?

3) 是否有任何性能问题?

4)当我使用这种方法时,我还需要注意其他任何事实吗?

5)如果有任何问题可以采取什么措施来减少这些事情?

4

2 回答 2

0

仅仅因为您在服务器上构建查询,没有任何变化。完全相同的问题也适用。问题是“动态sql”本身的使用,而不是它的执行位置

具体来说:

  1. 安全性没有改善。1=1;drop table users;--仍然可以作为输入传递。
  2. 所有 SQL 代码都被编译成一个查询计划。存储过程不会产生更好的计划。好处是您可以重用存储过程的计划,除非它执行的查询发生更改。以编程方式构造执行不同查询的条件语句就是这种情况。所以你也没有得到任何查询计划的好处。
  3. 性能根本没有提高。无论您是显式准备语句还是让查询优化器创建计划,都必须编译每个单独的查询。

事实上,从客户端发送的参数化查询会更安全且性能更好,因为可以防止注入,并且查询优化器将能够创建和重用参数化查询计划

于 2015-05-28T08:01:37.263 回答
0

只要有动态 SQL 被粗心处理(不带参数),SQL 注入就成为可能,无论是从客户端发送的 SQL 语句,在 T-SQL 存储过程中生成的动态 SQL,还是从 CLR 存储过程执行的 SQL 批处理。

存储过程优于从客户端发送的 SQL 的另一个优点是通过网络传输的字节更少。您只需传递存储过程的名称和几个参数,而不是通过网络发送 50 行查询。如果计算需要多个查询,这可能会变得更加重要,可能在两者之间有逻辑。如果所有逻辑都在数据库之外,这可能意味着数据必须传输到客户端,然后才能在下一刻返回。

因此这里考虑性能。

遵循这些做法以获得更好的动态查询

于 2015-05-28T08:07:03.383 回答