1

私はバックアップユーティリティを持っており、復元セクションで作業しています。これは私のテーブルです:

CREATE TABLE "SBOOKS"."DEV_CORPUS" 
   (    "CORPUSID" NUMBER(9,0) NOT NULL ENABLE, 
    "CORPUS_NAME" VARCHAR2(768 BYTE) NOT NULL ENABLE, 
    "CORPUSLASTSYNC" DATE, 
     PRIMARY KEY ("CORPUSID")

復元クラスでは、テーブルで主キーを探したいと思います。存在する場合は行を更新し、そうでない場合は行を挿入します。
問題は、クラスからパラメーターを渡す必要があることです (パラメーターはどのテーブルにも存在しません)。どうすればこれを行うことができますか? あなたの提案は何ですか?準備されたステートメントまたは何を使用していますか?そしてどうやって?ソースへの例またはリンクを提供してください。

詳細: 私は oracle sql 開発者と Java netbeans を使用しています。

編集: コマンドウィンドウでこれを試しています:

  MERGE INTO dev_corpus a  
  USING (SELECT corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain FROM dual WHERE corpusId = 1000156 AND corpus_name = 'sahar' AND corpusdesc = 'sahaaaaa' AND corpusimageids IS NULL AND rocf1 IS NULL AND rocf2 IS NULL AND rocf3 IS NULL AND rocc1 IS NULL AND rocc2 IS NULL AND rocc3 IS NULL AND corpusactive IS NULL AND corpusrunfrequency IS NULL AND corpuslastrun IS NULL AND corpuslastsync IS NULL AND rocsettingid IS NULL AND corpusaffinity IS NULL AND corpusterms IS NULL AND corpusdomain IS NULL) incoming 
  ON (a.corpusid = incoming.corpusid )  
  WHEN MATCHED THEN 
  UPDATE SET corpusid = incoming.corpusid , corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain 
  WHEN NOT MATCHED THEN 
  INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) 
  VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain)

これは実際のテーブルです:

CREATE TABLE "SBOOKS"."DEV_CORPUS" 
   (    "CORPUSID" NUMBER(9,0) NOT NULL ENABLE, 
    "CORPUS_NAME" VARCHAR2(768 BYTE) NOT NULL ENABLE, 
    "CORPUSDESC" VARCHAR2(4000 BYTE), 
    "CORPUSIMAGEIDS" VARCHAR2(768 BYTE), 
    "ROCF1" FLOAT(63), 
    "ROCF2" FLOAT(63), 
    "ROCF3" FLOAT(63), 
    "ROCC1" FLOAT(63), 
    "ROCC2" FLOAT(63), 
    "ROCC3" FLOAT(63), 
    "CORPUSACTIVE" NUMBER(3,0), 
    "CORPUSRUNFREQUENCY" NUMBER(3,0), 
    "CORPUSLASTRUN" DATE, 
    "CORPUSLASTSYNC" DATE, 
    "ROCSETTINGID" NUMBER(3,0), 
    "CORPUSAFFINITY" NUMBER(3,0), 
    "CORPUSTERMS" VARCHAR2(4000 BYTE), 
    "CORPUSDOMAIN" NUMBER(3,0), 
     PRIMARY KEY ("CORPUSID")

このエラーがスローされます:

Error at Command Line:2 Column:644
Error report:
SQL Error: ORA-00904: "CORPUSDOMAIN": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:

.

何が欠けているのかわからない。何か考えはありますか?

ありがとう!

EDIT2 : 最後に、これは comand win で機能します:

MERGE INTO dev_corpus a
  USING (SELECT 1000156 corpusid, 'sss2' corpus_name, 'sahaaaaaar' corpusdesc, null corpusimageids, null rocf1, null rocf2, null rocf3, null rocc1, null rocc2, null rocc3, null corpusactive, null corpusrunfrequency, null corpuslastrun, null corpuslastsync, null rocsettingid, null corpusaffinity, null corpusterms, null corpusdomain FROM dual) incoming 
  ON (a.corpusid = incoming.corpusid )  
  WHEN MATCHED THEN 
  UPDATE SET corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain 
  WHEN NOT MATCHED THEN 
  INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) 
  VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain)

しかし、これはJavaクラスnoootで更新の場合に機能しますが、挿入の場合は機能します。更新の場合、エラーはスローされず、DB からレコードを削除するまでフリーズしてから挿入されるため、更新はありません。このコードに何か問題がありますか?

preparedStatement = dbConnection.prepareStatement("MERGE INTO dev_corpus a " +
                              "USING (SELECT ? corpusid, ? corpus_name, ? corpusdesc, ? corpusimageids, ? rocf1, ? rocf2, ? rocf3, ? rocc1, ? rocc2, ? rocc3, ? corpusactive, ? corpusrunfrequency, ? corpuslastrun, ? corpuslastsync, ? rocsettingid, ? corpusaffinity, ? corpusterms, ? corpusdomain FROM dual) incoming " +
                              "ON (a.corpusid = incoming.corpusid ) " +
                              "WHEN MATCHED THEN " +
                              "UPDATE SET corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain " +
                              "WHEN NOT MATCHED THEN " +
                              "INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) " +
                              "VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain)");

ありがとう!

4

2 に答える 2

4

最後に、これは機能します!、SQL コマンドのクエリは次のとおりです。

MERGE INTO dev_corpus a
  USING (SELECT 1000156 corpusid, 'sss2' corpus_name, 'sahaaaaaar' corpusdesc, null corpusimageids, null rocf1, null rocf2, null rocf3, null rocc1, null rocc2, null rocc3, null corpusactive, null corpusrunfrequency, null corpuslastrun, null corpuslastsync, null rocsettingid, null corpusaffinity, null corpusterms, null corpusdomain FROM dual) incoming 
  ON (a.corpusid = incoming.corpusid )  
  WHEN MATCHED THEN 
  UPDATE SET corpus_name = incoming.corpus_name , corpusdesc = incoming.corpusdesc , corpusimageids = incoming.corpusimageids , rocf1 = incoming.rocf1 , rocf2 = incoming.rocf2 , rocf3 = incoming.rocf3 , rocc1 = incoming.rocc1 , rocc2 = incoming.rocc2 , rocc3 = incoming.rocc3 , corpusactive = incoming.corpusactive , corpusrunfrequency = incoming.corpusrunfrequency , corpuslastrun = incoming.corpuslastrun , corpuslastsync = incoming.corpuslastsync , rocsettingid = incoming.rocsettingid , corpusaffinity = incoming.corpusaffinity , corpusterms = incoming.corpusterms , corpusdomain = incoming.corpusdomain 
  WHEN NOT MATCHED THEN 
  INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) 
  VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain)

pstmtを使用したJavaコードは次のとおりです。

preparedStatement = dbConnection.prepareStatement("MERGE INTO dev_corpus a " +
                              "USING (SELECT ? corpusid, ? corpus_name, ? corpusdesc, ? corpusimageids, ? rocf1, ? rocf2, ? rocf3, ? rocc1, ? rocc2, ? rocc3, ? corpusactive, ? corpusrunfrequency, ? corpuslastrun, ? corpuslastsync, ? rocsettingid, ? corpusaffinity, ? corpusterms, ? corpusdomain FROM dual) incoming " +
                              "ON (a.corpusid = incoming.corpusid) " +
                              "WHEN MATCHED THEN " +
                              "UPDATE SET a.corpus_name = incoming.corpus_name , a.corpusdesc = incoming.corpusdesc , a.corpusimageids = incoming.corpusimageids , a.rocf1 = incoming.rocf1 , a.rocf2 = incoming.rocf2 , a.rocf3 = incoming.rocf3 , a.rocc1 = incoming.rocc1 , a.rocc2 = incoming.rocc2 , a.rocc3 = incoming.rocc3 , a.corpusactive = incoming.corpusactive , a.corpusrunfrequency = incoming.corpusrunfrequency , a.corpuslastrun = incoming.corpuslastrun , a.corpuslastsync = incoming.corpuslastsync , a.rocsettingid = incoming.rocsettingid , a.corpusaffinity = incoming.corpusaffinity , a.corpusterms = incoming.corpusterms , a.corpusdomain = incoming.corpusdomain " +
                              "WHEN NOT MATCHED THEN " +
                              "INSERT (corpusid, corpus_name, corpusdesc, corpusimageids, rocf1, rocf2, rocf3, rocc1, rocc2, rocc3, corpusactive, corpusrunfrequency, corpuslastrun, corpuslastsync, rocsettingid, corpusaffinity, corpusterms, corpusdomain) " +
                              "VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpusdesc, incoming.corpusimageids, incoming.rocf1, incoming.rocf2, incoming.rocf3, incoming.rocc1, incoming.rocc2, incoming.rocc3, incoming.corpusactive, incoming.corpusrunfrequency, incoming.corpuslastrun, incoming.corpuslastsync, incoming.rocsettingid, incoming.corpusaffinity, incoming.corpusterms, incoming.corpusdomain)");

質問セクションにテーブルの作成があります。誰かの役に立てば幸いです。:)

于 2013-07-18T16:23:20.597 に答える
1

Oracle を使用している場合は、MERGEステートメントに集中する必要がありINSERT ... ON DUPLICATE KEYます。これは Oracle では機能しません。

これが唯一の問題かどうかはわかりませんが、MERGE投稿したものにはいくつかの構文エラーがあります。

MERGE INTO dev_corpus a
USING (SELECT * FROM dual WHERE (corpusid=?, corpus_name=?, corpuslastsync=?)
                                ^^^^^^^^^^^^^^^^^^^^^^ (1)
ON (a.corpusid = incoming.corpusid )
WHEN MATCHED THEN
UPDATE SET (a.corpus_name = incoming.corpus_name AND a.corpuslastsync = incoming.corpuslastsync )
            ^^^^^^^^^^^^^^^^^^ (2)
WHEN NOT MATCHED THEN
INSERT (a.corpusid, a.corpus_name, a.corpuslastsync)
VALUES (incoming.corpusid, incoming.corpus_name, incoming.corpuslastsync)

問題 (1): 閉じていない括弧があり、さらに複数のWHERE条件をANDコンマではなく で区切る必要があります。これは、水平スクロールを必要としないようにインデントされた修正版です。

USING (
  SELECT * FROM dual
  WHERE (corpusid=? AND corpus_name=? AND corpuslastsync=?))

この場合、条件を囲む括弧WHEREはオプションであるため、これも機能します。

USING (
  SELECT * FROM dual
  WHERE corpusid=? AND corpus_name=? AND corpuslastsync=?)

問題 (2): の後の括弧。SETここでは、. の代わりにコンマが必要ですAND。このように表示されます (上記のように、横スクロールしなくても読めるようにインデントを入れています)

UPDATE SET
  a.corpus_name = incoming.corpus_name,
  a.corpuslastsync = incoming.corpuslastsync

これで構文エラーが解決されるはずですが、もちろん、結果が期待どおりになるという保証はありません:)

最後に、コメントで述べたように、テスト値 (パラメーターではなく) を使用して SQLPlus または SQL Developer でこれを試してください。そうすれば、デバッグがはるかに簡単になります。MERGE動作が正しくなったら、それを Java コードに移動してパラメーター化できます。頑張ってください!


更新された質問の補遺

まず第一に、これを解決するために SQL Developer を使用しているという朗報です。上記の最後の段落は無視してください:)

次に、 where には が含まれますAND corpuslastsync = nullIS NULLnull をチェックするときは、 ではなくが必要です= NULL

... AND corpuslastsync IS NULL

最後に、最近の試行で発生している特定のエラーは、次の行のエイリアスが原因であると確信しています。

INSERT (a.corpusid, a.corpus_name, a.corpuslastsync)

代わりにこれを試してください:

INSERT (corpusid, corpus_name, corpuslastsync)

dev_corpusOracle は、ここで名前が付けられた列がとしてエイリアス化されたテーブルに属していることを認識していますa

于 2013-07-17T18:51:30.480 に答える