2009-09-04 9 views
0

私は、このストアドプロシージャの定義マイナスボディTSQLストアドプロシージャの引数エラー

ALTER PROCEDURE sp_AlloctionReport(@where NVARCHAR(1000), @alldate NVARCHAR(200), @alldateprevweek NVARCHAR(200)) 
AS 

を持っていると私はこのように呼び出した場合。

sp_AllocationReport "ProductCode = 'FA' AND AllocationDate = '20090112' AND VenueInfo.VenueID In(SELECT vf.VenueID FROM VenueFilters vf INNER JOIN FilterTypes ft ON vf.FilterTypeID = ft.FilterTypeID WHERE ft.FilterDescription = 'Coke') AND State = 'NSW'","CampaignAllocations.AllocationDate = '20090112'","CampaignAllocations.AllocationDate = '20090105'" 

最初の引数がNVARCHAR(1000)に設定されていると、このエラーが発生します。

'AND AllocationDate = '20090112' AND VenueInfo.VenueIDにおいて(VenueFilters VF INNER FROM vf.VenueIDを選択FiがJOIN 'が長すぎます。最大長である' 製品コード=' FAで始まる識別子128

答えて

1
  1. は、where句を取ると
  2. は ''と' を置換新しいファイルで編集(単一引用符 - >ダブル単一引用符)
  3. EXEC dbo.sp_AllocationReport @where= '<THE TEXT EDITED ABOVE>'
0
  • 「コーク」の二重引用符を確認してください。ハイフリージャの構文はエラーを明白にします。
  • メインストリングには一重引用符を使用し、必要に応じてダブルエスケープします。それを行う。
  • 接頭辞NVarcharリテラルには大文字N
  • これはSQLインジェクションハックの発生を待っています。 sqlを文字列変数として渡す必要がありますか?
+0

私は一重引用符で試しましたが、同じエラーが表示されます。これは内部のアクセスフロントエンドアプリであり、文字列を使用しています。 – Malcolm

+0

。社内の従業員は決して悪いことをしないので大丈夫です。それに幸運。 –

0

の最大長128文字でSQL Serverのオブジェクト(私は思う)。おそらく、クエリを構築するときに文法上の問題が発生し、文字列全体がテーブル/ビュー名であると思われましたか?

0

あなたは、接続がQUOTED_IDENTIFIERが

http://msdn.microsoft.com/en-us/library/ms174393.aspx ON

になっていない限り、これは以降のSQL 2000のデフォルトですが、その後、旧バージョンからアップグレードした場合は、単一引用符の代わりに二重引用符を使用する必要があります。古いデフォルトは引き続きアクティブになります。

0

格納されたprocの本体があれば、それはより明確かもしれません。しかし、それは、SQL Serverがパラメータをインデンタ(つまり列名)として解釈しているように見えます。ヒントメッセージは「」ProductCode = 'FA'で始まり[...]で始まる識別子が長すぎます。です。つまり、SQL Serverは、名前のを探している「= 『FA』 製品コードと[...等...]

だから私はあなたがストアドプロシージャ内にこれをでやったされた疑いがあるものを:

SELECT col1, col2, col3, ... FROM table WHERE @where 

...とあなたは、ちょうどそのように動作することを望んでいる。

これを実行したと仮定すると、動作しません。これがあなたがやったことでない場合、この答えの残りの部分は完全に偽であるかもしれません:-)あなたがsprocのボディの例を与えることができるなら、物事をより明確にするかもしれません。

だから私のsuspisionが正しいと仮定すると、あなたはこのような動的SQLステートメントとしてそれを記述する必要があります。

DECLARE @sql NVARCHAR(2000) 
SET @sql = 'SELECT col1, col2, col3, ... FROM table WHERE ' + @where 
EXEC sp_ExecuteSQL @sql 

もつとも ...でも、これはのように物語の終わりではありませんこれはa very bad thingである注射攻撃を受けやすい。あなたがやっている方が良いのは、格納されたprocにパラメータを変更して、注入攻撃を受けにくいパラメータ化されたSQLを利用することです。このようなものは...

ALTER PROCEDURE sp_AllocationReport (@ProductCode VARCHAR(10), @AllocationDate DATETIME, {rest of your parameters}) 
AS 
    DECLARE @sql NVARCHAR(2000) 
    SET @sql = 'SELECT col1, col2, col3, ... FROM table WHERE 1 = 1' 

    IF ISNULL(@ProductCode, '') <> '' 
     SET @sql = @sql + ' AND ProductCode = @pProductCode' 
    IF @AllocationDate IS NOT NULL 
     SET @sql = @sql + ' AND AllocationDate = @pAllocationDate' 
    {other conditionals, depending on what you need to pass in} 

    EXEC sp_ExecuteSQL @sql, '@pProductCode VARCHAR(10), 
           @pAllocationDate DATETIME, 
           {other passed in params} 
          ', @ProductCode, @AllocationDate 

このコードは注入攻撃を受けにくいです。 SQL Serverは実行計画をより確実にキャッシュするので、パフォーマンスも向上します。これについて読む。そこにはたくさんのものがあります。

関連する問題