2011-07-29 6 views
6

는하자 우리는이 같은 쿼리를 가지고 말 : 내가 수동으로 모든 곳에서 문자열을 변경하여이 쿼리를 다른 테이블에 여러 번 실행하고테이블 이름을 문자열로 지정하는 방법이 있습니까?

SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM DB.dbo.Table 
) 
    INNER JOIN DB.dbo.Table ON ... 

.

DECLARE @tablename AS VARCHAR(255) 
SET @tablename = 'DB.dbo.Table' 

을하지만 그것은 내가 그것을 사용하기 전에 테이블 변수로 @tablename를 선언해야한다는 말을 나에게 오류가 발생으로 작동하지 않는 것 : 나는 다음과 같은 선언했습니다. 내 테이블 이름을 어떻게 형체화할 수 있습니까? 가능하다면 Intellisense는 여전히 작동합니까?

답변

7

이 같은 EXEC 문에 포장 할 수 있습니다

declare @my_tablename nvarchar(100) = 'mytable'; 
exec(' 
SELECT * FROM 
(
    SELECT * FROM 
    (
    SELECT * FROM ' + @my_tablename + ' 
) 
    INNER JOIN ' + @my_tablename + ' ON ...' 
); 

하지만, 인텔리 그 시나리오에서 작동하지 않습니다.

미리 출력이 어떻게되는지 알면 임시 테이블을 선언하여 결과를 보관할 수 있으며 EXEC 없이도 액세스 할 수 있습니다. 임시 테이블에 인텔리 센스가 있습니다. 예를 들어

는 :

--this must match whatever your SELECT is going to return 
    CREATE TABLE #results(
    FIELD1 INT 
    ,FIELD2 NVARCHAR(100) 
    ,FIELD3 BIT 
    ); 

EXEC(' 
    INSERT INTO #results(field1,field2,field3) 
    SELECT FIELD1,FIELD2,FIELD3 FROM ' + @my_tablename 
); 

select * from #results --you will have intellisense on #results 
3

당신은 동적 SQL을 사용합니다. 왜 많은 중첩 된 SELECT가 필요한지 잘 모르겠지만 다음과 같은 내용이 될 것입니다.

SQL 삽입에주의하십시오. IntelliSense에는 개체 이름에 대한 문자열을 구문 분석 할 수있는 기능이 없습니다 (또는 개체 이름을 편집하는 동안 알 수 있습니다).

+0

+1. 의존성 주입에 대해 언급 해 주셔서 감사합니다. –

4

아니요. C# 프로그램에서 함수 이름을 문자열로 지정할 수 없듯이. T-SQL 컴파일은 정확한 액세스 계획, 즉 열어서 쿼리를 만족시키는 데 사용할 인덱스를 제공해야합니다. C#에서는 메서드로 '문자열'을 호출하는 코드를 생성 할 수 없듯이 '문자열'에 대한 계획을 세우는 것은 불가능합니다.

declare @sql NVARCHAR(MAX) = N'SELECT ... FROM ' + 
    quotename(@dbname) + N'.' + quotename(@schema) + N'.' + quotename(@table) + 
    N' WHERE ...'; 
exec sp_executesql @sql; 

그냥 ... C#에서 동적 런타임 호출을 할 반사를 사용 하듯이 :

이 솔루션은 동적 SQL이다.

자세한 내용은 The Curse and Blessings of Dynamic SQL을 참조하십시오.

추신. @tablename을 구성 요소로 나누고 QUOTENAME을 사용하는 것이 절대적으로 필요하며 agaisnt SQL Injection을 보호합니다. 분할을 수행하려면 PARSENAME을 사용하십시오.

+0

+1 링크는 항상 동적 SQL을 다룰 때 가장 먼저 움직입니다. – Lamak

관련 문제