Mysql 什么是动态SQL?

Mysql 什么是动态SQL?,mysql,sql,stored-procedures,dynamic-sql,Mysql,Sql,Stored Procedures,Dynamic Sql,我刚刚问了一个与SQL相关的问题,第一个答案是:在这种情况下,动态SQL是一条出路 因为我以前从未听说过动态SQL,所以我立即搜索了这个网站和web以了解它是什么。维基百科没有这篇文章的标题。谷歌的第一个搜索结果都指向用户论坛,人们在那里或多或少地问一些相关的问题 然而,我没有找到什么是“动态SQL”的明确定义。这是特定于供应商的吗?我使用的是MySQL,在MySQL用户论坛上,我没有在MySQL手册中找到任何参考资料,只有一些问题,大部分是未回答的 另一方面,我发现了许多对存储过程的引用。虽然

我刚刚问了一个与SQL相关的问题,第一个答案是:在这种情况下,动态SQL是一条出路

因为我以前从未听说过动态SQL,所以我立即搜索了这个网站和web以了解它是什么。维基百科没有这篇文章的标题。谷歌的第一个搜索结果都指向用户论坛,人们在那里或多或少地问一些相关的问题

然而,我没有找到什么是“动态SQL”的明确定义。这是特定于供应商的吗?我使用的是MySQL,在MySQL用户论坛上,我没有在MySQL手册中找到任何参考资料,只有一些问题,大部分是未回答的

另一方面,我发现了许多对存储过程的引用。虽然我从未使用过任何存储过程,但我对存储过程有一点更好的理解。这两个概念有何关联?它们是相同的东西还是一个使用另一个

基本上,我们需要的是一个简单的介绍动态SQL的人谁是新的概念


注:如果您愿意,您可以尝试回答我之前提出的问题:

动态SQL只是动态生成查询的地方-对于某些供应商,您可以在一个存储过程中生成动态查询的文本,然后执行生成的SQL。在其他情况下,该术语仅指由客户机上的代码做出的决策,这至少与供应商无关。动态SQL只是一个在执行之前动态编写的SQL语句。例如,以下C语言使用参数化查询:

var command = new SqlCommand("select * from myTable where id = @someId");
command.Parameters.Add(new SqlParameter("@someId", idValue));
可以使用动态sql重新编写为:

var command = new SqlCommand("select * from myTable where id = " + idValue);
但是,请记住,动态SQL是危险的,因为它很容易允许SQL注入攻击。

是正确的,作为补充,除非您正确使用参数,而不是仅内联使用提供的文本中的参数值等。这也可能是一种安全风险。它还需要调试,等等


最后,当您不明智地使用动态SQL时,就会释放一些东西并吃掉子对象。

我认为这意味着您应该在执行查询之前动态地构建查询。对于您的其他问题,这意味着您应该首先选择所需的表名,然后使用编程语言构建第二个查询,以完成您在其他问题中想要做的事情。动态SQL是在运行时从字符串生成的SQL。动态设置过滤器或其他东西很有用

例如:

declare @sql_clause varchar(1000)  
declare @sql varchar(5000)   


set @sql_clause = ' and '    
set @sql = ' insert into #tmp  
 select   
   *
from Table 
where propA = 1 '    

if @param1 <> ''    
begin    
   set @sql = @sql + @sql_clause + ' prop1 in (' + @param1 + ')'    
end    
if @param2 <> ''    
begin    
   set @sql = @sql + @sql_clause + ' prop2 in (' + @param2 + ')'    
end 

exec(@sql)
这正是刚才提到的。要详细说明这一点,请使用以下SQL:

Select * from table1 where id = 1
我不确定您使用哪种语言连接到数据库,但如果我使用C,动态SQL查询的示例如下:

string sqlCmd = "Select * from table1 where id = " + userid;
您希望避免使用动态SQL,因为如果查询太大,要保持代码的完整性会有点麻烦。另外,非常重要的是,动态SQL容易受到SQL注入攻击

如果您使用的是SQL Server,编写上述语句的更好方法是使用参数

这是特定于供应商的吗


SQL-92标准有一整章是关于动态SQL的,第17章,但它只适用于完整的SQL-92,据我所知,没有一家供应商实现了它。

其他答案定义了动态SQL是什么,但我没有看到任何其他答案试图描述为什么我们有时需要使用它。我的经验是SQL Server,但我认为其他产品在这方面大体相似

当您要替换无法使用其他方法替换的查询部分时,动态SQL非常有用

例如,每次调用以下查询时:

SELECT OrderID, OrderDate, TotalPrice FROM Orders WHERE CustomerID = ?? 
您将为CustomerID传递不同的值。这是最简单的情况,可以通过使用参数化查询或接受参数的存储过程等来解决

一般来说,出于性能和安全考虑,应避免使用动态SQL,而应使用参数化查询。尽管性能差异可能在供应商之间存在很大差异,甚至可能在产品版本之间,甚至在服务器配置之间也存在很大差异

其他查询可以使用参数进行,但可能比动态SQL更简单:

如果总是有3个值,那么这与第一个值一样简单。但是如果这是一个可变长度的列表呢?可以使用参数,但可能非常困难。那么:

SELECT OrderID, OrderDate, TotalPrice FROM Orders WHERE CustomerID = ??
ORDER BY ??
这不能直接替换,您可以按照顺序使用一个庞大复杂的CASE语句,显式列出所有可能的字段,这可能是可行的,也可能是不可行的,这取决于可供排序的字段数量

最后,有些查询根本无法使用任何其他方法完成

假设您有一大堆订单表,这些表并没有说这是一个很棒的设计,但您可能会发现自己希望可以做一些类似的事情:

SELECT OrderID, OrderDate, TotalPrice FROM ?? WHERE CustomerID = ??
这不能用任何方法来完成 其他方法。在我的环境中,我经常遇到以下问题:

SELECT (programatically built list of fields)
FROM table1 INNER JOIN table2
(Optional INNER JOIN to table3)
WHERE (condition1)
AND (long list of other optional WHERE clauses)
再说一次,并不是说这一定是一个伟大的设计,但对于这些类型的查询来说,动态SQL是非常必要的


希望这能有所帮助。

对于大多数数据库来说,每个SQL查询都是动态的,这意味着它是一个由查询优化程序根据输入的SQL字符串和可能的参数绑定绑定变量进行解释的程序

静态SQL 但是,大多数情况下,SQL字符串不是动态构造的,而是静态构造的,无论是在PL/SQL之类的过程语言中:

对于SELECT*FROM foo中的rec,其中x=1循环 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^静态SQL .. 端环; 或者在客户端/主机语言(如Java)中,使用JDBC:

从x=1的foo中尝试ResultSet rs=stmt.executeQuerySELECT*{ //静态SQL^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. } 在这两种情况下,SQL字符串在嵌入它的语言中都是静态的。从技术上讲,它对SQL引擎仍然是动态的,它不知道SQL字符串是如何构造的,也不知道它是静态SQL字符串

动态结构化查询语言 有时,给定一些输入参数,需要动态构造SQL字符串。例如,在某些情况下,上述查询可能根本不需要任何谓词

然后,您可以选择继续动态构造字符串,例如在PL/SQL中:

声明 类型foo_c为参考光标; v_foo_c foo_c; v_foo foo%行类型; sqlvarchar21000; 开始 sql:=“从foo中选择*”; 如果有什么 sql:=sql | |'其中x=1'.-小心语法错误和SQL注入! 如果结束; 打开v_foo__c FOR sql; 环 将v_foo_c放入v_foo; 未找到v_foo_c%时退出; 端环; 终止 或者在Java/JDBC中:

字符串sql=SELECT*FROM foo; 如果有什么 sql+=其中x=1;//小心语法错误和SQL注入! try ResultSet rs=stmt.executeQuerysql{ .. } 或者

//这里没有语法错误/SQL注入风险 什么?FOO.X.eq1:DSL.trueCondition; 对于foo记录foo:DSL.usingconfiguration .选择Fromfoo .什么条件{ .. } 许多语言都有类似于上述的查询生成器库,它们在执行动态SQL时最为出色


免责声明:我在jOOQ后面的公司工作,如果能发布指向您所指问题的链接,我会很高兴:此查询的可能重复似乎会产生无效的SQL,其中和propX in…My bad:。嗯,这只是为了帮助解释。修正了。但每次我读到关于SQL注入的内容时,人们都会使用动态SQL作为纯粹的查询构造,在运行时使用字符串连接和变量。原因是他们将其与参数化查询和存储过程进行了对比。
SELECT (programatically built list of fields)
FROM table1 INNER JOIN table2
(Optional INNER JOIN to table3)
WHERE (condition1)
AND (long list of other optional WHERE clauses)