Показать полную графическую версию : ошибка типа данных (tinyint и text) при записи содержимого поля в переменную
БД под SQL2000. Столкнулся с такой проблемой.
Записываю в переменные поля с различными типами данных из одной таблицы - varchar, tinyint, text
DECLARE @S1 varchar(200)
DECLARE @S2 tinyint(1)
DECLARE @S3 tinyint(1)
DECLARE @S4 text(16)
DECLARE @S5 varchar(300)
DECLARE @S6 tinyint(1)
SELECT @S1 = NAME1
FROM LUT.dbo.NAME
WHERE nID = 10
SELECT @S2 = NAME2
FROM LUT.dbo.NAME
WHERE nID = 27
и т.д.
С типом varchar всё нормально, а tinyint и text не проходят.
При выполнении скрипта в EM получаю:
Server: Msg 2716, Level 16, State 1, Line 1
Column or parameter #-2: Cannot specify a column width on data type tinyint.
Server: Msg 2716, Level 16, State 1, Line 1
Column or parameter #-3: Cannot specify a column width on data type tinyint.
Server: Msg 2716, Level 16, State 1, Line 1
Column or parameter #-4: Cannot specify a column width on data type text.
Server: Msg 2716, Level 16, State 1, Line 1
Column or parameter #-6: Cannot specify a column width on data type tinyint.
Parameter '@S2' has an invalid data type.
Parameter '@S3' has an invalid data type.
Parameter '@S4' has an invalid data type.
Parameter '@S6' has an invalid data type.
Типы данных взяты из EM (таблица->свойства) и соответствуют тому что задал разработчик. Если в EM запустить парсер, то он выдаёт что команда комплит саксесфул.
В чём может быть проблема?
для text и tinyint размерность не указывают
Спасибо. В понедельник попробую применить.
В целом не получается. Т.е. действительно если не указывать размерность, то эта ошибка убирается. Но только для того что бы уступить место уведомлению, что ПОЛЯ С ТАКИМ ТИПОМ ДАННЫХ В ПЕРЕМЕННУЮ ЗАПИСАТЬ НЕЛЬЗЯ.
Отсюда вопрос, а как тогда можно скопировать ячейку из одной таблицы в ячейку другой? Т.е. строка уже там существует и надо просто заменить содержимое ячейки. UPDATE не работает с именами ячеек, только '...' | DEFAULT | NULL. INSERT создаёт новую строчку. Подскажите решение.
Delirium
17-10-2008, 08:44
UPDATE не работает с именами ячеек, только '...' | DEFAULT | NULL. INSERT создаёт новую строчку. Подскажите решение. »
в смысле не работает с именами ячеек? Непонятно :)
Желателен полный текст скрипта и пример данных и желаемый результат, тогда видно будет, что делать.
update table set @s2 = 'number' where s2=NUM ?
Есть две таблицы, например – Table1 и Table2.
Table1
nID NAME1 NAME2 NAME3 NAME4 NAME5 NAME6
1
2
3
Из Table1 надо скопировать поля в table2. Все поля принадлежат одной строке (н-р nID=2). Условие – передавать поля NAME1 и NAME5 через переменные, остальные как угодно, можно также через переменные. Обратиться к строчке могу только по ID (WHERE nID = 2), значение полей неизвестно.
Table2
nID NAME1 NAME2 NAME3 NAME4 NAME5 NAME6
1
2
3
4
5
6
DECLARE @S1 varchar(200)
DECLARE @S2 tinyint
DECLARE @S3 tinyint
DECLARE @S4 text
DECLARE @S5 varchar(300)
DECLARE @S6 tinyint
SELECT @S1 = NAME1
FROM Table1
WHERE nID = 2
SELECT @S2 = NAME2
FROM Table2
WHERE nID = 2
и т.д.
INSERT INTO Table2
(NAME1, NAME2, NAME3, NAME4, NAME5, NAME6)
VALUES (@S1, @S2, @S3, @S4, @S5, @S6)
Не проходит. Натыкаюсь на:
Server: Msg 2739, Level 16, State 1, Line 1
The text, ntext, and image data types are invalid for local variables.
Хорошо. Тогда делаю через переменные только NAME1 и NAME5. Получилось. В Table2 появилась строка nID=7, в которой 2 поля заполнены нужными значениями из Table1. Теперь в эту же строчку (которая nID=7) надо передать оставшиеся значения полей из Table1 nID=2. Как это сделать?
Как это сделать? »прочитать любую книжку про t-sql. Полностью!
insert table2
select nID, NAME1, NAME2, NAME3, NAME4, NAME5, NAME6
from table1
where nID=2
Слушайте, читайте внимательней. УСЛОВИЕ КОПИРОВАНИЯ СЛЕДУЮЩЕЕ - передавать поля NAME1 и NAME5 через переменные, остальные как угодно, можно также через переменные » (сам себя цитирую :) ) Два поля через переменные! Если бы мне просто надо было скопировать строчку, то никаких проблем бы это не вызвало! И этой темы бы здесь не было!
Delirium
20-10-2008, 02:46
Vi-P, у меня такое предложение:
Т.к. все делается в одной транзакции, то можно сделать так:
Открыть транзакцию, написать
INSERT INTO Table2
(NAME1, NAME2, NAME3, NAME4, NAME5, NAME6)
VALUES (@S1, @S2, @S3, @S4, @S5, @S6) »
через переменные только NAME1 и NAME5. Получилось. В Table2 появилась строка nID=7, в которой 2 поля
заполнены нужными значениями из Table1. »
В итоге у нас имеется строка с максимальным nID в Table2.
Накидал вот такой код, попробуйте немного видоизменить и применить:
DECLARE @S1 varchar(20)
DECLARE @S2 varchar(20)
DECLARE @S3 varchar(20)
DECLARE @S4 varchar(20)
DECLARE @S5 varchar(20)
DECLARE @S6 varchar(20)
delete from table2 ' удаляем все данные из второй таблицы для теста
' определяем переменные
SELECT @S1 = NAME1
FROM Table1
WHERE nID = 2
SELECT @S2 = NAME2
FROM Table1
WHERE nID = 2
SELECT @S3 = NAME3
FROM Table1
WHERE nID = 2
SELECT @S4 = NAME4
FROM Table1
WHERE nID = 2
SELECT @S5 = NAME5
FROM Table1
WHERE nID = 2
INSERT INTO Table2
(NAME1, NAME5 )
VALUES (@S1, @S5)
'делаем просмотр всех данных для просмотра
select * from table1
select * from table2
' Собственно, само обновление нужными данными
update table2 set name2=@S2, name3=@s3, name4=@s4 where table2.nid=(select max(nid) from table2)
' И просматриваем конечный результат
select * from table2
При первом просмотре в table2 видим:
4 name11 NULL NULL NULL name55
при последнем просмотре видим:
4 name11 name22 name33 name44 name55
Подойдет вам такое решение?
Хм.... НЕ ПОДОЙДЁТ!!!!!!! (т.е. конечно всё равно спасибо, но...)
У меня несколько полей, а именно NAME2 NAME3 NAME4 NAME6 с типом tinyint или text DECLARE @S1 varchar(200)
DECLARE @S2 tinyint
DECLARE @S3 tinyint
DECLARE @S4 text
DECLARE @S5 varchar(300)
DECLARE @S6 tinyint », а с такими типами данных у меня (или у всех :) ) не проходит запись в переменную Не проходит. Натыкаюсь на:
Server: Msg 2739, Level 16, State 1, Line 1
The text, ntext, and image data types are invalid for local variables. » У ВАС В ПРИМЕРЕ У ВСЕХ ПОЛЕЙ VARCHAR!!!
Delirium
21-10-2008, 01:23
блин, щас сделаю ваши типы и проверю....
а проблема то совершенно в другом!
http://www.sql-server-helper.com/error-messages/msg-2739.aspx
В этой ссылке все описано :)
Вот готовый код:
DECLARE @S1 varchar(200)
DECLARE @S2 tinyint
DECLARE @S3 tinyint
DECLARE @S4 varchar(8000)
DECLARE @S5 varchar(300)
DECLARE @S6 tinyint
delete from table2
SELECT @S1 = NAME1
FROM Table1
WHERE nID = 2
SELECT @S2 = NAME2
FROM Table1
WHERE nID = 2
SELECT @S3 = NAME3
FROM Table1
WHERE nID = 2
SELECT @S4 = CAST([NAME4] AS VARCHAR(8000))
FROM Table1
WHERE nID = 2
SELECT @S5 = NAME5
FROM Table1
WHERE nID = 2
SELECT @S6 = NAME6
FROM Table1
WHERE nID = 2
INSERT INTO Table2
(NAME1, NAME6 )
VALUES (@S1, @S6)
select * from table1
select * from table2
update table2 set name2=@S2, name3=@s3, name4=@s4, name5=@s5 where table2.nid=(select max(nid) from table2)
select * from table2
Смысл в том, что вместо TEXT при объявлении локальных переменных, необходимо использовать либо VARCHAR(8000), либо NVARCHAR(4000), а при выборке производить CAST.
Очень интересно! Спасибо.
Delirium
23-10-2008, 02:21
В моем примере необходимо помнить, что данные обновляются во второй таблице в строку с максимальным nID, и чтобы случайно не обновилась другая запись(вдруг одновременно двое нажмут), необходимо все делать в пределах одной транзакции, т.е. перед началом всего запустить транзакцию, а после всех действий подтвердить.
Всё работает, всё замечательно.
Но если VARCHAR(8000) недостаточно. Как установить больший размер переменной?
Delirium
11-12-2008, 01:14
А это в той же ссылке: A third option is to use the READTEXT, WRITETEXT and UPDATETEXT Transact-SQL statements together with the TEXTPTR function to manipulate text, ntext and image columns in a table. You can refer to Books Online regarding these Transact-SQL statements and functions for more information.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.