2013-02-14 7 views
2

데이터가있는 테이블이 있으며 열 중 하나에 텍스트로 저장된 숫자가 포함되어 있습니다. 응용 프로그램이 응용 프로그램을 업데이트하면 숫자 뒤에 _BAK + datetime 스탬프가 기록됩니다.데이터 유형 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 

(* SEL2의 선택은) 다음과 같은 테이블이 생성

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를 교체하십시오 오류가 발생한 위치를 정확하게 지적하면 CTE는 참조 될 때만 실행됩니다. –

+0

또한'sel2'가 아닌'SELECT * FROM sel3'을 쿼리에 사용하십시오. – Lamak

+0

'_BAK' 앞에있는 숫자는 항상 4 자리입니까? 왜냐하면 4 미만의 기록이 있으면 오류가 발생할 것입니다 ... –

답변

2

시도 : 여기

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

임시 테이블없이 할 수 있습니다 :'WITH * (* INTO * /)없이 SELECT */* ROW_NUMBER() SELECT는 WHERE num <> 1'에서 삭제하십시오. –

0

내가 대신 윈도우 함수의 그룹화 사용할 수 있습니다 생각입니다 :

SELECT max(id), max(sitenummer) 
FROM vdfkraan 
group by left(sitenummer,charindex('_BAK',sitenummer)); 
관련 문제