2010-01-14 5 views
0

간략한 히스토리 : 레거시 웹 응용 프로그램에서 레거시보고 시스템 (SQL Server Reporting Services 2000 사용)을 지원하는 저장 프로 시저를 작성하고 있습니다. 원래 구현 스타일을 유지하면서 각 보고서에는 보고서 서버에서 간단히 렌더링 할 수있는 "최종"데이터 집합을 반환하는 데 필요한 모든 쿼리를 수행하는 전용 저장 프로 시저가 데이터베이스에 있습니다.내 저장 프로 시저가 비정상적으로 실행됩니까?

이 보고서의 비즈니스 요구 사항으로 인해 반환 된 데이터 집합에는 알 수없는 열 수가 있습니다 (보고서를 실행하는 사용자에 따라 다르지만 4 ~ 30 개의 열이있을 수 있음).

저장 프로 시저 전체에서 사용자 ID를 추적하여 추가 쿼리를 수행하는 열 UserID를 유지합니다. 끝에서, 그러나, 나는 같은 것을 할 :

UPDATE #result 
SET Name = ppl.LastName + ', ' + ppl.FirstName 
FROM #result r 
LEFT JOIN Users u ON u.id = r.userID 
LEFT JOIN People ppl ON ppl.id = u.PersonID 

ALTER TABLE #result 
DROP COLUMN [UserID] 

SELECT * FROM #result r ORDER BY Name 

효과적으로 내가 일반 텍스트에 원하는 이름 형식으로 이름 varchar 열 (나는 약간의 피벗 로직을 수행하는 동안 그 이전에 NULL을 방치)을 설정합니다.

완료되면 보고서 사용자가 볼 수 없으므로 UserID 열을 삭제하려고합니다.

마지막으로 리턴 된 데이터 세트에는 사용자 이름에 대한 하나의 컬럼과 성능 합계가있는 임의의 수의 INT 컬럼이 있습니다. 이러한 이유로 SQL은 "SELECT * EXCEPT [UserID]"등을 지원하지 않기 때문에 UserID 열을 제외 할 수 없습니다. 그러나

Invalid column name 'userID'. 

:이 저장 프로 시저를 실행하면

, 내가 실행 오류 : 알려진이와

은 (어떤 스타일 포인터는 감사하지만,이 문제의 중심이되지 않음), 여기에 문제의 , 내 DROP COLUMN 문을 주석으로 처리하고 UserID를 유지하면 저장 프로 시저가 올바르게 수행됩니다.

무슨 일 이니? 명령문이 순서대로 실행되지 않고 이름 문자열을 설정하기 전에 열을 삭제하는 것처럼 보입니다.

CREATE TABLE #result ([Name] NVARCHAR(256), [UserID] INT); 

대소 문자 구분은 문제가되지 않습니다 :

[편집 1] 나는 (전체 저장 프로 시저가 대부분 관련이없는 논리의 약 200 거짓말, 그래서 내가 조각을 붙여 넣을 수 있습니다 이전에 사용자 ID를 정의 UserID 대신 userID가있는 곳이 하나 있었는데, 이제는 문제가 해결되어 UserID에 대한 오류 메시지가 표시됩니다.

내 "깨진"저장 프로 시저도 올바르게 작동합니다. SQL Server 2008 - 이것은 2000 년 버그이거나 심각한 오류입니다. SQL Server가 어떻게 작동했는지 알 수 있습니다.

모두에게 감사드립니다!

DECLARE @workaroundTableName NVARCHAR(256), @workaroundQuery NVARCHAR(2000) 
SET @workaroundQuery = 'SELECT [Name]'; 
DECLARE cur_workaround CURSOR FOR 
SELECT COLUMN_NAME FROM [tempdb].INFORMATION_SCHEMA.Columns WHERE TABLE_NAME LIKE '#result%' AND COLUMN_NAME <> 'UserID' 
OPEN cur_workaround; 
FETCH NEXT FROM cur_workaround INTO @workaroundTableName 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @workaroundQuery = @workaroundQuery + ',[' + @workaroundTableName + ']' 
    FETCH NEXT FROM cur_workaround INTO @workaroundTableName 
END 
CLOSE cur_workaround; 
DEALLOCATE cur_workaround; 
SET @workaroundQuery = @workaroundQuery + ' FROM #result ORDER BY Name ASC' 
EXEC(@workaroundQuery); 

모두에게 감사 : 앞으로이 검색 사람들을위한

, 나는 우리가 우리의 생산 버전을 업데이트 할 때까지 2000 호환성이 매우 원유 해결 방법을 추가했습니다!

+0

전체 저장 프로 시저와 함께 사용하는 방법이 유용 할 것입니다. –

+0

불행히도이 책을 읽는 사람은 SELECT *를 사용해야합니다. 그래서 그것에 대해 조언하면 작동하지 않을 것입니다 ... – JonH

+0

임시 테이블 내부에서 사용자 ID 필드를 정의한 방법을 보여주십시오. 해당 필드가 존재하지 않는 것처럼 보입니다. – JonH

답변

1

이 나를 위해 작동합니다 : 그것은 당신을 위해 잘못된 열 말한다

CREATE TABLE #temp_t 
(
    myInt int, 
    myUser varchar(100) 
) 

INSERT INTO #temp_t(myInt, myUser) VALUES(1, 'Jon1') 
INSERT INTO #temp_t(myInt, myUser) VALUES(2, 'Jon2') 
INSERT INTO #temp_t(myInt, myUser) VALUES(3, 'Jon3') 
INSERT INTO #temp_t(myInt, myUser) VALUES(4, 'Jon4') 

ALTER TABLE #temp_t 
DROP Column myUser 

SELECT * FROM #temp_t 

DROP TABLE #temp_t 

. 맞춤법을 검사하고 임시 테이블에 해당 열이 있는지 확인 했습니까?

+0

고마워요. JonH - 저는 이것이 제가 필요로하는 핵심 지식이라고 생각합니다. SQL Server 2000 인스턴스 (프로덕션 환경)에서 구문이 실패합니다. SQL Server 2008과 비교해 보면 성공할 수 있습니다! –

+0

이 또한 SQL Server 2005에서 작동합니다. – JonH

4

훨씬 더 쉬운 해결책은 열을 삭제하지 않는 것이지만 최종 선택에서 반환하지 않는 것입니다.

어쨌든 select *을 귀하의 절차에서 돌려 보내지 말아야하는 모든 종류의 이유가 있습니다.

편집 : 알 수없는 열 개수로 인해이 방법을 사용해야합니다.

오류 메시지를 기반으로 데이터베이스의 대소 문자를 구분하므로 userIDUserID 사이에 차이가 있습니까?

+0

그냥 내가 almsot 그가 SELECT * 사용해서는 안된다는 동일한 진술을했는지 알려주려고했다. 불행히도 해결책은 약간 더러워 져야합니다 ... – JonH

0

BEGIN ... COMMIT 트랜잭션에서 DROP COLUMN 앞에 오는 모든 것을 래핑 할 수 있습니다.

0

컴파일 할 때 SQL Server는 아마도 *를 전체 열 목록으로 확장 할 것입니다. 따라서 런타임에 SQL Server는 "SELECT *"대신 "SELECT UserID, Name, LastName, FirstName, ..."을 실행합니다. 최종 SELECT를 문자열로 동적으로 어셈블 한 다음 저장 프로 시저의 끝에서 실행하면 길일 수 있습니다.

관련 문제