#sql #sql-server #case #sql-null
#sql #sql-сервер #случай #sql-null
Вопрос:
Итак, у меня есть запрос, который выглядит следующим образом —
select
case when @subType = 1 or @subType = 2 then id end as Id,
case when @subType = 3 then name end as name
case when @subType = 3 or @subType = 2 then address end as address
from
table
Итак, проблема, с которой я сталкиваюсь, заключается в том, что если @subType равно 3, то столбец с именем ID будет иметь значение null. Тогда я не хочу возвращать весь этот столбец. И наоборот, если @subType равно 2, то все name будет null, поэтому мне не нужен весь этот столбец.
Комментарии:
1. Результирующий набор
SELECT
инструкции должен иметь постоянную форму, определенную во время компиляции. Если вы хотите возвращать разные столбцы , в зависимости от@subType
, вы должны использовать несколько операторов и использоватьIF
..ELSE
для выбора между ними. Однако это потенциально усложнит обработку результата, поскольку теперь ваш клиент не сможет рассчитывать на присутствие всех столбцов.2. Зачем вам вообще нужен такой запрос? В каждом случае он будет возвращать разные типы данных, что означает, что клиенту придется либо обрабатывать их все как текст, объект, динамическое или слабо типизированное значение, в зависимости от языка
3.Кстати, этот запрос не вернет значения NULL. Если
subtype
равно 3, вы получитеname
только . НиAddress
то, ниID
другое не будет возвращено.4. @PanagiotisKanavos он вернет null для идентификатора, если подтип равен 3.
5.
[address]
будет возвращено значение@subtype
is3
, @PanagiotisKanavos ,CASE
выражениеcase when @subType = 3 or @subType = 2 then address end as address
Ответ №1:
Единственный способ сделать это — использовать динамический SQL (как упоминает Гордон). При условии, что это запрос, а не функция, просмотр, тогда вы могли бы сделать это:
DECLARE @subType tinyint = 3;
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT '
STUFF(CASE WHEN @subType IN (1,2) THEN N',' NCHAR(13) NCHAR(10) N' id' ELSE N'' END
CASE WHEN @subType = 3 THEN N',' NCHAR(13) NCHAR(10) N' [name]' ELSE N'' END
CASE WHEN @subType IN (3,2) THEN N',' NCHAR(13) NCHAR(10) N' [address]' ELSE N'' END, 1, 10,N'') NCHAR(13) NCHAR(10)
N'FROM YourTable;';
PRINT @SQL; --Your debugging best friend.
--EXEC sp_executesql @SQL; --Uncomment to run the statement
Но, если запрос поступает из уровня представления, то на самом деле это должно обрабатывать отображаемые столбцы, а не SQL Server
Если вы также передаете параметры в WHERE
свой запрос, убедитесь, что вы параметрируете вызов to sp_executesql
; не вводите значения параметров в динамический оператор.
Комментарии:
1. Это именно то, что мне нужно. Большое вам спасибо.
Ответ №2:
Это слишком долго для комментария.
SQL-запрос возвращает фиксированный набор столбцов с именами и типами, определенными в SELECT
. Он не может иметь переменное количество столбцов.
Чтобы делать то, что вы хотите, вам нужно будет использовать динамический SQL. Я не уверен, работает ли это в вашем контексте. Например, динамический SQL не поддерживается в пользовательских функциях SQL Server.
Комментарии:
1. пользователь может использовать двойную таблицу, затем ее можно создать на SQL server!!
2. @nikhilsugandh что бы это дало?
dual
это просто таблица чисел. Это не влияет на значения null