2013-02-14 5 views
2

У меня есть таблица с данными, и один из столбцов содержит число, хранящееся в виде текста. Когда приложение обновляет его, оно записывает _BAK + дата-время за номером.Ошибка преобразования типа данных varchar в bigint

Теперь я пытаюсь очистить базу данных, удалив все записи, содержащие _BAK в столбце номера, где последний не должен быть удален.

id  sitenummer     
28376 1441_BAK20130213151952032  
28377 1441_BAK20130214142314705  

В этом случае линия с ID 28376 является самой старой и ее необходимо удалить.

Я создал запрос, который должен сделать только что:

;with sel1 AS (
select t1.ID,t1.sitenummer, CONVERT(BIGint,SUBSTRING(t1.sitenummer,CHARINDEX('_',t1.sitenummer,0)+4,50)) as Stamp1  
from vdfkraan as t1 
where t1.sitenummer like '%_BAK%' and (SELECT COUNT(SUBSTRING(t2.sitenummer,0,CHARINDEX('_',t2.sitenummer,0))) FROM vdfkraan as t2 
             where SUBSTRING(t1.sitenummer,0,CHARINDEX('_',t1.sitenummer,0))=SUBSTRING(t2.sitenummer,0,CHARINDEX('_',t2.sitenummer,0))) > 1 
group by t1.id,t1.sitenummer) 

, sel2 AS (
select t3.id, t3.sitenummer, t3.stamp1, 
     (select TOP(1) t4.stamp1 from sel1 as t4 
     WHERE SUBSTRING(t4.sitenummer,0,CHARINDEX('_',t4.sitenummer,0)) =SUBSTRING(t3.sitenummer,0,CHARINDEX('_',t3.sitenummer,0)) 
     order by t3.Stamp1 DESC) AS stamp2 from sel1 as t3) 

, sel3 AS (select id from sel2 where Stamp1=stamp2) 

--delete FROM vdfkraan 
--where id IN (SELECT t1.id FROM sel3 as t1) 

--select * from sel2 

Если я раскомментировать последнюю строку (выберите * из ВЫБ2), он производит следующую таблицу:

id  sitenummer     stamp1    stamp2 
28376 1441_BAK20130213151952032 20130213151952032 20130213151952032 
28377 1441_BAK20130214142314705 20130214142314705 20130213151952032 

Таблица sel3 содержит одну запись с одной колонкой id = 28376.

Так что, похоже, работает так, как я хочу.

Теперь я прокомментирую строку выбора и раскомментирую строки «Удалить».

Теперь я получаю следующее сообщение об ошибке:

Msg 8114, Level 16, State 5, Line 2
Error converting data type varchar to bigint.

Так без удаления строк, все не в порядке, никаких ошибок, но с ним, я получаю эту ошибку. Я проверил данные, не должно быть никаких проблем.

Что здесь происходит?

+0

Попробуйте заменить КТР с температурными таблиц точно указать место, где происходит ошибка, CTE выполняются только при ссылке. –

+0

Кроме того, вы должны делать 'SELECT * FROM sel3' в своем запросе, чтобы увидеть результаты, а не' sel2' – Lamak

+0

Вы уверены, что число перед '_BAK' всегда имеет 4 цифры? Потому что если есть записи, где у него меньше 4, будет ошибка ... –

ответ

2

Try с этим:

SELECT v.ID 
     , v.sitenummer 
     , ROW_NUMBER() OVER (PARTITION BY LEFT(v.sitenummer, PATINDEX('%_BAK%', v.sitenummer) - 1) ORDER BY v.id DESC) num 
INTO #temp 
FROM vdfkraan v 
WHERE PATINDEX('%_BAK%', v.sitenummer) > 0 

DELETE vdfkraan 
FROM #temp t 
JOIN vdfkraan v ON v.id = t.id 
AND  t.num <> 1 

SELECT * 
FROM vdfkraan 

Вот SQL Fiddle

+0

Спасибо, что работает еще лучше. – Eric

+0

Добро пожаловать, я рад, что это помогло. –

+0

Вы можете обойтись без временной таблицы: 'С рангом AS (/ * ваш ROW_NUMBER() SELECT без INTO * /) УДАЛИТЬ ОТ ранжированного WHERE num <> 1'. –

0

Я думаю, что вы можете использовать группировку вместо окна функции:

SELECT max(id), max(sitenummer) 
FROM vdfkraan 
group by left(sitenummer,charindex('_BAK',sitenummer)); 
Смежные вопросы