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

Откуда:
Сообщений: 22
Подскажите, как можно выполнить для каждой строки набора данных скрипт, который генерируется на лету. Если бы была функция, то CROSS APPLY подошел, но ситуация иная: есть список таблиц из базы, и генерируемый скрипт (текст), который для каждой строки(таблицы) считает количество строк в ней.

SELECT SCHEMA_NAME(SCHEMA_ID) + '.' + o.name as table_name,
'Select ''' + SCHEMA_NAME(SCHEMA_ID) + '.'
+ o.name + ''' as DBName, count(*) as Count From ' + SCHEMA_NAME(SCHEMA_ID) + '.'
+ o.name
+ ';' AS ' Script generator'
FROM sys.objects o
WHERE o.[type] = 'U'
ORDER BY SCHEMA_NAME(o.schema_id), o.name;

Спустя время я додумался взять выдачу кода выше (поле Script generator), поставить UNION в конце каждой строки и запустить снова. Норм. Но хочется знать как одним запросом это сделать. Курсор/цикл какой-нибудь.. или как?
7 авг 19, 19:24    [21944122]     Ответить | Цитировать Сообщить модератору
 Re: выполнить генерируемый на лету скрипт к каждой строке набора данных  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29799
Pasha4
Спустя время я додумался взять выдачу кода выше (поле Script generator), поставить UNION в конце каждой строки и запустить снова. Норм. Но хочется знать как одним запросом это сделать. Курсор/цикл какой-нибудь.. или как?
Положить полученное в переменную, и выполнить командой EXEC()
7 авг 19, 20:09    [21944143]     Ответить | Цитировать Сообщить модератору
 Re: выполнить генерируемый на лету скрипт к каждой строке набора данных  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8567
Pasha4,
ну а чем не подходит курсор?
Условия задачи не понятны. Поясните...
7 авг 19, 20:12    [21944144]     Ответить | Цитировать Сообщить модератору
 Re: выполнить генерируемый на лету скрипт к каждой строке набора данных  [new]
komrad
Member

Откуда: Msk -> Utrecht
Сообщений: 5090
Pasha4,

если я правильно понял, то стоит задача вернуть список таблиц и кол-во записей в них

см тут:
https://blog.sqlauthority.com/2017/05/25/sql-server-simple-query-list-size-table-row-counts/
7 авг 19, 20:24    [21944150]     Ответить | Цитировать Сообщить модератору
 Re: выполнить генерируемый на лету скрипт к каждой строке набора данных  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8567
ms_forEachTable ?
8 авг 19, 03:26    [21944267]     Ответить | Цитировать Сообщить модератору
 Re: выполнить генерируемый на лету скрипт к каждой строке набора данных  [new]
vikkiv
Member

Откуда: London
Сообщений: 2508
для такого частного случая действительно наверное простейший вариант
пойти путём предложенным SIMPLicity_ типа (что первое нагуглилось):
declare @t table(TableName nvarchar(128),NumRecords int)
insert into @t exec sp_MSforeachtable
'SELECT ''?'' TableName, Count(1) NumRecords from ?'
select*from @t order by 1
или то что Profiler перехватывает при выполнении отчёта "Disk Usage by Table" в SSMS
SELECT a3.name [schemaname],a2.name [tablename],a1.rows row_count,
       (a1.reserved+ISNULL(a4.reserved,0))*8 reserved,a1.data*8 data,
(CASE WHEN (a1.used+ISNULL(a4.used,0))>a1.data THEN(a1.used+ISNULL(a4.used,0))-a1.data ELSE 0 END)*8 index_size,
(CASE WHEN (a1.reserved+ISNULL(a4.reserved,0))>a1.used THEN(a1.reserved+ISNULL(a4.reserved,0))-a1.used ELSE 0 END)*8 unused
FROM(SELECT ps.object_id,SUM(CASE WHEN(ps.index_id < 2)THEN row_count ELSE 0 END)[rows],
		SUM(ps.reserved_page_count)reserved,
		SUM(CASE WHEN(ps.index_id<2)THEN(ps.in_row_data_page_count+ps.lob_used_page_count+ps.row_overflow_used_page_count)
				ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)END)data,
		SUM(ps.used_page_count)used
	FROM sys.dm_db_partition_stats ps
    WHERE ps.object_id NOT IN (SELECT object_id FROM sys.tables WHERE is_memory_optimized=1)
	GROUP BY ps.object_id)a1
LEFT OUTER JOIN(SELECT it.parent_id,SUM(ps.reserved_page_count)reserved,SUM(ps.used_page_count)used
	 FROM sys.dm_db_partition_stats ps INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
	 WHERE it.internal_type IN (202,204)
	 GROUP BY it.parent_id)a4 ON a4.parent_id = a1.object_id
INNER JOIN sys.all_objects a2  ON a1.object_id = a2.object_id
INNER JOIN sys.schemas a3 ON a2.schema_id = a3.schema_id
WHERE a2.type <> N'S' and a2.type <> N'IT'
ORDER BY a3.name, a2.name
для более сложных вариантов например для каждой
строки свой скрипт то через скалярную функцию
(в которой обычно процедуру не вызвать, за искл. нескольких специальных)
так что только которая CLR
8 авг 19, 04:46    [21944270]     Ответить | Цитировать Сообщить модератору
 Re: выполнить генерируемый на лету скрипт к каждой строке набора данных  [new]
vikkiv
Member

Откуда: London
Сообщений: 2508
..что в принципе упрощается в
SELECT a3.name[schemaname],a2.name[tablename],a1.rows row_count FROM
(SELECT ps.object_id,SUM(CASE WHEN(ps.index_id<2)THEN row_count ELSE 0 END)[rows]
from sys.dm_db_partition_stats ps
WHERE ps.object_id NOT IN(SELECT object_id FROM sys.tables WHERE is_memory_optimized=1)
group by ps.object_id)a1 INNER JOIN sys.all_objects a2 ON a1.object_id=a2.object_id
INNER JOIN sys.schemas a3 ON a2.schema_id=a3.schema_id
WHERE a2.type<>N'S'and a2.type<>N'IT'ORDER BY 1,2
8 авг 19, 05:03    [21944274]     Ответить | Цитировать Сообщить модератору
 Re: выполнить генерируемый на лету скрипт к каждой строке набора данных  [new]
Владислав Колосов
Member

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

Эту задачу проще и нагляднее решить курсором по списку объектов.
8 авг 19, 11:59    [21944534]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить