【发布时间】:2021-07-18 22:47:15
【问题描述】:
我有 2 个 SQL 表,如下所示:
1.噪音
| Noise_Id | Value |
|---|---|
| 2 | 73 |
| 7 | 57 |
| 8 | 78 |
| 12 | 86 |
| 14 | 89 |
2。颜色
|ColorInt |Criteria |SortOrder|
|---------|---------------|---------|
|-1 | [Value] < 75 | 75 |
|-16711936| [Value] < 80 | 80 |
|-128 | [Value] < 85 | 85 |
|-10496 | [Value] < 90 | 90 |
|-23296 | [Value] < 95 | 95 |
|-65536 | [Value] < 100 | 100 |
|-38476 | [Value] < 105 | 105 |
|-8388480 | [Value] < 110 | 110 |
|-11861886| [Value] >= 110| 111 |
此 [Criteria] 列可以包含其他表达式,例如:
[Value]=1
[Value]=2
[Value]=3
[Value]=4
[Value]=5
FindingsCnt_Overdue > 0
FindingsCnt_Completed = FindingsCnt - FindingsCnt_Deleted
[Value] = -1
[Value] < 30
[Value] < 50
[Value] < 70
[Value] < 90
[Value] < 110
[Value] < 150
[Value] >= 150
我想根据 [Criteria] 为每个 [Noise_Id] 计算 [ColorInt],如下所示:
预期结果
| Noise_Id | Value | ColorInt |
|---|---|---|
| 2 | 73 | -1 |
| 7 | 57 | -1 |
| 8 | 78 | -16711936 |
| 12 | 86 | -10496 |
| 14 | 89 | -10496 |
我如何创建一个高效的存储过程或函数来评估每个 [Noise_Id] 的 [Criteria] 列中的表达式,并在满足 [Criteria] 时转到下一个 [Noise_Id]?
这是我尝试过的代码:
CREATE TABLE #Results (
Noise_Id int,
Value varchar(MAX))
DECLARE @SQL varchar(MAX)=''
SELECT @SQL =
@SQL+' Insert Into #Results(Noise_Id, Value) Select '+cast(Noise_Id AS varchar(50))+', case when '+Replace([Criteria],'[Value]',Value)+' then [ColorInt] else null end as Value FROM [Noise] where Noise_Id = '+cast(Noise_Id AS varchar(50))
FROM [Noise]
exec (@sql)
select * from #Results
drop table #Results
非常感谢您的帮助!
【问题讨论】:
-
标准是什么?预期的输出是什么?
-
根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。
-
你的专栏
Criteria真的有N'[Value] < 75'的价值吗?如果是这样,唯一的方法是使用动态 SQL,我强烈建议不要这样做。如果您确实走这条路(不要),我希望您有非常好的流程来确保列中的表达式不能执行任何形式的注入。如果你不这样做,那么就不要靠近动态解决方案;改为修复设计(无论如何这是真正的解决方案)。 -
如果您还有其他操作,那么您也应该将其包含在问题中,但是,这只会使我的观点更有说服力;这是需要在这里改变的设计。除非您真的知道您正在使用动态 SQL 做什么,并且您对进入列的数据采取了安全措施,否则使用动态 SQL 只会是一个(巨大的)安全漏洞。
-
@Larnu 流浪球门柱的案例。我认为这些人已经离开了球场。我放弃了。
标签: sql-server tsql dynamic-sql