1

データベースにユーザー名が存在しない場合にのみ、ユーザー登録中にレコードを挿入する基本的なシナリオを考えてみましょう。

私の質問は、2 つの別個のストアド プロシージャを作成し、データベースへの 2 つの呼び出しを作成して、1 つはユーザー名が存在するかどうかを確認し、2 つ目は実際にデータベースに挿入するか、または 1 つのストアド プロシージャを作成し、その中に両方のクエリを書き込むかです。 ?

ストアド プロシージャを 1 つ作成する場合、2 番目の質問は、ストアド プロシージャから実際に何を返す必要がありますか? 私は通常、ストアド プロシージャからハード コードされた数値を返し、コード内をチェックします。これは良い習慣ですか?

4

4 に答える 4

4

この操作は最終的に「アトミック」である必要があります。チェックを実際の作成から切り離すことはできません。そうしないと、同時実行の問題が発生する可能性があります。その一部は、トランザクションと 2 つ以上の SP にまたがるロックで処理できますが、IMHO の最良の方法は、1 つの SP を使用し、挿入が発生すると同時に (同じステートメントで) チェックを実行することです。

挿入されたユーザーの完全なレコードを含むレコードセットを返し、名前の競合がある場合はエラーを発生させます。

于 2012-04-13T08:38:00.520 に答える
3

新しく挿入されたユーザーのIDを返す1つのストアドプロシージャを実行します。挿入が発生しなかった場合は-1を返します。

于 2012-04-13T08:30:30.540 に答える
1

次のようなことができます。

CREATE PROCEDURE AddNewUser
(
  @Username         VARCHAR(30)
, @Password         VARCHAR(30)
, @UserExists       BIT OUTPUT
)

AS

-- CHECK IF THE USER EXISTS:
DECLARE @RowCount INT

SELECT @RowCount = COUNT(*) 
FROM Users
WHERE Username = @Username


IF (@RowCount > 0)
BEGIN
   SET @UserExists = 1
END
ELSE

BEGIN

   SET @UserExists = 0

   INSERT INTO Users
     (Username, [Password])
   VALUES
     (@Username, @Password)
END

GO

次に、アプリケーションで @UserExists パラメータを使用できます。1 はユーザーが既に存在することを示し、0 はユーザーが存在せず、作成されたことを示します。

SQL インジェクション攻撃に対して脆弱になるため、インライン SQL ではなくストアド プロシージャを使用することをお勧めします。

于 2012-04-13T08:47:02.163 に答える
0

MERGEステートメントが役立つ場合があります。MERGE条件付きINSERT/としましょうUPDATE単一のステートメントINSERTでは、存在しない場合は新しいユーザーを作成でき、存在する場合はそれのみを作成できUPDATEます。

他の人が書いたように: ストアド プロシージャは動的 SQL よりもはるかに優れています。にラップMERGECREATE PROCEDUREます。

現実世界では、アプリ/ウェブアプリでのユーザー インタラクション/ワークフローから、1 つまたは 2 つの手順が必要かどうかがわかります。

シナリオ A)

  • ユーザーデータを教えてください
  • 私はあなたのためにアカウントを作成するか、それを更新します (1 つのストアド プロシージャ)

シナリオ A ではMERGE、条件付きINSERT/を行いUPDATEます。

シナリオ B)

  • ユーザーデータを提供して、サインアップするか、単にログインするかを決定します
  • (サインアップしたい) - 指定されたログインが無料かどうかを確認する (最初のストアド プロシージャまたは単にクエリ)
  • (無料です。サインアップしてください!) - アカウントを作成しますが、ログインがまだ無料かどうかをもう一度確認する必要があります(2番目の手順)

シナリオ B では、ログインの存在を確認してから行うINSERTか、(より良い)ブロックINSERTで行うことができます。有用なメッセージ/状態をブロックで実行TRY .. CATCHできるため、(return param の代わりに) SQL から「例外」をスローし、アプリケーション コードでキャッチすることにより、アカウントの作成に関する問題を報告できます。このロジックは、コーディングでより役立つ場合があります。RAISERRORCATCH

于 2012-04-13T09:40:27.413 に答える