2017-01-19 3 views
2

これは非常に簡単な解決策ですが、わかりません。助けてください。他のストアドプロシージャからOUTPUT paramを使ってprocを格納したSQLを呼び出す

私は、別のストアドプロシージャからOUTPUTパラメータを持つストアドプロシージャを呼び出す必要があります。私は問題の1つが動的SQLだと思いますが、@SQLWhereがC#コード内で動的に変更されるので、それをどのように書くべきかわかりません。

これは別のPROCから呼び出されprocのです。ここで

ALTER PROCEDURE [dbo].[USP_RetrieveTotalRecord] 
@SQLWhere AS NVARCHAR(1000), 
@TotalRecordsFound as varchar(16) OUTPUT 
AS 
BEGIN 
SET NOCOUNT ON; 
    DECLARE @SQL AS NVARCHAR(Max) 
    SET @SQL='Select @TotalRecordsFound = Count(Table_ID) 
    From TableName Where ' + @SQLWhere 
    EXEC(@SQL) 
    return 
END 

は、私は別のPROCからそれを呼び出しています方法です。ここで

Declare @TotalRec AS NVARCHAR(16); 
Declare @SQLWhere AS NVARCHAR(1000); 
SET @SQLWhere='Date Between ''12/13/2016'' AND ''12/14/2016''' 
EXECUTE USP_RetrieveTotalRecord @SQLWhere, @TotalRec output; 

は私が解決しようとしているエラーです:

Msg 137, Level 15, State 1, Line 30 
Must declare the scalar variable "@TotalRecordsFound". 
+0

SQLインジェクションの悪夢を無視して、出力をインクルードするように動的クエリをパラメータ化する必要があります。編集:ここの答えは、例です:http://stackoverflow.com/questions/3840730/getting-result-of-dynamic-sql-into-a-variable-for-sql-server – ZLK

答えて

0

なぜ2番目のSPを持っているのか分かりません。そのようなものを使用してください:

Declare @TotalRec AS NVARCHAR(16); 
Declare @SQLWhere AS NVARCHAR(1000); 
SET @SQLWhere='Date Between ''12/13/2016'' AND ''12/14/2016''' 
SET @SQL='Select @TotalRecordsFound = Count(Table_ID) 
    From TableName Where ' + @SQLWhere 
EXEC(@SQL) 

または使用日付変数それはあなたが選択(必要なし動的SQL)のために使用されているすべてだ場合 - これはちょうど簡単な例

でない限り---コメントセクションが壊れているので、応答で取得します値が出て、このようなものを使用します。

[OK]を - 最も簡単な方法は、あなたがやろうとしているものを行うだけストアドプロシージャに値を渡すと、次にビルドしないでくださいsp_executesqlを

Declare @result int 
Declare @sql nvarchar(max) 
SET @SQL = ' SELECT COUNT(*) FROM MyTable' 

exec sp_ExecuteSQL @sql, N' @Result int Output', @Result output 

select @result as MyCount 
+0

DaveN、あなたはこれが正しい簡略版です。 WHERE句には1つ以上の条件が存在する可能性があります。実際には、別のprocは必要ありません。仰るとおりです。しかし、どのように@TotalRecordsFoundを別の「選択」で使用するのですか? – SilverFish

+0

また、私は変数のフォームでカウントが必要なので、なぜ私は次のステップ – SilverFish

0

を使用することですダイナミックあなたのプロシージャ内のIC SQL、......

ALTER PROCEDURE [dbo].[USP_RetrieveTotalRecord] 
    @StartDate DATE = NULL 
    ,@EndDate  DATE = NULL 
    ,@TotalRecordsFound INT OUTPUT 
AS 
BEGIN 
SET NOCOUNT ON; 

    DECLARE @SQL NVARCHAR(Max); 
    SET @SQL = N' Select @TotalRecordsFound = Count(Table_ID) ' 
      + N' From TableName Where 1 =1 ' 
      + CASE WHEN @StartDate IS NOT NULL THEN 
       N' AND [Date] >= @StartDate ' ELSE N' ' END 
      + CASE WHEN @EndDate IS NOT NULL THEN 
       N' AND [Date] <= @EndDate ' ELSE N' ' END 

    EXEC sp_executesql @SQL 
         ,N'@StartDate DATE, @EndDate DATE, @TotalRecordsFound INT OUTPUT' 
         ,@StartDate 
         ,@EndDate 
         ,@TotalRecordsFound OUTPUT 
END 

のようなものは今@EndDate@StartDate変数は、手続きがそれに応じて動的SQLを構築し、その結果を返します渡す変数のどの値に応じて、オプションです。

また、sp_executesqlでパラメータ化されたクエリを使用すると、可能なSQLインジェクションアタッチから保護されます。また、パラメータ化された実行計画の利点があります。

+0

Mで計算をしなければならないので@TotalRecordsFoundを使用しているフィールドです。アリ、私は@ベースを構築して以来、.NETコードから送信@SQLWhereを使用する必要がありますいくつかの選択肢でしかし、私が見ることの1つは、EXEC sp_executesqlを使用していることです。私はそれを試みることができます。このproc USP_RetrieveTotalRecordを別のストアドプロシージャからどのように呼び出すのか教えてください。 – SilverFish

+0

@ Silberfishはアプリケーションレイヤーから値を取得するだけで、アプリケーションコードにt-sqlをビルドしないでください。また、有効な 'Date'値をプロシージャーに渡すことで、暗黙的な変換を回避し、表の索引の恩恵を受けることができます。 –

0

M. aliさん、ご協力いただきありがとうございます。しかし、動的選択の後、アプリケーションから条件を渡すことでSELECT、WHERE、およびGROUPがすべて取得されています。私は迅速な修正が必要でした。 最後に、私は一時テーブルを使用して問題を解決することができました。私はそれらが推奨されていないことを知っているが、私は共通テーブル式、テーブル変数を使用してみましたが、@TotalRecordsFoundは動的SQLの外では見えませんでした。したがって、作成されたテンポラリ・テーブルは、動的SQLを使用してデータに挿入され、次のselect文と結合されます。

関連する問題