0

より明確にするために:

テーブルテーブル (id int, username varchar(30), password varchar(30), last_successful_login timestamp, last_unsuccessful_login timestamp, another_variable varchar(30))は次の行があります:(1、 "tgh"、 "pass"、0、0、 "another")

1)間違ったユーザー/パスのペアですが、ユーザー名の行があります

すべての行の列をANDでselect id from thetable where username="tgh" and password="wrongpass" and another_variable="another";更新したいと思います(これは一意であり、( "tgh"、 "another")のペアで2つの行を使用することはできません。ただし、( "tgh"、 "another2")を使用することはできます)。 )から。last_unsuccessful_loginusername="tgh"another_variable="another"CURRENT_TIMESTAMP

したがって、例の行は(1, "tgh", "pass", 0, CURRENT_TIMESTAMP, "another")、完全に一致しない「select」クエリの後のようになります。

さらに明確にするために、私は、テーブル上でのみ、つまりusername="tgh"、選択の結果に応じて、余分な更新を実行しないようにしています。another_variable="another"update thetable set last_unsuccessful_login=CURRENT_TIMESTAMP where username="tgh" and another_variable="another";

2)正しいユーザー/パスペア

また、3つすべてとが一致する場合usernamepasswordanother_variable今回はをに設定last_successful_loginCURRENT_TIMESTAMPます。

これにより、行の例は `(1、" tgh "、" pass "、CURRENT_TIMESTAMP、0、" another ")になります。

これを行うための最も効率的な方法は何ですか?

4

1 に答える 1

1

あなたの質問に対する簡単な答えはノーです。SELECT ステートメントが更新を引き起こしたりトリガーしたりすることはできません。(ここでの注意点は、SELECT ステートメントは、UPDATE を実行できる FUNCTION (MySQL ストアド プログラム) を呼び出すことができるということです。)

UPDATE ステートメントの発行を回避することはできません。UPDATE ステートメントはどこかから発行する必要があり、SELECT ステートメントはそれを「トリガー」することはできません。

単一の UPDATE ステートメントで、提供されたパスワードをパスワード列の現在の値と照合してチェックし、last_successful_login 列と last_unsuccessful_login 列の両方を設定することができます。次に例を示します。

UPDATE thetable 
   SET last_successful_login = 
       IF(IFNULL(password,'')='wrongpass',CURRENT_TIMESTAMP,0)
     , last_unsuccessful_login = 
       IF(IFNULL(password,'')='wrongpass',0,CURRENT_TIMESTAMP)
 WHERE username='tgh' 
   AND another_variable='another'

したがって、最初に UPDATE ステートメントを発行できます。次に、SELECT ステートメントを発行します。

データベースへの「ラウンドトリップ」の数を最小限に抑えたい場合は、複雑さが増します (何が起こっているのかを他の人が把握するのが難しくなります) という犠牲を払って、UPDATE ステートメントをストアド プログラムに入れることができます。これを関数に入れると、ログインが成功したかどうかを示す戻り値を設定できます。

SELECT udf_login('username','wrongpass','another')

したがって、アプリケーションからはログイン チェックを行っているように見えますが、呼び出された関数は UPDATE を実行できます。

CREATE FUNCTION `udf_login`
( as_username         VARCHAR(30)
, as_password         VARCHAR(30)
, as_another_variable VARCHAR(30) 
) RETURNS INT
READS SQL DATA
BEGIN
   UPDATE `thetable`
      SET `last_successful_login` = 
          IF(IFNULL(`password`,'')=IFNULL(as_password,''),CURRENT_TIMESTAMP,0)
        , `last_unsuccessful_login` = 
          IF(IFNULL(`password`,'')=IFNULL(as_password,''),0,CURRENT_TIMESTAMP)
    WHERE `username` = as_username
      AND `another_variable` = as_another_variable;

   -- then perform whatever checks you need to (e.g)
   --     SELECT IFNULL(t.password,'')=IFNULL(as_password,'') AS password_match
   --       FROM `thetable` t
   --      WHERE t.username = as_username
   --        AND t.another_variable = as_another_variable
   -- and conditionally return a 0 or 1
   RETURN 0;
END$$
于 2012-08-20T21:57:03.673 に答える