0

さまざまな状況に基づいて列内のいくつかの値を更新したい.....テーブルには次のような詳細があります.....

                    Date               date
                    period             int
                    subcode            varchar(3)
                    status_bits        varchar(100)
                    // status bits resemble an information based code based...the data usually stored are  2343211 where each value in digits represent an information.....

ここで、さまざまな日付と期間に基づいてこれらの値を更新する必要がありますjava program....

私はJavaのような対応する変数に詳細を保存しました..

                   java.util.Date date[];
                   int period[];
                   String subcode[];

                   // Here for an index i , they share the same values within a row.....

異なる日付、期間、およびサブコード(結合)の varchar の 5 番目の文字を変更したいような方法で更新したい場合.....今..私は現在このように実行しています...

     Connection con;
     preparedStatement ps;
     String bitstatus;



     for(i=0; i < noofupdates; i++)
     {
           ps = con.prepareStatement("select status_bits from tablename where Date = ? AND period = ? AND subcode = ? limit 0,1");
           ps.setDate(1,date[i]);
           ps.setInt(2,period[i])'
           ps.setString(3,subcode[i]);

           rs=ps.executeQuery();
           while(rs.next())
           {

                 bitstatus = rs.getString(1);
                 // performed operation to update the bit.....
                 ps=con.prepareStatment("update status_bits correspondind to the same date,field and subcode");

                 ps.executeUpdate();
           }

     }

プログラムから、ビット操作が一般的なさまざまな日付と期間に基づいてテーブルの status_bits を更新したいことを理解していると思います......今、これらの方法が多くのクエリを実行し、深刻な影響を与えていることを本当に知っていますmysqlのパフォーマンス...だから、これに代わる多くのアイデアを提供することで私を助けてください........更新するレコードが約1000あります....

4

2 に答える 2

1

最初にデータベースからいくつかのデータ (status_bits) を読み取り、取得したレコードの数に基づいて複数のデータベースを複数回呼び出します。

代わりに、日付、期間、およびサブコードをパラメーターとして取り、SP 自体でロジック全体を実行するストアド プロシージャを 1 つだけ作成してみませんか?

そうすれば、DB 呼び出しは 1 回だけです。

于 2012-07-09T18:35:34.800 に答える
1

status_bits 文字列の 5 番目の位置を特定の値 (日付、期間、サブコード) に設定する必要があることがわかっている場合は、SELECT を回避して更新のみを実行できます。

更新: status_bits 列の既存の値が 4 文字未満の場合を適切に処理するために、既存の文字列の長さが 1 文字しかない場合、2 番目の文字ではなく 5 番目の文字を置換するようにします。テストを行うために CASE 式を使用できます。少なくとも 4 文字ある場合は、最初の 4 文字の後に (目的の) 5 番目の文字を追加できます。それ以外の場合は、(目的の) 5 番目の文字を追加する前に、既存の文字列を 4 文字に「埋め込む」必要があります。(以前は、ステートメントには、少なくとも 4 文字の長さの既存の文字列に対して機能する式のみが含まれていました。)

UPDATE tablename
   SET status_bits = 
       CASE WHEN CHAR_LENGTH(status_bits >= 4
         THEN CONCAT(LEFT(status_bits,4), ?, SUBSTR(status_bits,6))
         ELSE CONCAT(RPAD(status_bits,4), ? )
         END
 WHERE `Date` = ? AND period = ? AND subcode = ? 

(一致するすべての行を更新したくない場合は LIMIT 句を追加できますが、一致するすべての行を更新する場合は必要ありません。(date,period,subcode)が一意の場合、最大で 1 行と一致します。)

たとえば、where 句に述語を追加するか、SET で CASE 式 (または IF 関数) を追加することにより、他の条件に応じて status_bits の 5 番目の位置を設定することもできます。

UPDATE tablename
   SET status_bits = CONCAT(LEFT(status_bits,4)
                     , IF(SUBSTR(status_bits,1,1 = '1', ?, SUBSTR(status_bits,5,1))
                     , SUBSTR(status_bits,6))
 WHERE `Date` = ? AND period = ? AND subcode = ? 

次と同等です。

UPDATE tablename
   SET status_bits = CONCAT(LEFT(status_bits,4), ?, SUBSTR(status_bits,6))
 WHERE `Date` = ? AND period = ? AND subcode = ? 
   AND SUBSTR(status_bits,1,1) = '1'

このアプローチにより、実行しているクエリの数が半分になり (データベースへの往復回数が減ります)、status_bits列全体を返す必要がなくなります。

(残念ながら、varchar 列の 5 番目の文字を置き換える SQL テキストは少し扱いに​​くいです。MySQL にはSTUFF、SQL Server によって提供されるよりコンパクトな関数がないためです。)


更新:長さが 4 文字未満の既存の status_bits 文字列を処理するには、より複雑な式が必要です...)

UPDATE tablename
   SET status_bits = 
       CASE WHEN CHAR_LENGTH(status_bits) >= 4
            THEN CONCAT(LEFT(status_bits,4), ? , SUBSTR(status_bits,6))
            ELSE CONCAT(RPAD(status_bits,4,' '), ? )
       END
 WHERE `Date` = ? AND period = ? AND subcode = ?

注: その SQL ステートメントでは、5 番目の位置に配置する文字の値を 2 つの個別の位置パラメーターで指定する必要があります。

ノート:

于 2012-07-09T18:47:09.370 に答える