2012-04-12 3 views
0

C#으로 작성된 응용 프로그램에서 데이터베이스에 연결하고 데이터를 분석하고 데이터베이스가 자동화 된 테스트 실행에 대한 정보를 저장합니다. 위의 주어진 조건을 충족시키는 테스트. 그러나 우리는 서로 다른 프로젝트를 수행하고 있으며 점점 더 많은 것을 지원할 것이기 때문에 각 프로젝트마다 서로 다른 프로 시저를 만들고 싶지는 않지만 이름을 전달하십시오 - 두 번째 매개 변수 deploy를 매개 변수로 사용하여 쿼리가 프로젝트에 종속되어 데이터를 반환합니다. 신청서를 작성한 다음 보고서로 보내 드리겠습니다. 시간에 대한 프로 시저에 문자열 변수를 전달하고 쿼리에 추가합니다.

은 다음과 같습니다 인 : 어떤 조언을

CREATE PROCEDURE [dbo].[SuspectsForFalsePositive](@build_id INT, @deploy VARCHAR(25)) 
AS 
BEGIN 

    SET NOCOUNT ON; 

    DECLARE @i int, @build int, @deployname varchar(25), @SQL varchar(max) 
    DECLARE @result table (tc int, fp float) 
    SET @i = 0 
    SET @build = @build_id 
    SET @deployname = @deploy 

    SET @SQL = 'insert '[email protected]+'select testcase_id, fail_percentage FROM [BuildTestResults].[dbo].['[email protected]+'TestCaseExecution] 
        where build_id = @build and fail_percentage >= 70' 

--INSERT @result select testcase_id, fail_percentage FROM [BuildTestResults] 
--.[dbo].[ABCTestCaseExecution] 
--where build_id = @build and fail_percentage >= 70 
--commented works 
    EXEC(@SQL) 
    WHILE (@@rowcount = 0) 
    BEGIN 
    SET @build = @build - 1 
    EXEC(@SQL) 
--INSERT @result select testcase_id, fail_percentage FROM [BuildTestResults].[dbo]. --[ABCTestCaseExecution] 
--where build_id = @build and fail_percentage >= 70 
--commented works 
    END 
    select * from @result order by fp DESC 
END 
GO 

감사합니다!

+0

"프로젝트"는 데이터베이스에 어떻게 저장됩니까? 다른 테이블들? – Oded

+0

정확히 다른 테이블 – Artur

+0

Erland Sommarskog의 [동적 SQL의 저주와 축복] (http://www.sommarskog.se/dynamic_sql.html)을 읽어 보시기 바랍니다. – Oded

답변

1

문자열에 @build이 있습니다. 이것은 문자열로 해석됩니다. @SQL을 실행하면 해당 변수가 포함되지 않으므로 오류가 발생합니다.

당신은 직접 을 연결해야합니다

SET @SQL = 'insert '[email protected]+'select testcase_id, fail_percentage FROM [BuildTestResults].[dbo].['[email protected]+'TestCaseExecution] 
        where build_id = '[email protected]+' and fail_percentage >= 70' 

당신은 그 실행 사이도 수행해야합니다.

+0

안녕하세요, 이것에 대해 잊어 버렸지 만 결과와 deployname에는 여전히 문제가 있습니다. – Artur

+0

@Artur - 비슷한 문제 일 것입니다. 궁금하신 점을 정확히 설명해 주시겠습니까? 우리에게 당신의 솔루션 (부적절 할 수도 있음)을 제공하는 대신, 당신이 가지고있는 문제를 설명하고 해결해야 할 문제를 설명하십시오 - 우리는 다른, 더 나은 접근법을 제안 할 수 있습니다. – Oded

+0

물론 그렇습니다. 문제는 다음과 같습니다. - C#으로 작성된 응용 프로그램을 데이터베이스에 연결하고 데이터를 분석하고, 데이터베이스가 자동 테스트 실행에 대한 정보를 저장하며, 수행하려는 테스트를 검색합니다. 위의 주어진 조건. 그러나 우리는 서로 다른 프로젝트를 수행하고 있으며 점점 더 많은 것을 지원할 것이기 때문에 각 프로젝트마다 서로 다른 프로 시저를 만들고 싶지는 않지만 이름을 전달하십시오 - 두 번째 매개 변수 deploy를 매개 변수로 사용하여 쿼리가 프로젝트에 종속되어 데이터를 반환합니다. 신청서를 작성한 다음 보고서로 보내 드리겠습니다. – Artur

0

예에 몇 가지 문제가 있습니다. 그러나 이것은 하나의 과장된 고려 사항입니다.

변수 (테이블 및/또는 스칼라)는 정의 된 StoredProcedure에서만 볼 수 있습니다. EXEC(@SQL)을 호출하면 stored가 호출됩니다. 즉, @result 테이블과 다른 매개 변수가 실행중인 동적 SQL에 표시되지 않습니다.

테이블의 관점에서 임시 테이블을 대신 생성 할 수 있습니다. 스칼라 변수의 경우 EXEC 대신 SP_EXECUTESQL을 사용할 때 전달할 수 있습니다.

나는 현재 SQL 서버에 액세스 할 수 있지만, 어쩌면 당신의 방법에 당신을 시작할 수있는이 같은 somethign하지 않습니다 ...

CREATE PROCEDURE [dbo].[SuspectsForFalsePositive](@build_id INT, @deploy VARCHAR(25)) 
AS 
BEGIN 

    SET NOCOUNT ON; 

    DECLARE 
    @i   int, 
    @build  int, 
    @deployname varchar(25), 
    @SQL  varchar(max) 

    CREATE TABLE #result (
    tc int, 
    fp float 
) 

    SELECT 
    @i   = 0, 
    @build  = @build_id, 
    @deployname = @deploy 

    SET @sql = '' 
    SET @sql = @sql + ' INSERT INTO #result' 
    SET @sql = @sql + ' SELECT testcase_id, fail_percentage' 
    SET @sql = @sql + ' FROM [BuildTestResults].[dbo].['[email protected]+'TestCaseExecution]' 
    SET @sql = @sql + ' WHERE build_id = @build and fail_percentage >= 70' 

    SP_EXECUTESQL 
    @SQL, 
    '@build INT', 
    @build 

    WHILE (@@rowcount = 0) 
    BEGIN 
    SET @build = @build - 1 
    SP_EXECUTESQL 
     @SQL, 
     '@build INT', 
     @build 
    END 

    SELECT * FROM #result ORDER BY fp DESC 

END 
GO 


나는 또한 내가 그에게 occures @@ rowcount는 이제 SP_EXECUTESQL 내의 프로세스 인 행을 볼 수 있습니다. 어떤 경우에는 (출력 매개 변수를 사용하거나 @SQL에 루프를 포함시키는 등) 약간의 재배치가 필요할 수 있습니다.


전체적으로는 약간 투박한 느낌. 당신의 스키마 등에 대한 더 많은 정보를 가지고, 동적 SQL을 피할 수 있습니다. 이것은 여러 가지 장점을 가지고 있지만, 특히 한 것이다
- 지금 당신이 @deploy의 매개 변수 @deploy의 값을이 SP를 실행, 및/또는 제어 할 수 있습니다

사람에 대한 SQL 주입 공격에 열려있어 매개 변수가 데이터베이스에 악영향을 줄 수 있습니다.

예를 들어


... 당신 같은 테이블에있는 모든 TestCaseExecutions를 저장할 수 있을까요? 하지만 추가 필드가있는 경우 : TestCaseID * (아니면 심지어 TestCaseName)?

그러면 처리중인 데이터 세트를 제어하기 위해 동적 SQL을 빌드 할 필요가 없습니다. 대신 WHERE TestCaseID = @TestCaseID을 쿼리에 추가하면됩니다 ...

관련 문제