4

私が投稿したものとまったく同じタイトルの質問が他にもあることは知っていますが、それぞれが参照しているクエリまたは手順に非常に固有のものです.

ここで大学の Blackboard Learn システムを管理しており、データベースに直接アクセスできます。要するに、システムの頭痛の種を引き起こしているストアド プロシージャがあります。システムへの変更がコミットされると、エラーがバックエンドのログにスローされることがbbgs_cc_setStmtStatusあります。The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.

これは SP のコードですが、Blackboard がアプリケーションのテーブルにデータを入力して作成するときにインストールされる "機器" の一部であるため、私は書きませんでした。

USE [BBLEARN]
GO
/****** Object:  StoredProcedure [dbo].[bbgs_cc_setStmtStatus]    Script Date: 09/27/2013 09:19:48 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE              [dbo].[bbgs_cc_setStmtStatus](
   @registryKey   nvarchar(255),
   @registryVal   nvarchar(255),
   @registryDesc  varchar(255),
   @overwrite     BIT
) 
AS
BEGIN
  DECLARE @message varchar(200);

  IF (0 < (SELECT count(*) FROM bbgs_cc_stmt_status WHERE registry_key = @registryKey) ) BEGIN
    IF( @overwrite=1 ) BEGIN
      UPDATE bbgs_cc_stmt_status SET
        registry_value = @registryVal,
        description    = @registryDesc,
        dtmodified     = getDate()
      WHERE registry_key = @registryKey;
    END
  END
  ELSE BEGIN
    INSERT INTO bbgs_cc_stmt_status
        (registry_key, registry_value, description) VALUES
        (@registryKey, @registryVal, @registryDesc);
  END

  SET @message = 'bbgs_cc_setStmtStatus: Saved registry key [' + @registryKey + '] as status [' + @registryVal + '].';
  EXEC dbo.bbgs_cc_log @message, 'INFORMATIONAL';

END

Blackboard 固有のサポートは期待していませんが、SQL Server 2008 に関する限り、これを引き起こしているシステム設定があるかどうかを確認できるものがあるかどうかを知りたいです。Blackboard でチケットを開いていますが、まだ何も連絡がありません。

ここに私がチェックしたいくつかのことがあります:

tempdb システム データベース:

templog の初期サイズを 100MB に設定し、100MB ずつ自動拡張して、これが問題の原因であるかどうかを確認しました。役に立たなかったようです。実際の tempdb は 4GB から始まり、auto は必要になるたびに 1 ギガずつ増加します。tempdb で使用可能なスペースが tempdb の実際のサイズの 95 ~ 985 であることは正常ですか? たとえば、現在 tempdb のサイズは 12388.00 MB で、使用可能なスペースは 12286.37 MB です。

BBLEARNまた、自動拡張の最大値に達したため、メイン テーブルのログ ファイルの拡張が停止していました。サイズを大きくするために、初期サイズを 3GB に設定しました。

4

3 に答える 3

1

コミットを妨げている可能性のある潜在的なエラーがいくつか見られますが、構造について詳しく知らないため、これらは単なる推測です。

  1. ネストされた if の update 句が、一意である必要がある列 (または列のセット) を更新しようとしています。このチェックでは、少なくとも 1 つのアイテムが存在することのみが検証されますが、そのチェックはアイテムが 1 つだけ存在することを確認することに限定されないためです。

    IF (0 < (SELECT ...) ) BEGIN
    

    対。

    IF (1 = (SELECT ...) ) BEGIN
    

    一意である必要がある行に一意でない値を挿入する可能性があります。更新が実行される属性に制約がないことを確認してください (具体的には、主キー、ID、および一意の制約を探します)。これが問題である可能性: 低いがゼロではない。

  2. アプリケーションがすべてのパラメータに値を渡していないため、@message 文字列が null になり、ログ メソッドが null 文字列を追加しようとするとエラーが発生します。SQL では any + null = null なので、値を挿入して null に更新しても問題ありませんが、指定したコードのように null をログに記録することはできません。代わりに、null を考慮して、メッセージ変数のセッターを次のように変更する必要があります。

    SET @message = 'bbgs_cc_setStmtStatus: Saved registry key [' + COALESCE(@registryKey, '') + '] as status [' + COALESCE(@registryVal,'') + '].';
    

    これは、報告されたエラーに基づいて問題である可能性がはるかに高くなりますが、アプリ コード (null パラメーターが渡されるのを妨げている可能性があります) がなければ、知る方法はありません。

また、私は代わりに

IF (0 < (SELECT count(*) ...) ) BEGIN

私は使うだろう

IF (EXISTS (SELECT 1 ...) ) BEGIN

その方が効率的だからです。サブクエリのすべての行を返す必要はありません。これは、実行プランが最初に FROM ステートメントを実行し、実際に選択を評価してそれらの行をカウントし、それを 0 と比較するのではなく、行が存在することを確認するためです。

これらの提案から始めてください。さらに詳しい情報をお寄せいただければ、さらにトラブルシューティングをお手伝いできます。

于 2013-09-27T23:08:42.437 に答える
0

たぶん、MERGE ステートメントを使用できます: http://msdn.microsoft.com/fr-fr/library/bb510625%28v=sql.100%29.aspx

効率が上がると思います。

于 2013-09-27T22:38:25.983 に答える