问题描述
我正在尝试执行一条select语句:
SELECT group_id
FROM ACCOUNT_GROUPS
WHERE account_id = '1'
AND admin_user = '0'
AND active = '1'
AND uname IN (<cfqueryparam value="#send_to_var#" cfsqltype="cf_sql_varchar" list="yes" />)
AND uname != ''
如果uname
是像abc1这样的单个变量,则可以正常工作。但是现在我们需要搜索更多......
所以uname
现在有一个可能的列表,例如“ abc1,abc2,abc3,abc4”
现在#send_to_var#
还可以包含多个变量,例如“ abc3,efd6,asc9”
所以我尝试了CONTAINS
和其他sql技术,但一直遇到问题。
任何人都可以提供任何建议吗?
解决方法
如果您使用的是SQL Server 2016,则有一个STRING_SPLIT
函数会将uname
列分解为一个表,您可以使用列表cfqueryparm进行搜索。您的查询将类似于:
SELECT group_id
FROM ACCOUNT_GROUPS
WHERE account_id = '1'
AND admin_user = '0'
AND active = '1'
AND EXISTS ( SELECT * FROM STRING_SPLIT (uname,',')
WHERE VALUE IN (<cfqueryparam value="#send_to_var#" cfsqltype="cf_sql_varchar" list="yes" />)
AND uname != ''
性能可能很糟糕-出于某种原因,这被认为是不良的数据设计。如果您的SQL Server不支持STRING_SPLIT,则还有其他解决方案,范围从糟到糟。编辑您的问题以发布您的SQL Server版本。
,正如其他人已经解释了为什么那样,这看起来像讨厌的DB设计。但是,如果您真的被迫坚持下去,并且没有STRING_SPLIT
支持,那么骇人听闻的骇客将是:
SELECT group_id
FROM ACCOUNT_GROUPS
WHERE account_id = '1'
AND admin_user = '0'
AND active = '1'
AND (1=0 <cfloop list="#send_to_var#" index="thisItem"> OR ','+uname+',' LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%,#thisItem#,%" /> </cfloop>)
AND uname != ''
从问题中的示例数据中假设,您的列表定界符为,
,不带空格,并且该列表中存储的值中不允许有未转义的,
字符。
如果表很大,则前导通配符会使速度变慢。但是,与数据设计相比,这是您最少的担心。最好请有时间负责的人进行大修!