我需要创建一个oracle表,如果它在Oracle数据库中不存在,并且如果表存在则不执行任何操作,那么为此,我编写了一个匿名块,如果我触发该查询,则在SQL Developer中工作两次或三次我在sql开发人员中没有任何异常。这是我写的以下查询 -
public static final String DATABASE_TABLE = "LnPData";
public static final String CREATE_SQL = "DECLARE " +
"t_count INTEGER; " +
"v_sql VARCHAR2(1000) := 'create table " +DATABASE_TABLE +
"(ID number(10,0), " +
"CGUID VARCHAR(255), " +
"PGUID VARCHAR(255), " +
"SGUID VARCHAR(255), " +
"USERID VARCHAR(255), " +
"ULOC VARCHAR(255), " +
"SLOC VARCHAR(255), " +
"PLOC VARCHAR(255), " +
"ALOC VARCHAR(255), " +
"SITEID VARCHAR(255), " +
"PRIMARY KEY ( ID ))'; " +
"BEGIN " +
"SELECT COUNT(*) " +
"INTO t_count " +
"FROM user_tables " +
"WHERE table_name = '" +DATABASE_TABLE + "'; " +
"IF t_count = 0 THEN " +
"EXECUTE IMMEDIATE v_sql; " +
"END IF; " +
"END; ";
我在我的java代码中执行上面这样的sql查询 - 第一次运行我的程序时,表被创建,但第二次当我尝试运行相同的程序时,我总是得到以下异常。
// get the connection
LnPDataConstants.DB_CONNECTION = getDBConnection();
LnPDataConstants.STATEMENT = LnPDataConstants.DB_CONNECTION.createStatement();
LnPDataConstants.STATEMENT.executeUpdate(LnPDataConstants.CREATE_SQL);
我总是得到sql异常 -
SQL Error: ORA-00955: name is already used by an existing object
00955. 00000 - "name is already used by an existing object"
为什么会出现在Java代码中的任何建议?
P.S。我不想放弃表格
更新的代码: -
public static final String CREATE_SQL = "CREATE TABLE IF NOT EXISTS " +DATABASE_TABLE +
"(ID number(10,0), " +
" CGUID VARCHAR(255), " +
" PGUID VARCHAR(255), " +
" SGUID VARCHAR(255), " +
" USERID VARCHAR(255), " +
" ULOC VARCHAR(255), " +
" SLOC VARCHAR(255), " +
" PLOC VARCHAR(255), " +
" ALOC VARCHAR(255), " +
" SITEID VARCHAR(255), " +
" PRIMARY KEY ( ID ))";
答案 0 :(得分:4)
在PL / SQL中使用此脚本:
DECLARE cnt NUMBER;
BEGIN
SELECT count(*) INTO cnt FROM all_tables WHERE table_name = '<TABLE-NAME>';
IF cnt = 0 THEN
EXECUTE IMMEDIATE 'CREATE TABLE <TABLE-NAME>(<COLUMN-DEFINITIONS>)';
END IF;
END;
用适当的值替换<TABLE-NAME>
和<COLUMN-DEFINITIONS>
。
答案 1 :(得分:3)
我也回答了你的其他帖子。在这里,您似乎已经发现在查询中有一个支架。
这里的问题很容易解决:
如果检查user_tables,您将看到未使用双引号创建的表始终为大写 - 如果您希望使用CREATE TABLE "tAbLeNamE"(test number)
区分大小写的表。您选择表作为“LnPData”,表格包含一个LNPDATA条目。
解决方案是将LnPData更改为大写或只更改查询的where子句:
"WHERE table_name = UPPER('" +DATABASE_TABLE + "'); " +
答案也属于您的其他问题java.sql.SQLException: ORA-00904。
答案 2 :(得分:2)
首先,你为什么需要这样做?您的代码暗示您正在创建多个具有不同名称的相同表。这听起来像是我最糟糕的噩梦。
如果我错了,你只是创建一个表,那就不要在代码中执行。首先在数据库中执行,然后完成。如果我是正确的,那么规范化表格。添加一个额外的列username
(您已经拥有userid
?)或类似内容,并将具有此格式的所有数据插入到单个表中。此表再次可以创建,无需动态执行。
如果你进行规范化,你可能需要更多的索引,但是看起来好像你可能会遗漏某些索引,当你从这个表中选择时,你真的总是会有id
吗?
如果你觉得你真的 在应用程序代码中执行此操作,那么就像Matt suggests一样,不要在应用程序代码中执行此操作。您需要为正在运行的架构授予create table权限。
创建具有这些权限的用户并添加存储过程以对该用户执行此操作。然后为该模式授予应用程序模式执行权限。
您还应该使用dbms_assert
package来清理输入。
最后,Eggi is correct您需要大写对象名称,但默认情况下dbms_assert
执行此操作。
您还应注意,拨打user_tables
或all_tables
会对性能产生影响。另一个原因是不在申请中这样做。
将所有内容放在一起,您将得到一个类似于此的存储过程:
create or replace procedure create_the_table
( pTableName varchar2 ) is
declare
-- Sanitize the input.
l_table_name := dbms_assert.simple_sql_name(pTableName);
l_exists number;
begin
select count(*)
into l_exists
from all_tables
where owner = 'MY_APPLICATION_SCHEMA'
and table_name = l_table_name
;
if l_exists = 0 then
execute immediate 'create table ' || l_table_name ||
' ( ID number(10,0),
CGUID VARCHAR(255),
PGUID VARCHAR(255),
SGUID VARCHAR(255),
USERID VARCHAR(255),
ULOC VARCHAR(255),
SLOC VARCHAR(255),
PLOC VARCHAR(255),
ALOC VARCHAR(255),
SITEID VARCHAR(255),
PRIMARY KEY ( ID )
)';
-- need to grant permissions so that we can check if this
-- is run again.
execute immediate 'grant select on ' || l_table_name ||
' to my_application_user';
end if;
end;
/
然后
grant execute on create_the_table to my_application_user;
并致电......
begin
my_create_table_user.create_the_table(table_name);
end;
基本上我的建议是:
答案 3 :(得分:0)
如果有人遇到类似的问题,这应该会有所帮助:
Oracle版本:
DECLARE
NCOUNT NUMBER;
V_SQL LONG;
BEGIN
SELECT COUNT(*)
INTO NCOUNT
FROM USER_OBJECTS
WHERE OBJECT_NAME = 'tableName';
IF (NCOUNT <= 0) THEN
V_SQL := ' CREATE TABLE tableName(
column1,
column2,
column3,
column4,
column5,
column6 VARCHAR2(2))';
EXECUTE IMMEDIATE V_SQL;
END IF;
END;
Java版:
String sqlStanging = "DECLARE "
+"NCOUNT NUMBER; "
+"V_SQL LONG; "
+"BEGIN "
+"SELECT COUNT(*) INTO NCOUNT FROM USER_OBJECTS WHERE OBJECT_NAME = 'tableName' ;"
+"IF(NCOUNT <= 0) "
+"THEN "
+"V_SQL:=' "
+"CREATE TABLE tableName"
+"("
+" column1, "
+" column2, "
+" column3, "
+" column4, "
+" column5, "
+" column6 VARCHAR2(2))';"
+"EXECUTE IMMEDIATE V_SQL ;"
+"END IF; "
+"END; ";