powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
8 сообщений из 8, страница 1 из 1
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32021966
_svr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Три таблички, я их чищу следующим пакетом:

begin tran
truncate table dbo.yyy
truncate table dbo.zzz
truncate table dbo.xxx
go
if @@error!=0
begin
rollback tran
return
end
.
.
.
commit tran


(этот пакет я отлаживаю в QA для будущей процедуры, там еще много чего - пометил ".", но очистка стоит в самом начале)

Выдает ошибку:
Server: Msg 4712, Level 16, State 1, Line 1
Cannot truncate table 'dbo.xxx' because it is being referenced by a FOREIGN KEY constraint.

Таблица xxx - главная (сторона "один"), один кластерный индекс, являющийся первичным ключом.
Таблицы yyy и zzz - на стороне "ко многим" (там по нескольку индексов, в т.ч. и по внешним ключам)
На диаграмме проведены связи, в свойствах связей уже все флажки (на вкладке "Relationships") нафиг снял...

Еще одна непонятка, после этого сообщения вылезает (если убрать "go", этого сообщения нет):
Server: Msg 3903, Level 16, State 1, Line 3
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.

Подскажите, что почем - совсем запутался...
...
Рейтинг: 0 / 0
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32021970
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1.
BOL
" You cannot use TRUNCATE TABLE on a table referenced by a FOREIGN KEY constraint ; instead, use DELETE statement without a WHERE clause. Because TRUNCATE TABLE is not logged, it cannot activate a trigger.

TRUNCATE TABLE may not be used on tables participating in an indexed view."

>На диаграмме проведены связи, в свойствах связей уже все флажки (на вкладке "Relationships") нафиг снял...
Для того, чтобы можно было использовать TRUNCATE TABLE нужно удалить PK-FK consytraint, а не просто "снять флажки".


2. В T-SQL выполнение происходит отдельными пакетами(batch).
Каждый пакет выполняется отдельно и в общем не зависит от других пакетов.
GO является признаком окончания пакета.

Поэтому ваш ROLLBACK TRANSACTION ищет соответсвующий ему BEGIN TRANSACTION в своем пакете, а не в соседних.
...
Рейтинг: 0 / 0
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32021979
_svr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Эх, ну почему мне так стыдно, когда Glory отвечает?

Если серьезно, огромное спасибо за терпение.
Рискну еще раз его испытать

--------------------------------------------------------------------------------------
Все понял, truncate table я уже заменил на delete...
После чистки у меня идет вагон запросов на добавление - из таблиц LinkedServer'a (.dbf) переливается в серверные таблицы, местами уродуясь до неузнаваемости
Абсолютно все запросы я отлаживал по отдельности - работают.
Как только пускаю в пакете, унутри транзакции, на первом же запросе говорит
Server: Msg 8501, Level 16, State 3, Line 11
MSDTC on server 'MyServer' is unavailable.
Когда убираю транзакцию - работает. Получается, обращение ко внешним источникам данных внутри транзакции использовать нельзя?
--------------------------------------------------------------------------------------
Еще:
Когда должна вставляться эта конструкция
if @@error!=0
begin
rollback tran
return
end
- после каждого запроса на обновление, или можно непосредственно перед commit tran?
--------------------------------------------------------------------------------------
Ну и напоследок:
Так уж вышло, что я почти никогда не пользовался автоматическими средствами поддержания целостности (каскадные удаления/обновления, и пр.), а в схеме данных провел связи для удобства ее анализа (я соврал - таблиц на самом деле немного больше, чем 3 )
Дык вот: какой прок от PK-FK constraint, если я "снимаю все флажки
" ?
Это требуется при реализации собственных правил поддержки ссылочной целостности на триггерах?
--------------------------------------------------------------------------------------
ЗЫ 2Glory: мне правда неловко - если я опять задаю вопросы из серии RTFM, Вы так и скажите (ну можно еще топик из OB подсказать
). А то я думаю, Ваше время ой какое дорогое...
...
Рейтинг: 0 / 0
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32021992
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>Эх, ну почему мне так стыдно, когда Glory отвечает?
По крайней мере можно надеется, что вы запомните ответы надолго(скажем как таблицу умножения).
-------------------------------------------
>MSDTC on server 'MyServer' is unavailable.
А запущена ли у вас служба MS DTC(Microsoft Distributed Transaction Coordinator) на вашем SQL сервере MyServer ?

>Когда убираю транзакцию - работает. Получается, обращение ко внешним источникам данных внутри транзакции
>использовать нельзя?
Не то что нельзя, просто испльзовании linked server-а ролучается распределенная транзакция(distributed transaction) и многое зависит от провайдера linked server, как он умеет/не умеет работать с транзакциями в понятиях SQL сервера.
Я бы лично закачивал данные из dbf файлов(как впрчем и из других источников) во временные таблицы _до начала всех рассчетов_. IMHO вот у Helen(топик про File in use) ошибки получаются именно из-за непосредственного участия в транзакциях "неродных" для SQL данных.

-------------------------------------------------

Вообще-то @@ERROR содержит код ошибки _последней выполненной команды T-SQL_. Поэтому если уж вы взялись сами проверять ход выполнения, то можно решать эту задачу несколькими способами
- "установка" специальной переменной
DECLARE @errors bit
SET @errors = 0
BEGIN TRANSACTION
delete table dbo.yyy
if @@error <> 0 SET @errors = 1

update ....
if @@error <> 0 SET @errors = 1


if @errors = 0 COMMIT TRANSACTION
ELSE ROLLBACK TRANSACTION

- переход на метку

BEGIN TRANSACTION
delete table dbo.yyy
if @@error <> 0 GOTO all_bad

update ....
if @@error <> 0 GOTO all_bad

COMMIT TRANSACTION
goto all_ok

all_bad:
ROLLBACK TRANSACTION

all_ok:
RETURN

-------------------------------------------------

Автоматические каскадные операции появились лишь в SQL2000. В предыдущих версиях приходилось выбирать: либо FK-PK constraint-ы либо реализация ссылочной целостности через триггеры.
С одной стороны автоматические каскадные операции(если установлены) снимают с вас обязанность написания соответсвующих триггеров, что вроде бы уменьшает объем работы.
С другой стороны позволяют пользователю легким движением руки обеспечить вас этой самой работой по самое нехочу.
К тому же каскадные операции в SQL2000 сами тоже далеки от совершенства и не поддерживают рекурсию, т.е. иерахические операции удаления/обновления с их помощью реализовать не получиться.
Совсем недавно была в форуме кажется дискуссия по этому поводу, где Глеб Уфимцев и другие высказали ряд мыслей по этому поводу.
Т.е. использовать или не использовать автоматические каскадные операции придется решать вам.

>Дык вот: какой прок от PK-FK constraint, если я "снимаю все флажки " ?
Constraint, т.е. ограничение целосности-то все равно остается. Вы не сможете добавить в дочернюю таблицу запись с кодом, которого нет в родительской базе. Не сможете удалить запись родительской базы, у которой есть соответсвующие записи в дочерней базе и т.д.

>Это требуется при реализации собственных правил поддержки ссылочной целостности на триггерах?
Если отказаться вообще от PK-FK constraint, то в самую точку
...
Рейтинг: 0 / 0
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32022023
_svr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо огромное за разъяснения. Два вопросика на последок:
1. По поводу отката транзакции. Вы выразились по поводу моего предыдущего вопроса так:
...если уж вы взялись сами проверять ход выполнения...
Если у меня между begin tran и commit tran находится несколько команд TSQL, и отсутствует явно команда rollback tran, то произойдет ли откат транзакции при любой ошибке в процессе выполнения блока команд внутри begin tran и commit tran?
Я считал, что да, а непонятки появились при разборе примера из книги (экзамен экстерном по семерке), где в простенькой транзакции из двух команд после каждой был вставлен блок
if @@error!=0
begin
rollback tran
return
end
(это меня и сбило с толку - зачем эта проверка, если транзакция и так откатится? или... нет?)

2.Самое неприятное

Отладил я наконец мой многострадальный пакет (в QA) - все работает... (MS DTC действительно не был запущен, сейчас работает )
Начинаю ее переносить в хранимую процедуру - не проходит проверка синтаксиса, ошибка 7392 Could not start a transaction for OLE DB provider 'Microsoft.Jet.OLEDB.4.0'
Честно попытался применить описание ошибки, вычитанное в OB, но так ничего и не понял (транзакция у меня одна, сессия - тоже), SET XACT_ABORT ON делал, не помогло...
пробовал вставлять begin distributed tran вместо begin tran - те же яйца....
Пока попробую применить Ваш совет насчет временных таблиц, но что-то мне подсказывает, что не поможет (разве есть разница в этом случае, в какую таблицу делать добавление из внешнего источника - во временную, или нет?). Хотя... если копировать один в один, без сложных выборок...

Вообще-то, я считал, что любой batch, работающий в QA, должен работать и внутри SP... Выходит, не так?
...
Рейтинг: 0 / 0
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32022025
_svr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дополнение: щас засунул этот скрипт в Job из двух шагов
1. запуск батника для копирования .dbf'ов на локальный винт и снятия у них флага наличия индекса (иначе провайдер не берет)
2. скрипт
Все работает... Странно... Почему в SP-то нельзя?
...
Рейтинг: 0 / 0
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32022056
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1.откат транзакции при любой ошибке в процессе выполнения блока команд внутри begin tran и commit tran?
Ошибки бывают разные. Одно дело ошибки, вызванные, например, обрывом конекта между сервером и клиентом. Другое дело, так называемые ошибки выполнения или run-time errors. В первом случае действительно произойдет автоматический откат. А вот реакцией сервера во втором случае управляет SET XACT_ABORT. Если установлено SET XACT_ABORT OFF, то внутри транзакции придется проверять код ошибки после каждой команды.

BOL - Accessing and Changing Relational Data - Transactions - Controlling Transactions
и вообще можно прочитать всю главу BOL - Accessing and Changing Relational Data - Transactions и "попрыгать" по ссылкам из ее статей

!NB! Помните, что речь идет об откате транзакции, а не о прерывании выполнения текущего пакета.

2.Начинаю ее переносить в хранимую процедуру - не проходит проверка синтаксиса, ошибка 7392 ...
Почему в SP-то нельзя?

Создаете процедуру с помощью Enterprise Manager ?
Попробуйте создать вашу процедуру из QA через команду CREATE PROCEDURE. Если и там будет выскакивать ошибка, то попробуйте так
SET ANSI_WARNINGS ON
GO
SET ANSI_NULLS ON
GO
CREATE PROCEDURE ....
GO


(разве есть разница в этом случае, в какую таблицу делать добавление из внешнего источника - во временную, или нет?
Я имел ввиду то, что нормальная транзакция лучше распределенной. Т.е. внутри транзакции лучше избавиться запросов к linked server-у, закачав все данные в таблицы до начала транзакции. А временные таблицы IMHO лучше тем, что
- таблицы с одинаковыми именами можно свободно использовать в разных коннектах
- они автоматически удалются по завершении пакета/закрытии коннекта
Можно конечно использовать и постоянную таблицу.

Вообще-то, я считал, что любой batch, работающий в QA, должен работать и внутри SP... Выходит, не так?
нет, все так. Batch может быть преобразован в процедуру, дело просто в некоторых особенностях создания процедур, использующих запросы к linked server-у. В QA в отличии от EM можно с помощью команд сделать соответствующие установки.
Прочитайте в BOL - Transact-SQL Reference - CREATE PROCEDURE в части Remarks про то, какие установки используются и сохраняются при создании процедур.
...
Рейтинг: 0 / 0
truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
    #32022062
_svr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо огромное!
Ламерские вопросы на сегодня закончились...

Читаю BOL...
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / truncate table не чистит, а delete удаляет (подробно - унутри). Почему?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]