我正在尝试实现一种替换WHERE子句的“动态SQL”的方法
也就是说,创建一个临时表“#FilterTable”,它包含我的WHERE的名称和值。
然后,我使用“left join”将我的目标表#Hotel映射到#FilterTable
但是,使用以下代码时出现错误:
DECLARE @filterName varchar(50)='Id',
@filterValue int =13
CREATE TABLE #Hotel (Id varchar(50), DisplayName varchar(100))
CREATE TABLE #FilterTable (Name varchar(50), Value varchar(100))
INSERT INTO #Hotel(Id,DisplayName) VALUES ('1','California Inn'), ('13','Hilton Hotel')
INSERT INTO #FilterTable(Name,Value) VALUES ('Id','13'),('DisplayName','Hotel')
SELECT a.*
FROM #Hotel a WITH(NOLOCK)
LEFT JOIN #FilterTable b WITH(NOLOCK)
ON @filterName= b.Name
AND
CASE b.Name
WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
DROP Table #Hotel
DROP Table #FilterTable
它总是在
中显示错误WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
我知道如果我改为
WHEN 'DisplayName' THEN CONVERT(varchar(10), a.Id) END = b.Value
,它会通过,但在这种情况下无法在“WHEN”子句中添加第二个条件。
有没有人知道将这两个“WHEN”条款收集起来的正确语法是什么? 我的db版本是SQL SERVER 2014 Enterprise 谢谢。
答案 0 :(得分:1)
CASE的语法不正确。你在C,Java等中使用它就像一个switch语句。你没有说一个值的情况,然后打开值。相反,它就像一个if语句,其中每个条件都是独立的。
if (CUSTOM_CLOCK_MONOTONIC != CLOCK_REALTIME) {
if (clock_gettime(CUSTOM_CLOCK_MONOTONIC,tp) == 0) {
return;
}
}
这表示,如果squared = 0
def square(n):
"""Returns the square of a number."""
squared = n**2
print "%d squared is %d." % (n, squared)
return squared
square(10)
print(squared)
为SELECT a.*
FROM #Hotel a WITH(NOLOCK)
LEFT JOIN #FilterTable b WITH(NOLOCK)
ON @filterName= b.Name
AND
CASE
WHEN b.Name = 'Id' AND CONVERT(varchar(10), a.Id) = b.Value THEN 1
WHEN b.Name = 'DisplayName' AND a.DisplayName like b.Value THEN 1
ELSE 0
END = 1
并且转换模式匹配,则行匹配,或b.Name
为ID
且显示名称为{{1}行匹配。
试一试。
我必须指出,考虑到多行,这可能无法很好地扩展。您应该对每个案例都有一个单独的查询,以便SQL Server可以使用适当的索引和统计信息。
答案 1 :(得分:0)
在您的代码中:
WHEN 'Id' THEN CONVERT(varchar(10), a.Id) = b.Value
WHEN 'DisplayName' THEN a.DisplayName like b.Value END
= b.Value
和like b.Value
等于= b.Value
。如果您想使用LIKE
,则必须添加:like '%' + b.Value + '%'
但如果它并不意味着你可以使用:
b.Value = CASE b.Name
WHEN 'Id' THEN CONVERT(varchar(10), a.Id)
WHEN 'DisplayName' THEN a.DisplayName END