2013-07-17 92 views
0

我有一个备份实用程序,workig恢复部分。这是我的表:Oracle MERGE和准备语句

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") 

在恢复类,我想寻找在表的主键,如果存在则更新该行,如果没有则插入一行。
现在的问题是我需要从类中传递参数(它们不存在于任何表中),我该怎么做?你的建议是什么?使用preparedstatment还是什么?如何?请举例或链接来源。

更多信息: 我使用的是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胜:

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工作,但如果它是一个插入情况下,它会奏效。在更新的情况下,它不会抛出任何错误,只是冻结,直到我从数据库中删除记录,然后插入它,所以没有更新!你在这段代码中发现了什么错误?

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)"); 

谢谢!

+0

目前还不清楚您是否使用MySQL或Oracle。你在使用其中一个还是另一个?或两者?如果你使用Oracle,你需要'MERGE',如果你使用MySQL,你需要'INSERT ... ON DUPLICATE KEY'。至于语法问题,我发现最好是在命令窗口中查找查询,然后当它看起来很好时,可以在Java代码中实现它。 –

+0

@Ed Gibbs:对不起,我的不好,oracle sql开发人员。请参阅上面的edites代码。 – user149855

回答

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来工作了这一点!无视我上面的最后一段:)

二,你的地方包括AND corpuslastsync = null。当空检查,你需要IS NULL,不= NULL

... AND corpuslastsync IS NULL 

最后,我敢肯定,你与你的最新尝试获取特定的错误是由于该线路上的别名:

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

试试这个:

INSERT (corpusid, corpus_name, corpuslastsync) 

甲骨文知道,这里指定的列属于dev_corpus表,别名为a

+0

非常感谢你,但仍然没有工作:(。plz看编辑的问题 – user149855

+1

你可以尝试删除'UPDATE'部分'a.'别名吗?而不是'SET a.corpusid = incoming.corpusid等'尝试'SET corpusid =传入。corpusid'。 –

+0

thans再次,但仍然无法正常工作,但另一个错误,请参阅编辑的查询。 – user149855

1

最后这个作品!所以这里是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) 

这里是使用Java代码数PreparedStatement pstmt:

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)"); 

你有问题部分的创建表,希望它能帮助别人! :)