如何使用存储在表中的表/列名选择数据?动态建立SQL?

时间:2018-11-20 11:25:29

标签: sql database postgresql

我有一个表格,显示事件和与这些事件相关的载具:

id | model | colour     | cargo
--------------------------------------------
1 | vw       | red      | tomatoes
2 | bmw      | red      | golf clubs

我想要一个可用于管理警报的表。有一列代表要检查的字符串,另一列显示了要应用于的列/表,以及一些描述警报的文本:

id | column_name    | check_string     | alert_string
--------------------------------------------
1 | my_table.colour | red              | 'Vehicle is red'
2 | my_table.cargo  | [sport,club]     | 'Vehicle is carrying sports goods'

或可能:

id | column_name    | check_string     | alert_string
--------------------------------------------
1 | my_table.colour | red              | 'Vehicle is red'
2 | my_table.cargo  | sport            | 'Vehicle is carrying sports goods'
3 | my_table.cargo  | club             | 'Vehicle is carrying sports goods'

我想要一个可以运行的查询,该查询将返回适用于该行的所有警报:

id | alert_text
--------------------------------------------
1 | ['Vehicle is red']
2 | ['Vehicle is red', 'Vehicle is carrying sports goods']

我这样做的方式是在Python中构建SQL命令并在数据库上运行它们,但是随着规则数量的增加或需要更改/更新变量,这成为了负担(突然之间,我们并不关心红色汽车,但非常关注蓝色汽车)。

SELECT id, 'Vehicle is red' as alert_text FROM my_table 
WHERE my_table.colour = 'red';

SELECT id, 'Sports goods' as alert_text FROM my_table 
WHERE my_table.cargo in ['sport', 'club'];

SELECT <many other rules>;

有更好的方法吗?是否值得构建一个数据库表,该表可以动态指向一列,可以输入字符串以检查该列,然后发出与规则关联的警报文本?我是否应该甚至使用SQL来解决这个问题?

我觉得SQL可能不是适合此工作的工具,但我不知道我不知道的事...

1 个答案:

答案 0 :(得分:0)

此SQL代码将允许您为事件和警报使用任意大小的数据库表

Declare @vSQL nvarchar(Max)
Declare @vColumnName nvarchar(25)
Declare @vCheckString nvarchar(25)
Declare @vAlertString nvarchar(50)

Declare vCursor CURSOR For
  Select [column_name], [check_string], [alert_string] From vehicle_alerts

  Open vCursor;
  Fetch Next From vCursor Into @vColumnName, @vCheckString, @vAlertString

  --Make global temp table from source then delete contents.  
  --Ensures field lengths are as large as the largest value in the temp table (Not the most efficient but it works)
  Select id, alert_string INTO ##alerts From vehicle_alerts
  Delete From ##alerts  

  While @@FETCH_STATUS = 0  --Loop through alerts and interrogate your events using the LIKE operator
  Begin
     Set @vSQL = 'INSERT INTO ##alerts Select id, '''+@vAlertString+''' As [Alert] From vehicle_events Where ' + @vColumnName + ' Like ''%' + @vCheckString + '%'''
     Execute (@vSQL)
     Fetch Next From vCursor Into @vColumnName, @vCheckString, @vAlertString
  End;

  --Use STUFF to combine the alert strings by id
  Select id,STUFF((Select ',' + [alert_string] From ##alerts Where id = a.id FOR XML PATH('')),1,1,'') AS Tmp 
  From ##alerts AS a
  Group By id

  Drop Table ##alerts
  Close vCursor
  Deallocate vCursor