aug*_*tin 32 mysql sql stored-procedures dynamic-sql
我刚刚问了一个与SQL相关的问题,第一个答案是:" 这是一种动态SQL可行的方式. "
因为我之前从未听说过动态SQL,所以我立即搜索了这个网站和网页.Wikipedia没有关于此标题的文章.第一个Google结果都指向用户论坛,人们会在这些论坛中提出或多或少的相关问题.
但是,我没有找到"动态SQL"是什么的明确定义.这是供应商特定的吗?我使用MySQL并且我没有在MySQL手册中找到参考(只有问题,在MySQL用户论坛中大多没有答案).
另一方面,我发现许多对存储过程的引用.虽然我从未使用过任何存储过程,但我对存储过程的掌握稍微好一些.这两个概念有何关联?它们是相同的还是使用另一个?
基本上,我们需要的是对这个概念不熟悉的人简单介绍动态SQL.
PS:如果你有这种感觉,你可能会回答我之前提出过这个问题的问题:SQL:我们怎样才能在table1的字段中给出一个table1 JOIN table2?
Row*_*haw 23
动态SQL仅仅是在运行时构建查询的地方 - 对于某些供应商,您可以在一个存储过程中构建动态查询的文本,然后执行生成的SQL.在其他情况下,该术语仅指客户端上的代码做出的决定(这至少是供应商中立的)
Bra*_*adC 16
其他答案已经定义了什么是动态SQL,但我没有看到,试图描述任何其他的答案,为什么我们有时需要使用它.(我的经验是SQL Server,但我认为其他产品在这方面大致相似.)
当您替换无法使用其他方法替换的查询部分时,动态SQL非常有用.
例如,每次调用如下查询时:
SELECT OrderID, OrderDate, TotalPrice FROM Orders WHERE CustomerID = ??
Run Code Online (Sandbox Code Playgroud)
您将为CustomerID传递不同的值.这是最简单的情况,可以使用参数化查询或接受参数的存储过程等解决.
一般来说,出于性能和安全性原因,应避免使用动态SQL以支持参数化查询.(虽然供应商之间的性能差异可能相差很大,甚至可能在产品版本之间,甚至是服务器配置之间).
其他查询可以使用参数进行,但可能比动态SQL 更简单:
SELECT OrderID, OrderDate, TotalPrice FROM Orders
WHERE CustomerID IN (??,??,??)
Run Code Online (Sandbox Code Playgroud)
如果你总是有3个值,这就像第一个一样容易.但是,如果这是一个可变长度列表呢?它可能与参数有关,但可能非常困难.怎么样:
SELECT OrderID, OrderDate, TotalPrice FROM Orders WHERE CustomerID = ??
ORDER BY ??
Run Code Online (Sandbox Code Playgroud)
这不能直接替换,您可以使用ORDER BY中的一个巨大的复杂CASE语句来明确列出所有可能的字段,这可能是也可能不实用,具体取决于可用于排序的字段数.
最后,有些查询根本无法使用任何其他方法完成.
假设你有一堆Orders表(不是说这是一个很好的设计),但你可能会发现自己希望你可以这样做:
SELECT OrderID, OrderDate, TotalPrice FROM ?? WHERE CustomerID = ??
Run Code Online (Sandbox Code Playgroud)
使用任何其他方法无法完成此操作.在我的环境中,我经常遇到如下问题:
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)
Run Code Online (Sandbox Code Playgroud)
同样,并不是说这必然是很棒的设计,但这些类型的查询几乎都需要动态SQL.
希望这可以帮助.
Jus*_*ner 14
动态SQL只是一个在执行之前即时编写的SQL语句.例如,以下C#(使用参数化查询):
var command = new SqlCommand("select * from myTable where id = @someId");
command.Parameters.Add(new SqlParameter("@someId", idValue));
Run Code Online (Sandbox Code Playgroud)
可以使用动态sql重写为:
var command = new SqlCommand("select * from myTable where id = " + idValue);
Run Code Online (Sandbox Code Playgroud)
但请记住,动态SQL很危险,因为它很容易引发SQL注入攻击.
Ped*_*dro 10
动态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)
Run Code Online (Sandbox Code Playgroud)