2011-11-10 3 views
1

우리의 문서 저장 응용 프로그램에는 각 클라이언트마다 거의 동일한 서로 다른 데이터베이스가 있지만 각 클라이언트마다 하나의 테이블 DocumentIndexes은 고유합니다. 임의의 개수의 열과 유형이 있습니다.문자열을 반환하는 사용자 정의 함수에서 동적 SQL 사용

전화 할 수있는 데이터베이스 (예 : MYAPP_MASTER)의 일반 기능을 만들려고하는데 데이터베이스 이름과 문서 ID 값을 전달하고 지정된 이름에서 값과 열 이름을 다시 가져옵니다. 데이터베이스의 DocumentIndexes 테이블 데이터베이스 이름을 전달해야하므로 선택 SQL을 동적으로 생성하고 sp_executesql을 호출해야합니다.

필요한 코드를 확인하기 위해 INFORMATION_SCHEMA.COLUMNS 테이블을 폴링하는 다음 코드는 저장 프로 시저에서 올바르게 작동하지만 이러한 동적 코드를 검색하는 데 필요한 모든 저장 프로 시저에서이 코드를 모두 복사해야합니다. 값. 차라리 데이터베이스에 관계없이이 열의 문자열 값을 반환하는 함수를 하나 가지고 있는데이 함수는 데이터베이스 MYAPP_MASTER에 한 번 존재합니다. 다시 말하지만,이 코드는 작동하지만 SQL은 함수에 넣을 수 없습니다. 이 주변에 어쨌든 있습니까? SAMPLE_CLIENT_DB datababase DocumentIndexes 테이블 이름, 사무실 및 분류에 대한 열이

USE MYAPP_MASTER 
GO 
DECLARE @DatabaseName varchar(255) 
DECLARE @DocumentId int 
SET @DatabaseName = 'SAMPLE_CLIENT_DB' 
SET @DocumentId = 1234 
DECLARE @DynamicIndexes nvarchar(max) 
DECLARE @DynamicIndexesParam nvarchar(max) 
DECLARE @DynamicIndexesSql nvarchar(max) 
SET @DynamicIndexesParam = '@Indexes varchar(max) OUTPUT' 
SET @DynamicIndexesSql = 'SELECT @Indexes = COALESCE(@Indexes + ''+ '''', '', '''') + CAST(COLUMN_NAME as varchar(max)) + '': '''''' + '' + CASE WHEN DI.'' + COLUMN_NAME + '' IS NOT NULL THEN CAST(DI.'' + COLUMN_NAME + '' as varchar(max)) ELSE '''''''' END '' FROM ' + @DatabaseName + '.INFORMATION_SCHEMA.COLUMNS WHERE table_name = ''DocumentIndexes'' AND COLUMN_NAME <> ''DocumentID''; ' 
EXEC sp_executesql @DynamicIndexesSql, @DynamicIndexesParam, @Indexes = @DynamicIndexes OUTPUT 
SET @DynamicIndexes = '''' + @DynamicIndexes 
DECLARE @SelectionSql nvarchar(max) 
SET @SelectionSql = 'SELECT ' + @DynamicIndexes + ' as DocumentIndexes FROM ' + @DatabaseName + '..Document D LEFT OUTER JOIN ' + @DatabaseName + '..DocumentIndexes DI ON D.DocumentId = DI.DocumentId WHERE D.DocumentID = ' + CAST(@DocumentId as varchar(10)) 
EXEC sp_executesql @SelectionSql 

경우,이 코드처럼 보이는 간단한 문자열을 반환합니다 다음은 :

Name: Foo, Office: Bar, Classification: 123 
+0

+1 우수 질문. – LarsH

답변

0

당신은 실행 명령을 실행할 수 없습니다 SQL 함수 안에 있지만 DocumentID 수준에서 DocumentIndexes 테이블이 고유하다고 가정하면 출력 변수에 저장 프로 시저를 사용할 수 있습니다.

Create Proc DocID_DocIndexes @retval Varchar(Max) Output 
As 
... 
(Your code logic minus last two lines) 
... 
-- Populate your dynamic SQL into a variable to assign it to the output variable 
SET @SelectionSql = 'SELECT @result = ' + @DynamicIndexes + ' as DocumentIndexes FROM ' + @DatabaseName + '..Document D LEFT OUTER JOIN ' + @DatabaseName + '..DocumentIndexes DI ON D.DocumentId = DI.DocumentId WHERE D.DocumentID = ' + CAST(@DocumentId as varchar(10)) 
EXEC sp_executesql @SelectionSql, N'@result Varchar(Max) Output', @result = @retval Output 
Return 
+0

입력 해 주셔서 감사합니다.하지만이 함수에서 필요로하는 이유는 다른 쿼리에서 함수를 다시 사용할 수 있기 때문입니다. 예를 들어,'SELECT *, udfGetIndexes (DocumentID)를 Indexes FROM Document'와 같이 할 수 있기를 원한다고 가정 해 봅시다. 나는 SP로 어떻게 할 수 있을지 모르겠다. 그렇지? – bigmac

+0

아마도 작동 할 수있는 유일한 방법은 (그리고 만약 내가 틀렸다면 다른 사람이 논쟁에 뛰어 들기를 바랍니다) SQL CLR 함수를 생성하고 documentID를 전달한 다음 CLR이 스토어드 프로 시저를 호출하여 varchar 결과를 다시 CLR 함수로 리턴합니다. SQL 내에서 순수하게 당신이하려는 것은 코드 재사용없이 어느 정도 가능하지 않다고 믿습니다. –

관련 문제