2015-09-02 7 views
-1

Я пытаюсь реализовать способ замены «динамического SQL» предложения WHERE.
То есть, чтобы создать временную таблицу «#FilterTable», которая содержит имя и значение моего WHERE.
Затем я использую «левое соединение» для отображения моей целевой таблицы #Hotel с #FilterTable.
Однако, я получил сообщение об ошибке при использовании следующего кода:LEFT JOIN with CASE WHEN

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 

, он будет pass, но в этой ситуации нет возможности добавить второе условие в предложение WHEN.

Кто-нибудь знает, что такое правильный синтаксис, чтобы поставить эти два предложения «КОГДА» togather?
Моя версия db - это SQL SERVER 2014 Enterprise.
Спасибо.

ответ

1

Ваш синтаксис для CASE неверен. Вы используете его как оператор switch в C, Java и т. Д. Вы не говорите аргумент о значении, а затем включаете значение. Скорее, это как оператор if, где каждое условие является независимым.

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.NameID и шаблон преобразования матчей, строка соответствует, или если это b.NameDisplayName и имя дисплея, как b.Value, строка матчей.

Дайте это попробовать.

Я должен указать, что это, вероятно, недостаточно масштабируется при заданных нескольких строках. У вас действительно должен быть отдельный запрос для каждого случая, чтобы SQL Server мог использовать соответствующие индексы и статистику.

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 
+0

Благодарим Вас за уведомление @MegaTron – user3174976