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

Откуда:
Сообщений: 5
Доброго времени суток уважаемые форумчане!

Не так давно начал осваивать T-SQL и при решении задачи возникли некоторые вопросы:

1) Почему эти запросы дают разный результат?
declare @NameOfColumn varchar(12)
set @NameOfColumn = (COL_NAME(OBJECT_ID('Test_Table_1'),1))

exec('select ' + @NameOfColumn + ' from Test_Table_1')
exec('select (COL_NAME(OBJECT_ID(''Test_Table_1''),1)) from Test_Table_1')


2) Как нужно переписать
select count( distinct @NameOfColumn )
from  Test_Table_1

чтобы я мог правильно посчитать количество уникальных значений поля @NameOfColumn (в этом случае выводится название поля ровно столько раз, сколько записей в таблице, а следовательно - результат 1)?

3*) Литература говорит, что поля в таблицах не упорядочены, что к ним нельзя обратиться: "Выведи первый столбец", но для таблиц существует существует функция COL_NAME(), один из аргументов которой требует ID столбца, получается, что они все же имеют порядок?
30 мар 15, 15:02    [17450276]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
Glory
Member

Откуда:
Сообщений: 104760
Fimka2807
1) Почему эти запросы дают разный результат?

Потому, что это разные запросы

Fimka2807
3*) Литература говорит, что поля в таблицах не упорядочены, что к ним нельзя обратиться: "Выведи первый столбец", но для таблиц существует существует функция COL_NAME(), один из аргументов которой требует ID столбца, получается, что они все же имеют порядок?

ID - это идентификатор столбца. А не порядковый номер

Fimka2807
2) Как нужно переписать
select count( distinct @NameOfColumn )
from  Test_Table_1


чтобы я мог правильно посчитать количество уникальных значений поля @NameOfColumn (в этом случае выводится название поля ровно столько раз, сколько записей в таблице, а следовательно - результат 1)?

Динамический запрос
30 мар 15, 15:05    [17450301]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
Fimka2807
Member

Откуда:
Сообщений: 5
Нашел Ваш FAQ по динамическим запросам, попытался сделать аналогично - не вышло
declare @i int
declare @NameOfColumn nvarchar(15)
declare @NameOfTable nvarchar(15)
declare @SQL nvarchar(100)

set @SQL= 'set  @i = ( select count ( distinct  @NameOfColumn  ) 
		       from @NameOfTable )'
set @NameOfColumn = COL_NAME(OBJECT_ID('Test_Table_1'),1)
set @NameOfTable = 'Test_Table_1'

exec sp_executesql @SQL, N'@i int out, 
                           @NameOfColumn nvarchar(15), 
                           @NameOfTable nvarchar(15)',   
                   @i = @i out
select @i


Необходимо объявить табличную переменную "@NameOfTable".

Подскажите что я сделал не так
30 мар 15, 16:33    [17450840]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
Glory
Member

Откуда:
Сообщений: 104760
Fimka2807
попытался сделать аналогично

Потому что у вас внутри динамического запроса получился такой же запрос, как и без динамического
30 мар 15, 16:39    [17450878]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Fimka2807,

для имени объектов БД специально придумали тип sysname
30 мар 15, 16:40    [17450888]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
Fimka2807
Member

Откуда:
Сообщений: 5
Переделал
declare @i int
declare @NameOfColumn nvarchar(15)
declare @SQL nvarchar(100)

set @SQL= 'set @i  = ( select count ( distinct' + @NameOfColumn +' ) 
		       from Test_Table_1)'
set @NameOfColumn = COL_NAME(OBJECT_ID('Test_Table_1'),1)

exec sp_executesql @SQL, N'@i int out',  @i = @i out
select @i

На этот раз работает, но выдает значение NULL:(
Так же пробовал через ввод переменной @parametr
set @parametr = N'@i int out ' + @NameOfColumn +' nvarchar(15)'

но не вышло
30 мар 15, 18:49    [17451488]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
DmitryVRN
Guest
Вы просто проверьте свой запрос, обычным выводом и все будет ясно

declare @i int
declare @NameOfColumn nvarchar(15)
declare @SQL nvarchar(100)

set @SQL= 'set @i  = ( select count ( distinct' + @NameOfColumn +' ) 
		       from Test_Table_1)'
----
PRINT @SQL
----
set @NameOfColumn = COL_NAME(OBJECT_ID('Test_Table_1'),1)

exec sp_executesql @SQL, N'@i int out',  @i = @i out
select @i
30 мар 15, 18:54    [17451505]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
Fimka2807
Member

Откуда:
Сообщений: 5
DmitryVRN, проверил, строка пустая, тогда я вообще ничего не понимаю:
Я написал
set @SQL= 'set  @i = ( select count ( distinct  @NameOfColumn  ) 
		       from @NameOfTable )'

и был дан ответ, что это не динамический запрос, хотя я делал как в примере в FAQ'е (https://www.sql.ru/faq/faq_topic.aspx?fid=104)
В чем же тогда отличие и как подавать параметры на вход?
30 мар 15, 19:14    [17451553]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
Glory
Member

Откуда:
Сообщений: 104760
Fimka2807
и был дан ответ, что это не динамический запрос

был дан другой ответ
А именно, что текст запроса внутри динамического запроса никак не отличается от текста без динамического запроса
Динамичский запрос не отменяет синтаксис
Если при синтаксисе select @NameOfColumn from Test_Table_1 сервер не будет менять переменную на ее содержимое, то и exec('select @NameOfColumn from Test_Table_1') сервер тоже не будет это делать
И в FAQ, на который вы ссылаетесь, нет ни одного примера, где сервер подменяет имя переменной на ее значение в имени поля
30 мар 15, 20:01    [17451667]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос по составлению запроса  [new]
Fimka2807
Member

Откуда:
Сообщений: 5
Нашел ошибку, все оказалось весьма просто: нужно было поменять местами set'ы
declare @i int
declare @NameOfColumn nvarchar(15)
declare @SQL nvarchar(100)

set @NameOfColumn = COL_NAME(OBJECT_ID('Test_Table_1'),1)
set @SQL= 'set @i  = ( select count ( distinct ' + @NameOfColumn +' ) 
		       from Test_Table_1)'


exec sp_executesql @SQL, N'@i int out',  @i = @i out
select @i

Всем спасибо за участие:)!
30 мар 15, 20:36    [17451784]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить