如果表不存在,则插入其他表
Posted
技术标签:
【中文标题】如果表不存在,则插入其他表【英文标题】:If table doesn't exists then insert into other table 【发布时间】:2015-09-17 08:23:56 【问题描述】:我有这样的程序:
create or replace procedure smth
is
some_variable varchar(2;
begin
insert into **table**(col1,col2) (Select id,'text' from TABLE2),
insert into table(col1,col2) (Select id,'text' from TABLE3)
我想要做的是为这种情况添加一些 if-else(或 smoething else)语句,例如。表 2 不存在。 如果 Table2 不存在,则从 DUAL 插入 table ('smth','nameoftable')。我确切地知道 table2 的名称是什么。 (但由于某种原因,该表可能会从数据库中删除)。
如果我能这样做就太好了:
insert into **table**(col1,col2) if table2 doesn't exist then Select (1,'TABLE2') else (Select id,'text' from TABLE2),
if table3 doesn't exist then Select (1,'TABLE3') insert into table(col1,col2) else (Select id,'text' from TABLE3)
针对每种情况。
编辑
insert into **table**(col1,col2) (Select id,'text' from TABLE2),
insert into table(col1,col2) (Select id,'text' from TABLE3)
insert into table(col1,col2) (Select id,'text' from TABLE4)
insert into table(col1,col2) (Select id,'text' from TABLE4)
假设 table3 不存在,那么我想要的只是 INSERT into table ( Select 'text','text2' from dual。
【问题讨论】:
这是一个非常奇怪的案例;一张桌子不在那里,然后只需使用另一张桌子。在存储过程中使用 INSERT 语句,当表被删除时,您的过程将变得无效。因此,您需要动态 SQL,因此 DBMS 不会看到该表在过程中使用。 你好,我没有准确地说出我的期望。如果表不存在,则插入'text',text2' FROM DUAL 【参考方案1】:为了得到你想要的,你需要两件事
-
查找表是否存在:可以查询
user_tables
对
table_name
列,如果程序正在从表中读取
相同的架构
你需要使用动态sql,因为如果表不存在
使用静态 pl/sql 你会得到错误 PL/SQL: ORA-00942: table or
视图不存在,因为当 oracle 编译该过程时
找不到表。
动态plsql的一个例子是
sql_stmt := 'insert into table(col1,col2) (Select id,''text'' from ' || <the right table_name> || ')';
EXECUTE IMMEDIATE sql_stmt;
这里是dynamic sql 的 oracle 文档的链接。
编辑 在你澄清之后,可以像这样一个过程结束:
create or replace procedure insert_from_dual_if_not_exists(table_name_in in varchar2)
begin
.....
if table_exists('<table_name>') then
sql_stmt := 'insert into table(col1,col2)' (Select id,''text'' from ' || <the right table_name> || ')';
else
sql_stmt := 'insert into table(col1,col2)' (Select ''text1'',''text2'' from dual )';
end if;
EXECUTE IMMEDIATE sql_stmt;
end;
并调用insert_from_dual_if_not_exists
而不是你简单的插入;您还必须创建一个过程(或一个简单的语句)来告诉您的代码是否存在表。
【讨论】:
你好,我没有准确地说出我的期望。如果表不存在,则插入'text',text2' FROM DUAL【参考方案2】:您可以查询 USER_TABLES 视图以查看该表是否实际存在。并且,您必须(ab)使用 EXECUTE IMMEDIATE 来执行动态 sql。
例如,
SELECT COUNT(*)
INTO v_cnt
FROM USER_TABLES
WHERE TABLE_NAME = '<TABLE_1>';
v_sql := INSERT INTO TABLE(col1,col2).. SELECT id,'text' FROM ';
IF v_cnt > 0
THEN
v:sql := v_sql || TABLE_1;
EXECUTE IMMEDIATE v_sql;
ELSE
v:sql := v_sql || TABLE_2;
EXECUTE IMMEDIATE v_sql;
END IF;
UPDATE OP 希望动态使用 table_name 从多个表中插入另一个表。
循环遍历所有表,并在动态sql中使用table_name作为变量。
例如,
FOR i IN SELECT table_name FROM user_tables WHERE table_name <> 'inserting_table'
LOOP
v_sql := 'INSERT INTO inserting_table SELECT column_list FROM' || i.table_name;
EXECUTE IMMEDIATE v_sql;
END LOOP;
【讨论】:
它会工作,但我有太多的表(大约 20-25),然后我必须为每个表重复该代码。我必须将所有内容插入到 1 个表中,但从大约 20-25 个表中(其中一些可能不存在......)。我没有准确地说,但是如果表不存在,那么我想插入 TABLE ('text','1') - 一些明确的数据。 再一次,我犯了一些错误。 : 如果表不存在,则插入 'text',text2' FROM DUAL 这行不通。如果table_1
不存在,您的块将无法编译。只有table_1
和table_2
都存在时,代码才会编译。您需要使用动态 SQL。
@maciek2791 在这种情况下,您需要使用动态 sql 遍历所有这些表。查看更新。
@JustinCave 是的,它会抛出静态 sql 的编译错误。编辑为使用动态 sql。【参考方案3】:
您可以尝试这种执行动态 sql 的过程,其中包含匿名块并使用 sqlcode
捕获异常
create or replace procedure testproc
is
v_sql varchar2(4000) := q'[
declare
begin
insert into table3 values(1,2);
end;]';
begin
execute immediate v_sql;
exception when others
then if
sqlcode='-6550' then
insert into **table** values()
end if;
end testproc;
【讨论】:
以上是关于如果表不存在,则插入其他表的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 模型 - 如果数据库表不存在则返回 null