2011-04-26 11 views
7

いくつかのサーバーで、TSQLとは異なる結果セットを提供しますsql2008と比較してみましたが、私はかなり問題を絞り込んで、シンプルで再現性のある問題にするためにかなりのコードを削除しました。要約すると、TSQLの一部は、プロキシとして実行すると、ちょうどTSQLと同じコードが実行されている別の回答が返されます。クライアントサーバーであり、テストサーバーではありません。ストアドプロシージャはこれは私が昨日尋ねた質問にフォローされ

私はこのTSQL実行すると:

CREATE Procedure [dbo].[sp_test] 
    @PropertyID int = Null, 
    @PortfolioID int = Null, 
    @StartDate datetime = Null, 
    @EndDate datetime = Null, 
    @AcctMethod tinyint = 1 

AS 


DECLARE @ErrorMsg varchar(70) 
DECLARE @ExclAcct tinyint 

SET NOCOUNT ON 
CREATE TABLE #IncomeStatement (
    PropertyID  int, 
    GLAccountID  int, 
    SubTotalAccountID int, 
    Debits   money, 
    Credits   money, 
    YTDDebits  money, 
    YTDCredits  money, 
    PZDebits  money, 
    PZCredits  money, 
    AccountType  tinyint 
) 

--Initialize Temporary Table 
INSERT INTO #IncomeStatement(PropertyID, GLAccountID, SubTotalAccountID, AccountType, Debits, Credits, YTDDebits, YTDCredits, PZDebits, PZCredits) 
SELECT PropertyID, ID, SubTotalAccountID, AccountType, 0, 0, 0, 0, 0, 0 
FROM ChartOfAccounts 
WHERE (PropertyID = @PropertyID OR @PropertyID Is Null) 
    AND (@PortfolioID is null OR PropertyID in (select PropertyID from PortfolioProperty where [email protected])) 
    AND (Category > 3 or CashFlowCode <> 0) 

--Period Activity 
IF @AcctMethod = 1 
    SET @ExclAcct = 0 
ELSE 
    SET @ExclAcct = 1 

UPDATE Bal 
SET 
    Debits = Debits + D.TotDebit, 
    Credits = Credits + D.TotCredit 
FROM #IncomeStatement Bal 
    INNER JOIN (SELECT GLAccountID, Sum(Debit) AS TotDebit, Sum(Credit) AS TotCredit 
      FROM GLTransaction GT 
      WHERE (GT.PropertyID = @PropertyID OR @PropertyID Is Null) 
       AND AccountingMethod <> @ExclAcct 
       AND Posted = 1 
       AND TranDate >= @StartDate 
       AND TranDate <= @EndDate 
      GROUP BY GLAccountID) AS D 
     ON BAL.GLAccountID = D.GLAccountID 

select * from #IncomeStatement where GLAccountID=11153 
drop table #IncomeStatement 

してから実行します。

DECLARE @PropertyID int 
DECLARE @PortfolioID int 
DECLARE @StartDate datetime 
DECLARE @EndDate datetime 
DECLARE @AcctMethod tinyint 

SET @PropertyId=3555 
--SET @PortfolioId = null 
SET @StartDate= '3/1/2010' 
SET @EndDate='2/28/2011' 
SET @AcctMethod=1 

DECLARE @ErrorMsg varchar(70) 
DECLARE @ExclAcct tinyint 

SET NOCOUNT ON 
CREATE TABLE #IncomeStatement (
    PropertyID  int, 
    GLAccountID  int, 
    SubTotalAccountID int, 
    Debits   money, 
    Credits   money, 
    YTDDebits  money, 
    YTDCredits  money, 
    PZDebits  money, 
    PZCredits  money, 
    AccountType  tinyint 
) 

--Initialize Temporary Table 
INSERT INTO #IncomeStatement(PropertyID, GLAccountID, SubTotalAccountID, AccountType, Debits, Credits, YTDDebits, YTDCredits, PZDebits, PZCredits) 
SELECT PropertyID, ID, SubTotalAccountID, AccountType, 0, 0, 0, 0, 0, 0 
FROM ChartOfAccounts 
WHERE (PropertyID = @PropertyID OR @PropertyID Is Null) 
    AND (@PortfolioID is null OR PropertyID in (select PropertyID from PortfolioProperty where [email protected])) 
    AND (Category > 3 or CashFlowCode <> 0) 

--Period Activity 
IF @AcctMethod = 1 
    SET @ExclAcct = 0 
ELSE 
    SET @ExclAcct = 1 

UPDATE Bal 
SET 
    Debits = Debits + D.TotDebit, 
    Credits = Credits + D.TotCredit 
FROM #IncomeStatement Bal 
    INNER JOIN (SELECT GLAccountID, Sum(Debit) AS TotDebit, Sum(Credit) AS TotCredit 
      FROM GLTransaction GT 
      WHERE (GT.PropertyID = @PropertyID OR @PropertyID Is Null) 
       AND AccountingMethod <> @ExclAcct 
       AND Posted = 1 
       AND TranDate >= @StartDate 
       AND TranDate <= @EndDate 
      GROUP BY GLAccountID) AS D 
     ON BAL.GLAccountID = D.GLAccountID 

select * from #IncomeStatement where GLAccountID=11153 
drop table #IncomeStatement 

を私はこのようなストアドプロシージャに上記のコードを入れたとき、私は、しかし、$ 124.27の借方金額を取得私はそれがどうあるべきかを正確にダブルで$ 248.54の借方金額を、取得

EXEC sp_test @PropertyID=3555, @StartDate='03/01/2010', @EndDate='02/28/2011' 

:それはこれをローク。

私は本当に困惑しています。 odderのことは、このデータベースをバックアップしてからSQL2008R2を実行しているwin2003サーバーまたはSQL2008R2を実行しているwin2008サーバーにコピーすると、どちらの場合でも正常に動作します。だから、と思われますが、問題を引き起こしているサーバーやデータベースの設定ですが、チェックするために不足しているものがあります。ここ

+0

うわー、奇妙な行動。 – alex

+0

それは本当に奇妙です。両方のケースで#IncomeStatementで同じ数のレコードから開始しているかどうかを確認できますか?また、一時テーブルの代わりにテーブル変数を使用しようとしましたか?たぶんクライアントサーバー上のtempdbに設定があり、ここで不思議なことが起こっているかもしれません。 – rsbarro

+0

SET ANSI_NULLSが違いを生むかどうかチェックしましたか? http://msdn.microsoft.com/en-us/library/ms188048.aspx –

答えて

7

OKは、私の修正です - それは絶対に元の問題を説明していませんが、これは私がやったことです:

私は「パラメータスニッフィング」パフォーマンスの問題を持っているときはいつでも、私ことを解決するために、このように、PROCの残りの部分にのみ、ローカル変数を使用し、その後、すべてのパラメータのための「ローカル」変数を宣言これらの変数にそれらのパラメータを割り当て、そして:

ALTER Procedure [dbo].[rptDateIncomeStatementPlusCash] 
     @PropertyID int = Null, 
     @PortfolioID int = Null, 
     @StartDate datetime = Null, 
     @EndDate datetime = Null, 
     @AcctMethod tinyint = 1 
    AS 
     DECLARE @xPropertyID int 
     DECLARE @xPortfolioID int 
     DECLARE @xStartDate datetime 
     DECLARE @xEndDate datetime 
     DECLARE @xAcctMethod tinyint 

     SET @xPropertyID= @PropertyId 
     SET @xPortfolioId = @PortfolioId 
     SET @xStartDate = @StartDate 
     SET @xEndDate = @EndDate 
     SET @xAcctMethod = @AcctMethod 

類似性は、パラメータスニッフィングが問題であるときということです、あなたはMGMTスタジオを介してストアドプロシージャを実行することができますし、SQLとしてそれを実行するよりも良いパフォーマンスを得る(上記のような)、usu同盟国はそれを修正する。

私のケースでは、ストレートTSQLとprocの実行の違いが分かりましたが(パフォーマンスには関係ありませんでしたが)、私は試してみました。私は、正直なところ、SQL Serverがほぼ同じコードを実行しているときに矛盾した結果を出すと思うのは恐ろしいことだと思います。

私は、少なくとも右の状況下では、SQLサーバーはあなたに悪い答えを与えることを確認しないことに、似ていますが、別の問題についてthis bulletin from MSを見つけた、このキーフレーズとthis related bug report

説明:二つセッションごとに、 プロシージャPへのコールが でパラメータ値が変更されます。 プロシージャPは、 静的データに対して1つのクエリを実行します。場合によってはOPTION (RECOMPILE)を使用し、場合によっては使用しません。

時々Pが間違った結果を与える (以下のreproの場合、これは通常、 が時間の約1/2%〜1%で発生します)。 Pの結果が間違っている場合、Pは の行の0または2のいずれかを に返します。

誰か昨日は可能性として盗聴パラメータについてのコメントを残したが、何らかの理由で、彼らは彼らのコメント(または回答)を削除したので、私は先端のためにそれらに信用を与えることはできません。

+0

私たちは、ロットアルゴリズムの可能なマッチを生成する手続きを持っています。宝くじゲームのお客様私たちがクエリで持っていた問題は、ストアドプロシージャを直接実行した場合、80%以下の結果は返されませんでしたが、SSMSのブロックを強調表示して実行すると、より良い値の分布が得られることでした。パラメータの値は変更していませんでしたが、新しい値を作成して値を割り当てることは完全に機能しました。 **ありがとうございました!** –

1

Here is the execution plan, for those interested - could figure out how do this as a comment

+0

これは実行プランを探す上のコメントに対応しています。コメントとして追加できませんでした。 –

+1

パラレル化のバグに遭遇した場合の不思議 - 2つの同時スレッドが同じデータや何かを処理しています。 SQL Server 2000 SP4で[いくつかのパラレルバグ](http://support.microsoft.com/kb/888799)が修正されたように見えますが、明らかに関連しているものは見えませんでした。 –

関連する問題