2013-07-26 2 views
0

변수에 있어야하는 테이블에서 select를 수행하려고합니다. 나는 응용 프로그램에서 동적으로 생성 된 테이블에 대해 작업하고 있습니다. 테이블의 이름은 CMDB_CI_XXX이며, 여기서 XXX는 다른 테이블의 값을 기반으로하는 정수 값입니다. 궁극적 인 목표는 테이블에서 CI 이름을 얻는 것입니다.TSQL : 함수의 변수에서 테이블 사용

테이블 이름을 구성하는 조각을 함수에 전달하고 함께 끈 다음 이름 값을 반환하려고 시도했지만 함수에서 EXEC 문을 사용할 수 없습니다.

: 이것은 이름 값을 얻을 수있는 기능을 사용하려는 SP의 코드가

Select [Name] from 'CMDB_CI_' + C.CI_TYPE_ID + Where CI_ID = c.CI_ID 

입니다 :

내가 다시 이름 값을 얻기 위해 실행하고자하는 것입니다
SELECT 
    CI_ID, 
    C.CI_TYPE_ID, 
    CI_CUSTOM_ID, 
    STATUS, 
    CI_TYPE_NAME, 
    --(Select [Name] from CMDB_CI_ + C.CI_TYPE_ID + Where CI_ID = c.CI_ID) 
FROM [footprints].[dbo].[CMDB50_CI_COMMON] c 
join [footprints].[dbo].[CMDB50_CI_TYPE] t 
on c.CI_TYPE_ID = t.CI_TYPE_ID 
where status <> 'retired' 
order by CI_TYPE_NAME 

나는 이것을 어떻게 처리해야할지 모르겠다. 도와주세요?

감사합니다, 제니퍼

+3

와우,이 나쁜 소리, 응용 프로그램에서 동적으로 생성 된 테이블 이유 - 그들은 3 자에 다를 경우 CMDB_CI''라는 이름의 테이블과 코드를 저장하는 긴 3 자하는 열의가 있어야는 . SQL에서 테이블을 동적으로 생성하고 싶지는 않습니다. SQL Server, DB2, Oracle, mySQL 또는 Progress 등 어떤 플랫폼을 사용하고 있습니까? – Hogan

+2

SQL 쿼리에서 테이블을 매개 변수화 할 수 없습니다. 그리고 나는 @Hogan에 동의합니다. 여러분이 실제로 쿼리 할 수있는 데이터를 테이블 이름에 포함시켜 버린 것처럼 보입니다. 이는 데이터와 메타 데이터가 혼란 스럽습니다. –

+0

SQL Server 2008을 사용하고 있습니다. 응용 프로그램을 지원 팀에 요청하여 왜 이렇게 설정했는지, 그리고 테이블에 특성이 설정되어 있고 각 유형마다 다른 특성을 가질 수 있으므로 열 이름이 다를 수 있다고 들었습니다. 각 속성. 하나는 열 이름이 "Color"이고 다른 하나는 "SerialNumber"일 수 있습니다. 그러나 나는 너에게 전적으로 동의한다. 나는 그것을 매우 다르게 설정했을 것이다. – Jennifer

답변

1
-- This part would be a SP parameter I expect 
DECLARE @tableName varchar(100) 
SET @tableName = 'CMDB_CI_508' 

-- Main SP code 
DECLARE @sqlStm VARCHAR(MAX) 

SET @sqlStm = 'SELECT * 
FROM '+ @tableName 

EXEC (@sqlStm) 

바이올린 http://sqlfiddle.com/#!3/436a7/7

+0

나는'Declare @ suffix char (3), @tableName varchar (100);과 같은 것을 할 것이다. @tableName = 'CMDB_CI _'+ @ suffix'를 설정하면 주입 공격이 훨씬 어려워집니다. –

+0

@KM - 그렇습니다. 단지 "깨끗한 코드"이기 때문입니다. 여기서 동적 SQL의 예를 만들었습니다. 주입 측면에서 프로그래머는 매개 변수화 된 쿼리와 SPs를 사용해야합니다. – Hogan

+0

그건 작동하지 않습니다. 문제는 함수에서 EXEC 문을 사용할 수 없다는 것입니다. 내가 아는 한, 스토어드 프로 시저에 테이블 이름을 전달하면 select 절에서 그렇게 할 수 없다. 테이블에서 반환되는 각 행에 대해이 작업을 수행해야합니다. 내가 정말 필요한 것은이 같은 것입니다 :. CI_ID, C.CI_TYPE_ID, CI_CUSTOM_ID, 상태, CI_TYPE_NAME, UDF_GetCIName (C.CI_TYPE_ID C.CI_ID)를 선택 [발자국] FROM [DBO].[CMDB50_CI_COMMON] 3 [발자국] 가입 [DBO] CMDB50_CI_TYPE] t c.CI_TYPE_ID에 CI_TYPE_NAME – Jennifer

0

첫째, 그래, 나는 그것이 나쁜 디자인 알고있다. 나는 그것을 디자인하지 않았다. 그것은 우리 회사가 콜센터에서 구입 한 문제 추적 소프트웨어와 함께 제공되었습니다. 그래서 나는 모든 접근 방식을 포기하고 여러 테이블의 모든 이름을 하나의 임시 테이블로 가져온 다음 원래의 쿼리에 조인하기 위해 임시 테이블을 사용했습니다.

ALTER Proc [dbo].[CI_CurrentItems] 

As 

Declare @CIType nvarchar(6) 
Declare @Qry nvarchar(100) 
/* 
Create Table Temp_CI 
(T_CI_ID int, 
    T_CI_Type_ID int, 
    T_Name nvarchar(400) 
) 
*/ 

Truncate Table Temp_CI 

Declare CI_Cursor Cursor For 
select distinct CI_TYPE_ID FROM [footprints].[dbo].[CMDB50_CI_COMMON] 
where STATUS <> 'Retired' 

Open CI_Cursor 

Fetch Next from CI_Cursor into @CIType 

While @@FETCH_STATUS = 0 
BEGIN 
Set @Qry = 'Select CI_ID, CI_Type_ID, Name from Footprints.dbo.CMDB50_CI_' + @CIType 
Insert into Temp_CI Exec (@Qry) 
Fetch Next from CI_Cursor into @CIType 
END 

Close CI_Cursor 
Deallocate CI_Cursor 

SELECT CI_ID, 
    C.CI_TYPE_ID, 
    CI_CUSTOM_ID, 
    STATUS, 
    CI_TYPE_NAME, 
    T_Name 
FROM [footprints].[dbo].[CMDB50_CI_COMMON] c 
JOIN [footprints].[dbo].[CMDB50_CI_TYPE] t 
ON c.CI_TYPE_ID = t.CI_TYPE_ID 
JOIN Temp_CI tc 
ON c.CI_ID = tc.T_CI_ID 
AND t.CI_TYPE_ID = tc.T_CI_TYPE_ID 
WHERE STATUS <> 'retired' 
ORDER BY CI_TYPE_NAME