2012-04-12 7 views
0

私はC#で書かれたアプリケーションをデータベースに接続し、そのデータを分析し、データベースに自動テストの実行に関する情報を格納しています。上記の条件を満たすテスト。しかし、私たちは別のプロジェクトを持っており、ますますサポートしていきますので、それぞれに異なるプロシージャを作成するのではなく、名前を渡してください - 2番目のパラメータ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

こんにちは、これは忘れましたが、resultとdeploynameにはまだ問題があります。 – Artur

+0

@Artur - これは同様の問題です。あなたは達成しようとしていることを(あなたの質問で)正確に説明できますか?私たちにあなたのソリューション(不適切な可能性があります)を与える代わりに、あなたが抱えている問題を説明し、解決しなければならない問題を説明してください。 – Oded

+0

もちろん、問題は次のとおりです。C#で書かれたアプリケーションをデータベースに接続してデータを分析し、データベースに自動テストの実行に関する情報を格納しています。実行したいテストを取得することです上記の条件。しかし、私たちは別のプロジェクトを持っており、ますますサポートしていきますので、それぞれに異なるプロシージャを作成するのではなく、名前を渡してください - 2番目のパラメータdeployをパラメータとして使用して、クエリはプロジェクトに依存し、アプリケーションでは、レポートで送信します。 – Artur

0

例にはいくつか問題があります。しかし、これは1つのオーバーアーチ型の考察です。

変数(テーブルおよび/またはスカラー)は、定義されているStoredProcedureにのみ表示されます。EXEC(@SQL)を呼び出すと、ストアドプロシージャが呼び出されます。これは、実行中の動的SQLに対して、他のパラメータではなく、@resultテーブルが表示されないことを意味します。

テーブルに関しては、代わりに一時テーブルを作成することで回避できます。また、スカラー変数の場合、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 @@行数はSP_EXECUTESQL以内のプロセスである行を表示するようになりました。この場合、出力パラメータを使用するか、ループを@SQLに埋め込むなどして、少し並べ替えが必要な場合があります。


全体的には少し不格好な感じ。あなたのスキーマなどの詳細については、動的SQLを避けることができます。
- @deployパラメータでSQLインジェクション攻撃を受けている可能性があります。

このSPを実行したり、@ deployの値を制御できる人は誰でも参加できます。パラメータがデータベースに悪影響を与える可能性があります。例えば


...あなたは同じテーブル内のすべてのTestCaseExecutionsを格納してもらえますか?しかし、余分なフィールド:TestCaseID *(またはさらにTestCaseName)?

次に、処理するデータセットを制御するために動的SQLを構築する必要はありません。代わりにWHERE TestCaseID = @TestCaseIDをクエリに追加してください。

関連する問題