Я пересмотрел некоторые таблицы SP с временной таблицей, чтобы исключить дозировки declare @vars
в каждом SP.Работая по отдельности, они, кажется, отлично работают, пока я не написал сценарий тестового примера, циклически повторяя текущие записи в производственной системе, чтобы протестировать эти невыпущенные новые sps (ATM, я не могу придумать более эффективных способов просмотра циклов через наборы параметров, чтобы проверить ихбез курсора. Пожалуйста, постарайтесь не фокусироваться на использовании курсора здесь).Я получил другой результат во время повторного exec
.Например,
-- sub_sp2:
-- sub_task2
select top 1 col1, col2, .... col30
into #temp_sub_sp2
from tb1
left join tbl_ext1
left join tbl_ext2
left join tbl_ext3
left join tbl_ext....
where cond1 = true
if @@row_count < 0
print cond1=true do A thing
else
print cond1=false do B thing
-- sp1:
-- this is a master sp with a couple of sub tasks written in sub_sps.
exec sub_sp2 param1,...., @task2_result output
exec sub_sp3 param1,...., @task3_result output
exec sub_sp4 param1,...., @task4_result output
-- do sth with @result1
-- test script:
-- a test script to call sp1 repeatedly with
-- different parameters from production system to check result.
declare cur1 ...
for select colx from prd_mach_status
open cur1
fetch next from cur1 into @param1
...
while ...
exec sp1 @param1
Результат похож на
| param1 | print |
| value1 | cond1 = 1 do A |
| value1 | cond1 = 0 do B |
| value2 | cond1 = 0 do B |
| value1 | cond1 = 0 do B |
Живые данные варьируются, но всегда следуют одному и тому же шаблону.После того, как 1-й cond1 верен, следующий exec все приведет к cond1 = 0. Даже если cond1 истинен.
Очевидно, что select into
не удалось после первого успешного select into
.и временная таблица не освобождается после SP2 или SP1 завершен.
Здесь локальный #temp_sp2
создается внутри области sp2, а не из внешней области, как только вызов возвращается, область создания больше не действительна, но таблица не освобождается.Такое ощущение, что последний вызов того же sp разделяет ту же область действия с предыдущими вызовами.
Я уже знаю следующее:
- Временные таблицы - это просто псевдонимные таблицы с причудливыми именами вTempdb.
- Концепция областей действия определяет их видимость
- Сессии - это области верхнего уровня, разделенные на соединение.
Мой вопрос об их продолжительности жизни.Обычно, как только объект создается, он связывается с локальной областью функций, когда область исчезает, объект GCed.Локальная временная таблица, созданная здесь во вложенном sp, явно не следовала этому.
В чем здесь подвох, как его следует использовать, когда обычное понимание области действия здесь не применимо (например, python).
Ответ от Scope of temporary tables in SQL Server
фактически противоречит этому.
Кроме того, нет необходимости DROP TABLE в конце вашей процедуры (снова по той же ссылке):
Локальная временная таблица, созданная в хранимой процедуре,автоматически отбрасывается по завершении хранимой процедурыреальная таблица) имеет область видимости / создания, но не уничтожается автоматически до завершения сеанса.Это объясняет некоторые вещи, но противоречит предыдущим утверждениям из ответа на предложенный вопрос.
Область и срок службы на самом деле не применяются.SQL не C #.#somename - это реальная таблица, которая создается при выполнении оператора create table и существует до тех пор, пока открыт сеанс / соединение.
Теперь я в замешательстве ...