|
Заставить 1С каждый раз создавать новую временную таблицу в СУБД по одному набору колонок | ☑ | ||
---|---|---|---|---|
0
TormozIT
гуру
22.05.23
✎
08:50
|
Нужна идея. Как заставить 1С каждый раз создавать новую временную таблицу в СУБД по одному набору колонок даже в рамках одного соединения?
Пример Первое выполнение Выбрать 2 поместить аа в СУБД делает CREATE TABLE #tt4 (_Q_000_F_000 NUMERIC(1, 0)) А второе выполнение Выбрать 2 поместить аа в рамках того же соединения СУБД делает ничего (переиспользует #tt4). А надо чтобы опять выполнился запрос. |
|||
1
НафНаф
22.05.23
✎
08:52
|
(0) удалять перед повторным использованием
|
|||
2
TormozIT
гуру
22.05.23
✎
08:54
|
(1) Удаление временной таблицы в СУБД не выполнится. Она останется.
|
|||
3
НафНаф
22.05.23
✎
08:59
|
(2) тогда огласите всю задачу
если я напишу "Выбрать 42 поместить аа" там же теперь 42? |
|||
4
TormozIT
гуру
22.05.23
✎
09:01
|
(3) Речь не про строки таблицы, а про саму временную таблицу в СУБД. Ее содержимое конечно будет обновляться. Но сама она не удаляется, а переиспользуется. Это описано в документации.
|
|||
5
trad
22.05.23
✎
09:02
|
Выбрать 2 аа, 1 _guid
|
|||
6
katamoto
22.05.23
✎
09:04
|
(4) А зачем нужно, что бы именно удалялась?
|
|||
7
Asmody
22.05.23
✎
09:07
|
(0) сделай лишнюю колонку со случайным именем
|
|||
8
TormozIT
гуру
22.05.23
✎
09:15
|
(7) Не поможет. Играет роль только порядок и типы колонок.
|
|||
9
TormozIT
гуру
22.05.23
✎
09:16
|
Перефразирую (0) - хочу гарантировано увидеть в трассе СУБД запрос создания временной таблицы при выполнении своего запроса 1С
|
|||
10
Chai Nic
22.05.23
✎
09:21
|
(9) Временные таблицы удаляются при удалении менеджера временных таблиц. А его удаление зависит от области действия его переменной. То есть, нужно создавать запрос с явным или неявным МВТ в какой-то функции или процедуре.
|
|||
11
TormozIT
гуру
22.05.23
✎
09:24
|
(10) На уровне 1С да. Но на уровне СУБД не так. Там кэшируются (пустые) временные таблицы и потому после их удаления на уровне 1С - в СУБД они остаются но пустыми.
|
|||
12
TormozIT
гуру
22.05.23
✎
09:26
|
Пока единственный рабочий вариант - перебор длины фиктивной текстовой колонки.
Выбрать 2, ВЫРАЗИТЬ("" КАК СТРОКА(#123#)) поместить аа На 100-й раз уже придется выполнить 100 лишних запросов. |
|||
13
Chai Nic
22.05.23
✎
09:36
|
(11) То есть 1с не дает команду DROP TABLE для временных таблиц?
|
|||
14
TormozIT
гуру
22.05.23
✎
09:36
|
(13) УНИЧТОЖИТЬ (как и уничтожение менеджера временных таблиц) удаляет СТРОКИ таблицы в СУБД, а не саму таблицу. Т.е. выполняет TRUNCATE TABLE вместо DROP TABLE
|
|||
15
Valdis2007
22.05.23
✎
09:37
|
пишешь хранимую процедуру, которая дропает твою таблицу, запускаешь ее из 1с через скриптик
|
|||
16
TormozIT
гуру
22.05.23
✎
09:38
|
(15) Как удалить временную таблицу в чужом соединении СУБД? Вроде так нельзя.
|
|||
17
Chai Nic
22.05.23
✎
09:59
|
(14) А чем это поведение объясняется, интересно? Оптимизация? Так было всегда или с какого-то релиза платформы?
|
|||
18
katamoto
22.05.23
✎
10:04
|
(13) DROP TABLE на самом деле не удаляет временные таблицы в SQL Server, они всё равно кэшируются, чтоб не пересоздавать постоянно объекты.
|
|||
19
TormozIT
гуру
22.05.23
✎
10:05
|
(18) Ты уже про внутренний уровень СУБД. Он в рамках рассматриваемой задачи не интересен.
|
|||
20
TormozIT
гуру
22.05.23
✎
10:06
|
(17) Такое кэшироование временных таблиц в СУБД вроде бы с 8.3 началось. Сделано в частности для повышения вероятности переиспользования планов запросов.
|
|||
21
katamoto
22.05.23
✎
10:26
|
По идее, создание индекса на временной таблице должно приводить к построению новой таблицы, вместо использования закэшированной.
|
|||
22
НафНаф
22.05.23
✎
10:34
|
(8) ну значит последовательно увеличивай длину строкового поля (изменение типа) пока возможно, потом сбрасывай до 1 и т.д.
|
|||
23
TormozIT
гуру
22.05.23
✎
10:42
|
(21) Если индекс имеет ту же структуру, то он не пересоздается.
|
|||
24
TormozIT
гуру
22.05.23
✎
11:55
|
Попробую с другой стороны зайти к задаче. Есть ли простой способ в MSSQL программно создать скрипт создания временной таблицы на основе имеющейся временной таблицы?
|
|||
25
JanK
22.05.23
✎
12:52
|
||||
26
Chai Nic
22.05.23
✎
12:52
|
(24) ВЫБРАТЬ * ПОМЕСТИТЬ Новая_ВТ ИЗ Старая_ВТ
А "в MSSQL" это " уже про внутренний уровень СУБД. Он в рамках рассматриваемой задачи не интересен." |
|||
27
TormozIT
гуру
22.05.23
✎
19:58
|
(25) Спасибо. После небольшого допила получился скрипт для создания скрипта создания временной таблицы на основе глобального имени существующей временной таблицы.
Проверено на MSSQL 2016 use tempdb; DECLARE @table_name SYSNAME DECLARE @table_nameLocal SYSNAME SELECT @table_name = '%ГлобальноеИмяВременнойТаблицы%' SELECT @table_nameLocal = '%ИмяНовойВременнойТаблицы%' DECLARE @object_name SYSNAME , @object_id INT SELECT @object_name = s.name , @object_id = s.[object_id] from tempdb.sys.tables as s WHERE s.name = @table_name DECLARE @SQL NVARCHAR(MAX) = '' ; SELECT @SQL ='CREATE TABLE ' + @table_nameLocal + CHAR(13) + '(' + CHAR(13) + STUFF(( SELECT CHAR(9) + ', [' + c.name + '] ' + CASE WHEN c.is_computed = 1 THEN 'AS ' + cc.[definition] ELSE UPPER(tp.name) + CASE WHEN tp.name IN ('varchar', 'char', 'varbinary', 'binary', 'text') THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(5)) END + ')' WHEN tp.name IN ('nvarchar', 'nchar', 'ntext') THEN '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(5)) END + ')' WHEN tp.name IN ('datetime2', 'time2', 'datetimeoffset') THEN '(' + CAST(c.scale AS VARCHAR(5)) + ')' WHEN tp.name = 'decimal' THEN '(' + CAST(c.[precision] AS VARCHAR(5)) + ',' + CAST(c.scale AS VARCHAR(5)) + ')' ELSE '' END + CASE WHEN c.collation_name IS NOT NULL THEN ' COLLATE ' + c.collation_name ELSE '' END + CASE WHEN c.is_nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END + CASE WHEN dc.[definition] IS NOT NULL THEN ' DEFAULT' + dc.[definition] ELSE '' END + CASE WHEN ic.is_identity = 1 THEN ' IDENTITY(' + CAST(ISNULL(ic.seed_value, '0') AS CHAR(1)) + ',' + CAST(ISNULL(ic.increment_value, '1') AS CHAR(1)) + ')' ELSE '' END END + CHAR(13) FROM sys.columns c WITH (NOWAIT) JOIN sys.types tp WITH (NOWAIT) ON c.user_type_id = tp.user_type_id LEFT JOIN sys.computed_columns cc WITH (NOWAIT) ON c.[object_id] = cc.[object_id] AND c.column_id = cc.column_id LEFT JOIN sys.default_constraints dc WITH (NOWAIT) ON c.default_object_id != 0 AND c.[object_id] = dc.parent_object_id AND c.column_id = dc.parent_column_id LEFT JOIN sys.identity_columns ic WITH (NOWAIT) ON c.is_identity = 1 AND c.[object_id] = ic.[object_id] AND c.column_id = ic.column_id WHERE c.[object_id] = @object_id ORDER BY c.column_id FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, CHAR(9) + ' ') + ')' + CHAR(13) PRINT @SQL |
|||
28
TormozIT
гуру
22.05.23
✎
20:00
|
Ну а поиск глобального имени нужной временной таблицы делаю программно по точному совпадению набора колонок на базе такого запроса
"SELECT | c.name AS ИмяКолонки, | c.column_id AS НомерКолонки, | c.system_type_id AS НомерТипа, | tb.name AS ИмяТаблицы |FROM | tempdb.sys.columns AS c | INNER JOIN tempdb.sys.tables AS tb | ON tb.object_id = c.object_id |WHERE tb.name like '" + ИмяОригинальнойВТ + "_%' |ORDER BY НомерКолонки |"; |
|||
29
Смотрящий
22.05.23
✎
20:12
|
(0) Заставь ее использовать ##tt4 вместо #tt4. Насколько я помню ##tt4 как раз и будет "одноразовой" таблицей
|
|||
30
JanK
23.05.23
✎
09:17
|
(29) https://stackoverflow.com/questions/2920836/local-and-global-temporary-tables-in-sql-server
Но в общем даже без учёта неправильного синтаксиса - это совёт из разряда "станьте ёжиками". |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |