Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Запрос c проверкой на существование столбца  [new]
Denis Stowattoff
Member

Откуда:
Сообщений: 31
Ребят, подскажите, можно ли составить такой запрос без использования sp_executesql, чтобы он выполнялся, когда столбца HF нет.

Вот пример моего запроса:

USE Test
if (columnproperty(object_id('VersionInfo'),'HF','AllowsNull') is not null)
  SELECT [Version] + ' HF' + convert(varchar,[HF]) FROM [VersionInfo]
else        
  SELECT [Version] FROM [VersionInfo]


Проблема при выполнении данного запроса в том, что там, где столбца HF нет - SQL Server отказывается выполнять запрос. Хотя у меня в таком случае должен выполняться select без запроса этой колонки.
3 дек 14, 15:10    [16944040]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
if not exists (
   select 1
   from INFORMATION_SCHEMA.COLUMNS
   where TABLE_NAME = 'VersionInfo'
     and COLUMN_NAME = 'HF'
)
begin
 -- если столбеца  в таблице нет
end else
begin
-- если столбец в таблице есть
end
3 дек 14, 15:14    [16944071]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Denis Stowattoff
Member

Откуда:
Сообщений: 31
Maxx, спасибо, но проблема не меняется.
SQL Server ругается на использование столбца HF в первом селекте. Просто говорит, что такого столбца нет и всё. И не важно - будет этот селект выполняться или нет.
3 дек 14, 15:28    [16944186]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
таки проверил сам - в таком случае только dsql ибо ето на етапе проверки происходит..до выполнения кода даже не доходит
3 дек 14, 15:30    [16944200]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Странный запрос к странной базе, индетерменизм вообще-то недопустим в реляционных БД.
Формируйте запрос на клиенте, если так уж надо, ибо если в базе, в которой находится процедура, отсутствует столбец, то база поломана.
3 дек 14, 15:54    [16944379]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Denis Stowattoff
Member

Откуда:
Сообщений: 31
Мне нужно выполнять запрос на БД разных версий.

В последних версиях БД появился столбец HF и хорошо бы его тоже запрашивать, если он есть.
В предыдущих версиях столбца нет и я хочу делать запрос без обращения к столбцу HF.
3 дек 14, 16:17    [16944582]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3274
Denis Stowattoff,

Делаете ДВА запроса.

В первом выясняете версию схемы базы (наличие/отсутствие столбца), во втором - соотв. запрос, который не сломается. Если запросов много, ты выяснение версии можно делать один раз.
3 дек 14, 16:18    [16944594]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Этот запрос хранится в базе или его формирует клиент?
3 дек 14, 16:22    [16944623]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Denis Stowattoff
Member

Откуда:
Сообщений: 31
Запрос у меня статически зашит в клиенте. В данный момент внедрять в программу логику изменения запроса в зависимости от другого запроса не планирую, т.к. это потребовалось только в данном случае.

Использовал такой способ, который меня на данный момент устраивает:

declare @sqls nvarchar(255)
declare @res int
declare @hf nvarchar(64) = ''

if (columnproperty(object_id('VersionInfo'),'HF','AllowsNull') is not null)
	set @hf = ' + ('' HF'' + convert(varchar,[HF]))'

set @sqls = 'USE Test SELECT ([Version] + ''.'' + convert(varchar,[PatchVersion]))' + @hf + ' as [Версия]'

exec sp_executesql @sqls, N'@res varchar(100) out', @res = @res out
3 дек 14, 16:45    [16944825]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
ну так выж не наличие столбца то проверяете в конце то концовю Вы определитесь вам или столбец или нулл значения в нем надо
3 дек 14, 17:00    [16944903]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Диклевич Александр
Member

Откуда:
Сообщений: 610
Вот так трюк:
Столбца нет
DECLARE @TableA table([id] [int] NOT NULL);

INSERT INTO @TableA([id]) VALUES (1), (2);

SELECT x.*
FROM (SELECT NULL AS SomeCol) AS dummy
CROSS APPLY
(
  SELECT
    ID,
    SomeCol AS MyTest
  FROM @TableA
) AS x;

а выборка работает.

А теперь столбец есть
DECLARE @TableA table([id] [int] NOT NULL, [SomeCol] [int] NOT NULL);

INSERT INTO @TableA([id], [SomeCol]) VALUES (1, 1), (2, 2);

SELECT x.*
FROM (SELECT NULL AS SomeCol) AS dummy
CROSS APPLY
(
  SELECT
    ID,
    SomeCol AS MyTest
  FROM @TableA
) AS x;

тоже работает!

Воспроизводил на
(
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
May 14 2014 18:34:29
Copyright (c) Microsoft Corporation
Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
)
3 дек 14, 21:43    [16946488]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Диклевич Александр
Вот так трюк:
Столбца нет
DECLARE @TableA table([id] [int] NOT NULL);

INSERT INTO @TableA([id]) VALUES (1), (2);

SELECT x.*
FROM (SELECT NULL AS SomeCol) AS dummy
CROSS APPLY
(
  SELECT
    ID,
    SomeCol AS MyTest
  FROM @TableA
) AS x;


а выборка работает.

А теперь столбец есть
DECLARE @TableA table([id] [int] NOT NULL, [SomeCol] [int] NOT NULL);

INSERT INTO @TableA([id], [SomeCol]) VALUES (1, 1), (2, 2);

SELECT x.*
FROM (SELECT NULL AS SomeCol) AS dummy
CROSS APPLY
(
  SELECT
    ID,
    SomeCol AS MyTest
  FROM @TableA
) AS x;


тоже работает!

Воспроизводил на
(
Microsoft SQL Server 2012 - 11.0.5058.0 (X64)
May 14 2014 18:34:29
Copyright (c) Microsoft Corporation
Developer Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
)
А где тут трюк-то?
В подзапросе CROSS APPLY видны все поля таблиц из FROMа.
Если в таблице подзапроса поля с указанным именем нет, берётся поле из внешних запросов.
Поэтому в двух приведённых запросах поле SomeCol - из разных таблиц.
В первом из dummy, во втором - из @TableA
3 дек 14, 22:11    [16946599]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Обычно такие вопросы возникали по поводу коррелированных подзапросов.
3 дек 14, 22:23    [16946630]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Диклевич Александр
Member

Откуда:
Сообщений: 610
iap,

так в том и трюк.
это же надо ТС?
3 дек 14, 22:24    [16946631]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Denis Stowattoff
Member

Откуда:
Сообщений: 31
Maxx
ну так выж не наличие столбца то проверяете в конце то концовю Вы определитесь вам или столбец или нулл значения в нем надо

Согласен - обычно использую if not exist. Просто во время шаманств перепробовал множество способов - в надежде, что MS SQL поймёт, что проверка на наличие столбца у меня уже выполняется. Ну да не суть...


Диклевич Александр
Вот так трюк:
Столбца нет ...


Действительно, трюк!
Принцип, конечно, понятен. Но сам я пока не умею генерировать такие решения... ))
4 дек 14, 08:45    [16947366]     Ответить | Цитировать Сообщить модератору
 Re: Запрос c проверкой на существование столбца  [new]
Glory
Member

Откуда:
Сообщений: 104760
Denis Stowattoff
Просто во время шаманств перепробовал множество способов - в надежде, что MS SQL поймёт, что проверка на наличие столбца у меня уже выполняется.

Пакет компилируется ДО выполения. Поэтому MS SQL никогда не поймет, какая ветка условного выполнения будет выполнена, а какая не будет. Поэтому компилятор проверяет все ветки.

Поэтому, если вы хотите, чтобы разные части пакета компилировались в разное время, то вам придется ваш единый пакет разделить на несколько
4 дек 14, 09:13    [16947436]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить