:: Не фоксом единым
MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Понадобилось немножко в MS SQL-е покопаться. На Oracl-е делал так:

begin
for txtColumn in
( select column_name
from user_tab_columns
where table_name = 'MYTABLE'
and data_type='VARCHAR2')
loop
dbms_output.put_line('Название столбца '||txtColumn.column_name);
end loop;
end;

Можно это "в лоб" (как можно ближе, что бы один в один) перевести на MS SQL?



Исправлено 1 раз(а). Последнее : S-type, 05.07.16 12:45
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
У меня получилось

begin
declare @Column sysname
declare txtColumn cursor for
select c.name
from syscolumns c
inner join sysobjects o
on o.id = c.id
where c.xtype=231
and o.name='MYTABLE'
open txtColumn
while (1=1)
begin
fetch next
from txtColumn
into @Column
if @@fetch_status!=0 break
PRINT 'Название столбца '+@Column
end
close txtColumn
deallocate txtColumn
end

Т.е. пришлось создать дополнительную переменную и явно описать курсор. Но, IMHO, как то всё коряво. Можно упростить?
Пожалуйста, покритикуйте этот код - как его улучшить?



Исправлено 2 раз(а). Последнее : S-type, 05.07.16 12:41
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
PaulWist

Сообщений: 14601
Дата регистрации: 01.04.2004
Что в итоге должно получиться? перечень столбцов в таблице?

use msdb
declare
@NameTable nvarchar(100) = N'DTA_Input',
@xtype nvarchar(10) = N'U'
select * from sys.sysobjects o
inner join sys.syscolumns l on l.id = o.id
inner join sys.systypes t on l.xtype = t.xusertype
where
o.name = @NameTable and o.xtype = @xtype -- 'U' -- user table, V -- user view, TF - табл ф-ия


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 2 раз(а). Последнее : PaulWist, 05.07.16 13:15
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Запрос не важен. Колонки не при чём.

В Oracle есть конструкция вида

for переменная in
( запрос) -- обычный запрос вида "select список_полей from таблица ..."
loop
действие; -- доступ к результата запроса через "переменная.поле"
end loop;

Есть ли такая конструкция в MS SQL? Что бы без явного создания курсора?



Исправлено 2 раз(а). Последнее : S-type, 05.07.16 13:23
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
Есть ли такая конструкция в MS SQL? Что бы без явного создания курсора?
Пока нету На самом деле в оракле это по сути синтаксический сахар - что неявный курсор и неявная record-переменная, что сам цикл FOR по курсору. Меньше буковок в исходнике, но по сути тот же самый результат. Естественно при "ручном" рулении курсором доступно гораздо больше всяких "фишек", но они нужны сравнительно нечасто, вот и придумали упрощающую жизнь разработчика конструкцию...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
pasha_usue

Сообщений: 3647
Откуда: Е-бург
Дата регистрации: 06.10.2006
Мне когда навскидку надо было, я не нашёл. Сделал примерно так же.
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
А что то типа SYS_REFCURSOR в MS SQL есть?
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
А Execute Immediate есть? Например, в Oracle есть такой код

declare
lColumn varchar2(200);
sql_stmt varchar2(200);
count_rec integer;
cursor txtColumn
is
select column_name
from user_tab_columns
where table_name = 'MYTABLE'
and data_type='VARCHAR2';
begin
open txtColumn;
loop
fetch txtColumn
into lColumn;
exit when txtColumn%NOTFOUND;
sql_stmt := 'SELECT count(*) FROM MYTABLE WHERE '||lColumn||' = :1';
EXECUTE IMMEDIATE sql_stmt INTO count_rec using 'какое то значение'; -- это можно как то в MS SQL-е сделать?
if count_rec>0 then
dbms_output.put_line('Название столбца '||lColumn);
end if;
end loop;
close txtColumn;
end;
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
PaulWist

Сообщений: 14601
Дата регистрации: 01.04.2004
На выбор:

declare @str nvarchar(100) = N'select 1, getdate() '
exec (@str)
exec sp_executesql @str


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
А входной и выходной параметры?
exec (@str)

Тут параметров нет - сразу в топку.

exec sp_executesql @str

На сколько понял, параметры возможны, осталось понять "как".
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
pasha_usue

Сообщений: 3647
Откуда: Е-бург
Дата регистрации: 06.10.2006
Ключевое слово: OUTPUT
https://msdn.microsoft.com
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
PaulWist

Сообщений: 14601
Дата регистрации: 01.04.2004
declare
@str nvarchar(100) = N'select @OutVar = dateadd(day, @nDay, getdate()) ', -- скрипт добавляет к текущей дате 30 дней
@nDay int = 30, -- кол-во доб. дней
@OutVar datetime -- сюда вернём результат, будет август
exec sp_executesql @str,
N'@nDay int, @OutVar datetime OUTPUT',
@nDay = @nDay, @OutVar = @OutVar OUTPUT
select @OutVar


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено 1 раз(а). Последнее : PaulWist, 05.07.16 14:58
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Спасибо!

В итоге получилось:

begin
declare @Column sysname
declare @sql_stmt nvarchar(200)
declare @count_rec int
declare txtColumn cursor for
select c.name
from syscolumns c
inner join sysobjects o
on o.id = c.id
where c.xtype=231
and o.name='tbl_Account'
open txtColumn
while (1=1)
begin
fetch next
from txtColumn
into @Column
if @@fetch_status!=0 break
set @sql_stmt = 'SELECT @count_rec=count(*) FROM MYTABLE WHERE '+@Column+'=@par1'
exec sp_executesql @sql_stmt, N'@par1 nvarchar(200), @count_rec int OUTPUT', @par1=N'какое то значение', @count_rec=@count_rec OUTPUT
if @count_rec>0 begin
PRINT 'Название столбца '+@Column
end
end
close txtColumn
deallocate txtColumn
end

Зверский какой то синтаксис...
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
PaulWist

Сообщений: 14601
Дата регистрации: 01.04.2004
S-type
Зверский какой то синтаксис...

Ты бы на пальцах объяснил, что надо в итоге получить, тогда решение может было бы проще.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
В Oracl-е

sql_stmt := 'SELECT count(*) FROM MYTABLE WHERE '||lColumn||' = :1';
EXECUTE IMMEDIATE sql_stmt INTO count_rec using 'какое то значение';

В MS SQL-е

set @sql_stmt = 'SELECT @count_rec=count(*) FROM MYTABLE WHERE '+@Column+'=@par1'
exec sp_executesql @sql_stmt, N'@par1 nvarchar(200), @count_rec int OUTPUT', @par1=N'какое то значение', @count_rec=@count_rec OUTPUT

Что бы сделать то же - букв больше, "конструкций" больше и, соответственно, возможностей ошибиться то же больше... а результат выполнения программы тот же.
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Зверский не синтаксис, а задача - динамический SQL вообще достаточно нечасто нужен А задачи из разряда "пойди туда - не знаю куда, принести то не знаю что" так и вовсе редчайшие исключения. Вообще такой фигни кроме как для целей кодогенерации/отладки/поиска косяков в БД я никогда и не использовал


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Задача - изучаю новый софт. AuditModern. Вендор на вопросы отмалчивается, приходится рыскать по базе, искать - что где в каком месте лежит. Соответствующие скрипты для Oracl-а есть, но тут база на MS SQL. Вот, колюсь, мучаюсь и изобретаю велосипед...
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
ssa

Сообщений: 12999
Откуда: Москва
Дата регистрации: 23.03.2005
Писание чего-то жутко универсального в декларативных языках, к коим относится и T-SQL как один из диалектов SQL, очень неблагодарное и часто вредное дело.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
ssa
Писание чего-то жутко универсального в декларативных языках, к коим относится и T-SQL как один из диалектов SQL, очень неблагодарное и часто вредное дело.

Честно говоря, не понял - к чему была эта фраза?

Есть интерфейс программы, в котором видны данные. Есть база, в которой лежат данные. Небольшой скрипт перебирает все таблицы базы (коих 679), просматривает все текстовые поля (коих 1145), перебирает все записи (считать лень) и меньше чем за секунду находит, что подразделения находятся в таблице tbl_OrganChart (кто бы мог подумать). Глазками делать это было бы долго. А так - и задача решена, и пару скриптов скриптов в "загашник" закинул.
Ratings: 0 negative/0 positive
Re: MSSQL - есть ли такая конструкция
ssa

Сообщений: 12999
Откуда: Москва
Дата регистрации: 23.03.2005
Для получения списка всех текстовых полей всех таблиц совершенно не нужны курсоры, перебирания таблиц и прочая ерундистика.
S-type
set @sql_stmt = 'SELECT @count_rec=count(*) FROM MYTABLE WHERE '+@Column+'=@par1'
exec sp_executesql @sql_stmt, N'@par1 nvarchar(200), @count_rec int OUTPUT', @par1=N'какое то значение', @count_rec=@count_rec OUTPUT
Конкатенацию строк для получения текста запроса лучше делают клиенты. На сервере такой вот универсальный код получения количества строк с каким-то значением поля менее эффективен.
Все вместе выливается в напрасную трату времени и средств.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 2 (Гостей: 2)

© 2000-2024 Fox Club 
Яндекс.Метрика