2011-03-10 3 views
2

sp_executesql을 사용하는 저장 프로 시저를 만들려고합니다. here 길고 열심히 보았습니다.하지만 내 코드에서 잘못하고있는 것을 볼 수 없습니다. 나는 저장 프로 시저/SQL 서버 기능에 익숙하지 않으므로 간단한 것을 놓치고있는 것 같다. 스토어드 프로 시저 변경은 문제가 없지만 실행하려고하면 오류가 발생합니다.params와 함께 sp_executesql을 사용하면 변수를 선언해야한다고 불평합니다.

오류가 발생했습니다.

Msg 1087, Level 15, State 2, Line 3 
Must declare the table variable "@atableName" 

절차는 다음과 같습니다.

set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
go 

ALTER PROCEDURE [dbo].[sp_TEST] 
    @tableName varchar(50), 
    @tableIDField varchar(50), 
    @tableValueField varchar(50) 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @SQLString nvarchar(500); 
    SET @SQLString = N'SELECT DISTINCT @aTableIDField FROM @atableName'; 
    EXEC sp_executesql @SQLString, 
      N'@atableName varchar(50), 
       @atableIDField varchar(50), 
       @atableValueField varchar(50)', 
      @atableName = @tableName, 
      @atableIDField = @tableIDField, 
      @atableValueField = @tableValueField; 
END 

그리고 저는 이것을 이와 같이 호출하려고합니다.

EXECUTE sp_TEST 'PERSON', 'PERSON.ID', 'PERSON.VALUE' 

이 예제에는 특별한 사항이 추가되지 않지만 비슷한 코드를 가진 많은 수의보기가 있습니다. 이 저장 프로 시저를 작동 시키면 많은 코드가 상당히 줄어들 수 있습니다.

도움 주셔서 감사합니다.

편집 : 쉬운 유지 관리 목적으로이 작업을 시도하고 있습니다. 테이블 이름을 제외하고 기본적으로 동일한 정확한 SQL 여러보기가 다릅니다. 데이터는보고 목적으로 SQL Server 인스턴스로 전달됩니다. 각각 하나의 값을 포함하는 1 인당 여러 행을 포함하는 표가있을 때 종종 사용자를 위해 단일 셀에 표가 필요합니다.

답변

3

배우고 실험하려는 경우가 아니라면 효과가 있지만 권장하지는 않습니다.

ALTER PROCEDURE [dbo].[sp_TEST] 
    @tableName varchar(50), 
    @tableIDField varchar(50), 
    @tableValueField varchar(50) 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @SQLString nvarchar(500); 
    SET @SQLString = N'SELECT DISTINCT ' + quotename(@TableIDField) + ' FROM ' + quotename(@tableName); 
    EXEC sp_executesql @SQLString; 
END 

읽기 The Curse and Blessings of Dynamic SQL

+0

"select * from @tablename"부분은 유지 관리 목적을 위해 무엇을 하려는지 설명했습니다. 다중 값 데이터베이스에서 내 보낸 10 - 100 초 필드가 있습니다. 이들은 공급 업체 제품에서 내보내지고 행당 개인 ID 및 값이있는 테이블에 배치됩니다.보고 목적 상, 코드는 종종 모든 값을 하나로 끌어 오기 위해 작성됩니다. 모든 곳에서 동일한 코드가 작성 되었기 때문에이 반복적 인 경향을 한 곳에서 작성함으로써 유지 관리가 더 쉬울 수도 있다고 생각했습니다. 내가 그것을 빨고 같은 구조가 도처에 반복하게해야합니까? – wilbbe01

+0

@ wibbe01, 게시물의 링크 된 기사를 살펴보십시오. 동적 SQL은 그 자리를 차지하고 있지만 특히 테이블 이름과 열 이름을 전달하는 것과 같이 올바르게 사용하지 않으면 위험합니다. 그것은 SQL 주입에 매우 취약합니다. 상황에 맞는 SP 생성 코드 생성 도구를 사용하는 것이 훨씬 더 안전 할 수 있습니다. 그러나이 길로 가기로 결정했다면 매우 조심하십시오. –

3

당신은 테이블 이름의 파라미터를 할 수없는, 그래서 당신은 종류의 sp_executesql을

를 사용 fo를 목적으로 패배 atableName와 첫 번째 비트를 연결할 필요가

@atableName

와 함께 실패합니다
+0

감사합니다. 나는 내가 다른 방식으로 그렇게 할 것이라고 생각한다. 내가 여기서하려고하는 전체 쿼리는 꽤 길다. sp_executesql을 사용하는 것과는 다른 방식으로 테이블 이름을 연결해야한다는 것을 말하고 있습니까? 당신의 도움을 주셔서 감사합니다. – wilbbe01

+1

Andriy M의 대답을 참조하십시오. 그러나 이것은 SQL 주입까지 열어줍니다. 개인적으로 나는 내 데이터베이스에 여러 객체를 귀찮게하지 않을 것입니다. – gbn

2

당신이 변수를 사용할 수 없습니다 테이블 이름과 열 이름을 매개 변수로 동적 쿼리에 전달합니다. 가능하다면 실제로 동적 쿼리를 사용하지 않았을 것입니다!

대신 변수를 사용하여 동적 쿼리를 구성해야합니다. 이처럼 :

SET @SQLString = N'SELECT DISTINCT ' + QUOTENAME(@TableIDField) + 
        ' FROM ' + QUOTENAME(@TableName); 

매개 변수는 일반적으로 필터 조건에서 사용하기 위해, 을 전달하는 데 사용된다.

관련 문제