PL/SQL - 仅当记录不存在时才插入记录

Posted

技术标签:

【中文标题】PL/SQL - 仅当记录不存在时才插入记录【英文标题】:PL/SQL - insert record only if record does not exist 【发布时间】:2013-09-29 15:23:10 【问题描述】:

我的问题没有得到很好的答案,我知道该怎么做。只有当记录不存在时,您才会将记录插入到表中:

1) 在您的架构上创建或替换函数(这是检查 2 个参数,您可以将其设置为检查任意多个)PL/SQL 非常具体,按照我编写的复制和粘贴应该可以成功编译。需要多次尝试才能使语法正确。此函数检查要写入的表,以及要检查的相应列名是否已经一起存在。

create or replace function Found(
   var1 type, 
   var2 type)
 return number 
 is             
   numberOfSelectedRows number := 0;
 begin 
   select count(*) 
     into numberOfSelectedRows 
     from TABLE 
    where COLUMN_NAME = var1 
      and COLUMN_NAME = var2;

   return numberOfSelectedRows;
 end Found;

2) 编写 java 来执行 pl/sql 函数:这是使用 NetBeans 完成的。单击该按钮时,它将从其他表中加载 FORM 数据,并确定要插入的表中是否已存在该记录。

  try              
       DriverManager.registerDriver (new oracle.jdbc.OracleDriver());   
       con = DriverManager.getConnection(""+LOGIN.url+"");

       String str1 = jTextField_VariableName.getText();
       String str2 = jTextField_VariableName.getText();

       String q = "insert into TABLE (var1 type, var2 type) VALUES ('"+str1+"', '"+str2+"')" ; 

       cs = con.prepareCall("?=call Found(?, ?)");              // cs = CallableStatement - defined in class  CallableStatement cs = null; 

       cs.setString(2, str1);
       cs.setString(3, str2);
       cs.registerOutParameter(1, Types.INTEGER);
       cs.execute();

       if(cs.getInt(1)>= 1)
            
            JOptionPane.showMessageDialog(null, " this record already exists");
            
       else 
           
            try
                DriverManager.registerDriver (new oracle.jdbc.OracleDriver());  
                con = DriverManager.getConnection(""+LOGIN.url+"");

                pst = con.prepareStatement(q);

                pst.execute();

                catch(SQLException ex)  Logger.getLogger(REGISTER_STUDENT.class.getName()).log(Level.SEVERE, null, ex);
           

       catch (SQLException ex) Logger.getLogger(REGISTER_STUDENT.class.getName()).log(Level.SEVERE, null, ex);     

【问题讨论】:

你可以看看OracleMERGE声明。 【参考方案1】:

只要做:

String q = 
"insert into TABLE (var1, var2) " +
"SELECT ?, ? FROM dual "+
"WHERE NOT EXISTS(
"   SELECT 1 FROM table
"   WHERE var1 = ? AND var2 = ? )";
pst = con.prepareStatement(q);
pst.setString( 1, str1 );
pst.setString( 2, str2 );
pst.setString( 3, str1 );
pst.setString( 4, str2 );
int status = pst.execute();
if( status > 0 )
    System.out.println("New row inserted");
else
    System.out.println("Row already exists, insert skipped");

--- 编辑 --- 大多数 DBMS 都支持INSERT INTO .... SELECT .... 语法,请参阅此链接了解更多详细信息:http://www.w3schools.com/sql/sql_insert_into_select.asp 它只是从一个表中选择行并将结果插入到另一个表中。dual 是 Oracle 数据库上的一个“虚拟”表,它有一列一行,下面是一个示例: http://www.sqlfiddle.com/#!4/d41d8/11 在我们需要创建具有某些值的行的许多情况下,双表很有帮助。在其他数据库中——尤其是在 mysql 和 PostGreSQL 中——这可以使用简单的SELECT x, y 来完成,不幸的是 Oracle 不支持这种语法,我们必须使用 SELECT x, y FROM dual。 在我们的例子中,它用于创建我们想要插入到表中的一行值:

INSERT INTO table
SELECT x, y FROM dual;

但是,只有在满足某些条件时才必须插入行 - 此条件在 WHERE 子句中描述:

INSERT INTO table
SELECT x, y FROM dual
WHERE NOT EXISTS( 
   SELECT 1 FROM table
   WHERE var1 = X and var2 = Y
)

如果子查询SELECT 1 FROM ... 返回一行(存在一行) - 那么条件NOT EXISTS ... 为假,SELECT x, y 不返回任何内容(空结果集),并且没有任何内容插入到表中。另一方面,当子查询没有找到任何东西时,整个条件为真,SELECT x,y 语句创建一个包含两列的行:X+Y,并将此行插入到表中。 在我们使用的 PreparedStatement(在 java 代码中)中?而不是 X,Y 变量 - ?是placeholder(替换变量)。此链接:http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html 详细描述了 PreparedStatement 的工作原理以及如何使用替换变量。 简单地说 - 我们的查询有 4 个占位符 ?

 insert into TABLE (var1, var2)  
 SELECT ?, ? FROM dual  
 WHERE NOT EXISTS(
    SELECT 1 FROM table
    WHERE var1 = ? AND var2 = ? ) ;

和 setXXX 语句将值绑定到连续的占位符:

pst.setString( 1, str1 );
pst.setString( 2, str2 );
pst.setString( 3, str1 );
pst.setString( 4, str2 );

因此,在将值绑定到替换标记之后,查询(最终执行)如下所示:

 INSERT INTO TABLE (var1, var2)  
 SELECT 'str1', 'str2' FROM dual  
 WHERE NOT EXISTS(
    SELECT 1 FROM table
    WHERE var1 = 'str1' AND var2 = 'str2' ) ;

【讨论】:

感谢 Kordirko,我之前问过这个问题,并得到了一些聪明的评论,关于我应该如何祈祷它起作用。我在 PL/SQL 方面几乎没有受过培训,你能推荐一个显示这种表示法的好网站吗?谢谢 @user2826554 我添加了一个解释,希望对您有所帮助 好的,但是关于 VALUES 的部分在哪里插入?知道显示此符号的好页面吗? 看看这个链接:docs.oracle.com/cd/B28359_01/server.111/b28286/…,examples 部分。它是 Oracle 文档(非常详细,有时甚至过于详细且难以阅读),但那里有很好的 INSERT INTO ... VALUESINSERT INTO ... subquery 命令示例。

以上是关于PL/SQL - 仅当记录不存在时才插入记录的主要内容,如果未能解决你的问题,请参考以下文章

仅当 Access 2007 中不存在时才添加记录

如果不存在则插入数据的过程pl sql

仅当行不存在时才插入 SQL

仅当表中不存在两个 id 的组合时才将值插入表中

Access97:如果不存在则插入

通知调用方不存在记录的 DML PL/SQL 过程