在 sql 查询中使用局部变量作为开关是不好的做法吗
Is it bad practice to use local variables as switches in sql queries
我在存储过程中有一个动态 sql 查询,我应该将其转换为 Table 值函数 (TVF)。
正在使用如下代码构建字符串:
Declare @str = 'select * from tableName where table = ''words'''
If @flag = 'ONE'
set @str = @str + 'AND year_id = '+@year_id
ELSE
If @flag = 'TWO'
set @str = @str + 'AND record_id = '+@record_id
set @str = @str + 'order by year_id, record_id'
exec (@str)
在 TVF 中,您不能 运行 插入语句,因此您不能 return 将此 exec 查询的结果提供给用户(至少据我所知,请随意纠正我)。
为了绕过这个限制,我创建了一个过滤器,它仅在局部变量具有给定值时应用。
select *
from tableName
where table = 'words'
AND (
(@flag = 'ONE' and year_id = @year_id)
OR (@flag = 'TWO' and record_id = @record_id)
)
Order by year_id, record_id
现在,这看起来适用于更简单的查询,但对于更复杂的查询,您需要为每个可能的动态 sql 字符串组合创建一个条件。
抛开这个限制,以这种方式编写查询是否存在安全 and/or 性能风险?有没有更简单的方法来为 TVF 编写这样的查询?
将动态 SQL 转换为 ITVF 的目的是消除这种废话。只需将 ITVF 写为
create function schemaNme.funcName() returns table return
select * from tableName where table = 'words';
然后让客户端直接添加任何所需的过滤条件,如下所示:
select *
from schemaNme.funcName() t
where t.year_id = @year_id;
这从物理 table 中隐藏了数据如何组装成逻辑视图的详细信息,同时仍使客户端能够根据需要进行过滤。
根据我下面的补充评论更新:
ITVF 是参数化视图,可能带有缓存的查询计划。像任何其他视图(或 table 一样),如果您希望动态修改访问机制,就像这里一样,您将不得不使用动态 SQL。然而,因为查询的内部结构已经为您封装在 ITVF 中,在这种情况下,您可以简单地动态修改 WHERE 子句,这是一个稍微简单的任务
我在存储过程中有一个动态 sql 查询,我应该将其转换为 Table 值函数 (TVF)。 正在使用如下代码构建字符串:
Declare @str = 'select * from tableName where table = ''words'''
If @flag = 'ONE'
set @str = @str + 'AND year_id = '+@year_id
ELSE
If @flag = 'TWO'
set @str = @str + 'AND record_id = '+@record_id
set @str = @str + 'order by year_id, record_id'
exec (@str)
在 TVF 中,您不能 运行 插入语句,因此您不能 return 将此 exec 查询的结果提供给用户(至少据我所知,请随意纠正我)。
为了绕过这个限制,我创建了一个过滤器,它仅在局部变量具有给定值时应用。
select *
from tableName
where table = 'words'
AND (
(@flag = 'ONE' and year_id = @year_id)
OR (@flag = 'TWO' and record_id = @record_id)
)
Order by year_id, record_id
现在,这看起来适用于更简单的查询,但对于更复杂的查询,您需要为每个可能的动态 sql 字符串组合创建一个条件。
抛开这个限制,以这种方式编写查询是否存在安全 and/or 性能风险?有没有更简单的方法来为 TVF 编写这样的查询?
将动态 SQL 转换为 ITVF 的目的是消除这种废话。只需将 ITVF 写为
create function schemaNme.funcName() returns table return
select * from tableName where table = 'words';
然后让客户端直接添加任何所需的过滤条件,如下所示:
select *
from schemaNme.funcName() t
where t.year_id = @year_id;
这从物理 table 中隐藏了数据如何组装成逻辑视图的详细信息,同时仍使客户端能够根据需要进行过滤。
根据我下面的补充评论更新:
ITVF 是参数化视图,可能带有缓存的查询计划。像任何其他视图(或 table 一样),如果您希望动态修改访问机制,就像这里一样,您将不得不使用动态 SQL。然而,因为查询的内部结构已经为您封装在 ITVF 中,在这种情况下,您可以简单地动态修改 WHERE 子句,这是一个稍微简单的任务