T-SQL - Как записать условное соединение

О единственном месте я соглашаюсь, что Goto мог использоваться быть, когда необходимо иметь дело с ошибками, и каждая конкретная точка, ошибка происходит, требует специальной обработки.

, Например, если Вы захватываете ресурсы и используете семафоры или взаимные исключения, необходимо захватить их в порядке, и необходимо всегда выпускать их противоположным способом.

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

всегда возможно сделать его правильно без goto, но в этом случае и немногие другие Goto является на самом деле лучшим решением, прежде всего, для удобочитаемости и пригодности для обслуживания.

-Adam

44
задан Corey Burnett 4 December 2009 в 22:02
поделиться

6 ответов

Если я правильно понимаю, это звучит так, будто ваши условия соединения будут эквивалентны
ON ((@AddressID IS NOT NULL) AND (alias.column = @AddressID)) и то же самое для присоединения к группе.

Иногда я использую это условное соединение.

44
ответ дан 26 November 2019 в 22:05
поделиться

Простые способы на самом деле не очень хорошие решения. Как бы плохо это ни звучало, лучшим решением является наличие явного IF в коде и отдельных запросов:

IF (condition) 
  SELECT ... FROM Person WHERE ...
ELSE IF (otherCondition)
  SELECT ... FROM Person JOIN ... ON ... WHERE ...
ELSE IF (moreCondition)
  SELECT ... FROM Persons JOIN ... JOIN ... WHERE ...

Причина в том, что если вы пытаетесь создать один-единственный запрос, который соответствует всем трем (или более) условиям, тогда механизм должен создать один единственный план запроса, который работает при всех условиях. В T-SQL одна инструкция равна одному плану. Помните, что планы создаются для общего случая, для любого значения переменной, поэтому результат всегда будет очень, очень плохим планом.

Хотя это противоречит здравому смыслу и кажется ужасным решением для любого программиста, так работают базы данных. Причина, по которой это не проблема в 99,99% случаев, заключается в том, что, попробовав то, что вы просите, и увидев, что это должно быть сделано,

25
ответ дан 26 November 2019 в 22:05
поделиться

Да, это очень просто. Сделайте левые присоединения по адресу и группам. Затем в предложении where ...

(@group_id is null or g.group_id = @group_id)
and (@address_id is null or a.address_id = @address_id)
7
ответ дан 26 November 2019 в 22:05
поделиться

У вас должна быть возможность расширить это ...

DECLARE @SQL varchar(max)

    SET @SQL = 'SELECT * FROM PERSON P'

    IF NULLIF(@ADDRESSID,"") IS NULL SET @SQL = @SQL + " INNER JOIN ADDRESSES A ON P.AddressID = A.AddressID"

    EXEC sp_executesql @SQL, N'@ADDRESSID int', @ADDRESSID
3
ответ дан 26 November 2019 в 22:05
поделиться

То, что написал Quntin, неплохо, однако с ним есть некоторые проблемы с производительностью. Хотите верьте, хотите нет, но быстрее всего проверить каждый параметр и написать SQL Join. на основе случая

Дополнительно:

IF @AddressParameter IS NOT NULL
BEGIN
SELECT blah1, blah2 FROM OneTable INNER JOIN AddressTable WHERE ....
-more code
END
ELSE...
BEGIN
END
...

Еще вы можете выполнить соединения и в фильтре запроса (предложение where) вы можете сделать:

WHERE
(Address = @Address OR @Address IS NULL)

Производительность здесь тоже сомнительная.

0
ответ дан 26 November 2019 в 22:05
поделиться

Соедините три таблицы вместе и используйте что-то вроде этого в своем предложении WHERE:

WHERE Addresses.ID = COALESCE(@AddressID, Addresses.ID)
AND  Groups.ID = COALESCE(@GroupID, Groups.ID)
0
ответ дан 26 November 2019 в 22:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: