什么是准备好的陈述?它们与动态sql有何不同?

时间:2010-08-24 02:14:19

标签: sql sql-server database

我没有看到任何重复的问题,但想知道是否有人可以提供一些好的例子和特别的最佳实践。

3 个答案:

答案 0 :(得分:2)

准备好的语句是预编译的语句,您可以在数据库上多次运行,并且SQLServer每次运行时都不会解析或生成不同的执行计划。通常,您在客户端上下文中运行预准备语句(使用JDBC,ADO.NET,ODBC或任何其他客户端访问技术)。

Java中的预准备语句(当然使用JDBC)将类似于:

PreparedStatement ps = conn.prepareStatmente("insert into t(field1) values (?)");
ps.setString(1, "Hello");
ps.executeUpdate();
ps.setStrgin(2, "World");
ps.executeUpdate();
ps.close();
// two rows will be inserted into table t:
// field1 => "Hello"
// field1 => "world"

Dynamic SQL能够在SQLServer中的存储过程或函数内运行存储在动态变量(即字符串)中的任何SQL语句。您可以在提供的链接中找到一些示例。

答案 1 :(得分:1)

用某些背景来解释会更容易......

Java, PreparedStatements中是Java String中的SQL语句,并且支持可以填充的占位符,而不必担心转义单引号。 .NET also has PreparedStatement syntax

  

应用程序通常使用准备执行来重复执行相同的参数化SQL语句。准备执行比执行超过三次或四次的语句的直接执行更快,因为语句只编译一次,而直接执行的语句每次执行时都会编译。准备执行还可以减少网络流量,因为驱动程序可以在每次执行语句时向数据源发送执行计划标识符和参数值,而不是整个SQL语句。

缺少使用存储过程...

MySQL's dynamic SQL syntax is also called PreparedStatements ...

动态SQL

动态SQL基本上是声明为字符串数据类型的任何SQL - 它可以在执行前自定义。当您想要执行动态列和/或表引用等操作时,需要使用动态SQL。例如,没有SQL支持字符串变量来表示FROM子句中的表(表值变量是一个例外,在支持的情况下)。

了解EXECEXEC sp_executesql之间关于SQL Server上的动态SQL的区别非常重要。 SQL Server 2005中添加了EXEC sp_executesql,您可以在优秀的文章中阅读有关SQL Server上的动态SQL的更多信息:The Curse and Blessings of Dynamic SQL

答案 2 :(得分:0)

PreparedStaement是一种语言结构,提供已在上述答案中解释过的预编译查询。使用预准备语句的一个非常重要的好处是它们可以避免恶意SQL注入攻击。怎么样?您只有占位符,您可以在其中放入值而无其他方式来更改查询(预编译),而在语句的情况下,您可以更改查询字符串。例如:

我有一个更新表的查询 -

UPDATE table_name SET col1 = 40 WHERE id = 'A001';

这可以(恶意地)改为 -

UPDATE table_name SET col1 = 40 WHERE id = 'A001'; DROP TABLE table_name;

你的桌子不见了!

动态查询是一种数据库结构,可帮助您编写一个查询,您可以在其中使用绑定变量而不是使用值。这些特别用于PL / SQL代码。在执行DDL语句时也很有用。示例代码(Oracle):

ip_job_name := 'APP_EXTRACT'; lv_query := 'SELECT 1 FROM user_table WHERE table_name = :tab_name';

BEGIN

EXECUTE IMMEDIATE lv_query INTO lv_tab USING ip_job_name;

EXECUTE IMMEDIATE 'DROP TABLE ' || ip_job_name;

EXCEPTION

WHEN NO_DATA_FOUND THEN NULL;

END;