![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Почему парсер в queryAnalizer-е выдает ошибку [MSSQL]
Bless © (2004-09-29 16:02:00)There is already an object named '#t' in the database.
на нижеследующий код.
declare @x int
set @x=0
if @x>0 select * into #t from shabp
else select * into #t from pozib
Причем если убрать строчку с else, то все нормально компилируется.
Bless (2004-10-01 12:12:00) [1]sniknik © (30.09.04 17:55) [31]>
Неа.
sniknik (2004-10-01 12:12:00) [2]странно, вчера у меня получалось почемуто, сегодня тоже нет.
ну тогда создавай таблицу по другому, перечисление полей придется делать
SELECT Cast(ID as INT) AS ID, Name INTO #t FROM Table WHERE 1=0
ID понятно был автоинкрементом.
Bless (2004-10-01 11:52:00) [3]sniknik © (30.09.04 17:55) [31]>
Неа.
sniknik (2004-09-30 17:55:00) [4]SET IDENTITY_INSERT #t ON
не получается?
Bless (2004-09-30 17:32:00) [5]Еще такой вопрос.
Если делать select * into #t from t1 WHERE 1=0, а затем INSERT INTO #t, то возникает такая проблема: в t1 одно поле - автоинкрементное. И в #t - получается тоже.
Как установить IDENTITY_INSERT в ON для временной таблицы?
Bless (2004-09-30 14:45:00) [6]>с - это секунды?!
А, ну да, там же 10000. Тогда нормально.
Bless (2004-09-30 14:35:00) [7]MOA[27]>
>21 c
с - это секунды?!
А вот мой пример (в таблице t1 27448 записей):
create table #t (name varchar(200))
insert into #t select name from t1
drop table #t
go
select name into #t from t1
drop table #t
Вот, что показал профайлер (1-ая цифра - для первого батча, 2-ая - для второго):
CPU: 500 156
READS: 29832 1152
MOA (2004-09-30 13:38:00) [8]Проверил.
Таблица названий месяцев Month(ID_Month Integer,Name Char(10), Name_Rod char(10)), 12 записей.
Процедуры:
CREATE PROCEDURE up_TestProc2
AS
BEGIN
SET NOCOUNT ON
SELECT * INTO #t FROM dbo.Month
END
CREATE PROCEDURE up_TestProc3
AS
BEGIN
SET NOCOUNT ON
CREATE TABLE #t(
ID_Month Integer,
Name Char(10),
Name_Rod char(10)
)
INSERT INTO #t(
ID_Month,
Name,
Name_Rod
)
SELECT
ID_Month,
Name,
Name_Rod
FROM dbo.Month
END
CREATE PROCEDURE up_TestProc4
AS
BEGIN
SET NOCOUNT ON
DECLARE @t TABLE (
ID_Month Integer,
Name Char(10),
Name_Rod char(10)
)
INSERT INTO @t(
ID_Month,
Name,
Name_Rod
)
SELECT
ID_Month,
Name,
Name_Rod
FROM dbo.Month
END
--Запускающая процедура - подставляется название вызываемой ХП
CREATE PROCEDURE up_TestProc1
AS
BEGIN
SET NOCOUNT ON
DECLARE @I Integer
SET @I=0
WHILE @I < 10000
BEGIN
EXEC dbo.up_TestProc4
SET @I=@I+1
END
END
Результаты:
SELECT .. INTO (up_TestProc2): 21 c
CREATE TABLE (up_TestProc3): 15 c
DECLARE TABLE (up_TestProc4): 9 c
Вполне ожидаемые результаты ;)
Bless (2004-09-30 13:10:00) [9]Мдя. Действительно не работает. Непонятно только, как я проверял. Прошу прощения за дезинформацию.
Ладно. Придется сначала создавать, а потом вставлять.
>CREATE + INSERT должно быть быстрее чем INSERT INTO
Если имелось в виду "быстрее чем SELECT INTO", то у меня имеются сомнения.
Профайлер говорит, что наоборот. Или я опять что-то напутал?
MOA (2004-09-30 12:31:00) [10]Засомневался и вот сейчас специально попробовал - с exec не работает - 'Invalid object name #t'.
sniknik (2004-09-30 12:28:00) [11]> Вы ошибаетесь.
проверь вот это, на тестовой базе Northwind (или замени своими таблицами)
SET NOCOUNT ON
IF 1=0
select * into #TempTable FROM Orders
ELSE
exec('select * into #TempTable FROM Orders')
select * from #TempTable
есть результат? (рекордсет)
Bless (2004-09-30 12:08:00) [12]sniknik [19]>
MOA [20]>
Вы ошибаетесь. Я проверял работоспособность понравившегося мне кода, прежде, чем запостить сюда: все работает.
>в таком виде решение нерабочее, там же и обьяснялось почему
Это не в этом топике. Нерабочим является вариан с sp_executesql.
А exec - это не батч и не процедура. Это команда(?) execute.
sniknik (2004-09-30 11:59:00) [13]> Проблема с решением на глобальных временных таблицах возникнет сразу, как только два юзера попытаются выполнить процедуру ;).
ну видимо поэтому и не упоминали.
по мне тоже, проше использовать разные имена и все, чем извращатся.
MOA (2004-09-30 11:37:00) [14]Проблема с решением на глобальных временных таблицах возникнет сразу, как только два юзера попытаются выполнить процедуру ;).
Стоит ли городить огород только для того, чтобы написать звёздочку? Вот так экономия времени ;).
MOA (2004-09-30 11:34:00) [15]Вариант exec('select into #TempTable') не заработает - таблицу вне батча (exec) увидеть не удастся - она будет удалена, поскольку временная ;).
CREATE + INSERT должно быть быстрее чем INSERT INTO
Офтопик: IMHO, стоит явно перечислять поля - это поможет в дальнейшем (например, когда Вы будете разбираться в коде через год). Частое добавление полей в таблицы базы чаще всего говорит скорее о неважной проработке проекта.
Удачи!
sniknik (2004-09-30 11:32:00) [16]Bless © (30.09.04 10:56) [17]
> За предложенный им вариант:
> IF ...
> select into #TempTable
> ELSE
> exec('select into #TempTable')
> Им я наверное и воспользуюсь.
в таком виде решение нерабочее, там же и обьяснялось почему, не буду повторятся. а вот пойти на шаг дальше и сделать небольшое изменение там почемуто никто не догадался (???). странно участвовали вполне знающие люди.
IF ...
select into ##TempTable
ELSE
exec('select into ##TempTable')
вот так будет работать, но наверное добавит других проблем (как там у тебя по смыслу процедуры)
stone (2004-09-30 11:09:00) [17]2 Bless ©
а ты так ничего и не понял
Про временные таблицы, видимо, тоже толком не читал. В противном случае знал бы, какие особенностипридает таблице значек #. Тогда и вопрос бы твой решился сам по себе.
ЗЫ. Желаю удачного танца по граблям...
Bless (2004-09-30 10:56:00) [18]sniknik © (29.09.04 18:15) [16]>
фокус с WHERE 1=0 я тоже знаю.
Только от перечисления всех полей в INSERT INTO это не избавит.
И при изменении структуры таблицы мне придется править процедуру.
Ну это я уже привередничаю, конечно. :)
Приз за самое красивое решение проблемы я бы отдал DArtem-у.
Из топика "Чудеса SELECT INTO" (кажется). Адрес - в [8].
За предложенный им вариант:
IF ...
select into #TempTable
ELSE
exec('select into #TempTable')
Им я наверное и воспользуюсь. (Вот только выясню, что эффективнее SELECT INTO или CREATE + INSERT INTO, а то в топиках высказывались диаметрально противоположные мнения.)
sniknik (2004-09-29 18:15:00) [19]> Просто не хотелось делать INSERT INTO
> потому что придется перечислять все поля, а их больше 30.
из ссылок
http://www.sql.ru/forum/actualthread.aspx?bid=1&tid=2698&hl=if+else+select+into+%ee%f8%e8%e1%ea%e0+There+is+already+an+object+named
пост AnKa
кстати там и решение приводится, более менее подходяшее (даже несколько если подумать, пара точно есть)
Nikolay M. (2004-09-29 18:11:00) [20]
> Просто не хотелось делать INSERT INTO
> потому что придется перечислять все поля, а их больше 30.
Хоть 100 полей. В QA поднимаешь скрипты на создание таблиц shabp и pozib, меняешь названия на #t.