如何通过从数据库中获取表名和列名来更新 Oracle 表?
Posted
技术标签:
【中文标题】如何通过从数据库中获取表名和列名来更新 Oracle 表?【英文标题】:How to update Oracle table by getting table name and column names from database? 【发布时间】:2015-11-11 07:18:05 【问题描述】:我想制作一个表格来更新我的 oracle 数据库中多个表中的一些数据,我必须在不同的组织中使用这个表格。
我要更新的表我将通过使用此脚本从表 dba_tab_columns 中获得
SELECT table_name, column_name
FROM dba_tab_columns
WHERE upper(column_name) LIKE 'PATIENT%'
我的问题是,如果我运行上面的脚本,我会得到一组不可预知的数据,我的意思是有些组织的表比其他组织多,而有些组织的表相似但名称不同。所以我想先从我的表单中用上面的脚本读取所有的表名和列名,然后用下面的脚本更新那个表。
UPDATE <target_table_name>
SET <target_column_name> = :BLK_TOOLS.PATIENT_ID1
WHERE <target_column_name> = :BLK_TOOLS.PATIENT_ID2;
怎么做?
我尝试执行以下数据库过程,但它不起作用。
CREATE OR REPLACE PROCEDURE HIMS.merge9898
(PID1 NUMBER, PID2 VARCHAR2) IS
TYPE tab_array IS TABLE OF VARCHAR2(40)
INDEX BY binary_integer;
TYPE col_array IS TABLE OF VARCHAR2(40)
INDEX BY binary_integer;
v_dml_str VARCHAR2 (200);
v_tab_array tab_array;
v_col_array col_array;
BEGIN
SELECT table_name,column_name BULK COLLECT
INTO v_tab_array,v_col_array
FROM sys.dba_tab_columns
where upper(column_name) like'PATIENT%' and global_stats='YES';
FOR i IN v_tab_array.first..v_tab_array.last LOOP
v_dml_str := 'UPDATE '
|| v_tab_array(i)
|| ' SET '||v_col_array(i)||' = :PID1'
|| ' WHERE '||v_col_array(i)||' = :PID2';
EXECUTE IMMEDIATE v_dml_str USING PID1, PID2;
END LOOP;
END;
/
并显示此错误
LINE/COL ERROR
-------- -----------------------------------------------------------------
12/3 PL/SQL: SQL Statement ignored
14/12 PL/SQL: ORA-00942: table or view does not exist
【问题讨论】:
你需要动态sql -execute immediate
在您的示例中emp_rec.column_name
是什么?
sry 错了没有emp_rec
@Tatiana 我尝试做“数据库过程”,所以我会从表单中调用它,但仍然无法正常工作。有什么想法吗?
您根据dba_tab_columns
信息进行更新。但是您可能无权更新该列表中的某些表。如果你没有权利这样做 - 你会得到错误 - table or view does not exist
。使用all_tab_columns
表。此处存储您拥有权限的所有对象
【参考方案1】:
类似的东西。
BEGIN
FOR tab IN (select table_name,column_name from dba_tab_columns where upper(column_name) like'PATIENT%') LOOP
EXECUTE IMMEDIATE 'UPDATE '||tab.table_name||
' SET '|| tab.column_name ||' = '|| :BLK_TOOLS.PATIENT_ID1 ||
' WHERE '||tab.column_name ||' = '|| :BLK_TOOLS.PATIENT_ID2;
END LOOP;
END;
或
BEGIN
FOR tab IN (select table_name,column_name from dba_tab_columns where upper(column_name) like'PATIENT%') LOOP
EXECUTE IMMEDIATE 'UPDATE '||tab.table_name||
' SET '|| tab.column_name ||' = :1
WHERE '||tab.column_name ||' = :2'
USING :BLK_TOOLS.PATIENT_ID1 ,:BLK_TOOLS.PATIENT_ID2 ;
END LOOP;
END;
不确定在动态 sql 中使用绑定变量
【讨论】:
第 8 行第 9 列出现错误 103 在预期以下情况之一时遇到符号“IMMEDIATE”::=.(@%; 符号“.= 被插入到“IMMEDIATE”之前以计数。 我不确定是否将绑定变量与立即执行一起使用。但尝试更新的答案。最好发布错误号,而不仅仅是描述 必须是这样的:EXECUTE IMMEDIATE 'UPDATE '||tab.table_name|| ' SET '|| tab.column_name ||' = :p1 WHERE '||tab.column_name ||' = :p2' USING BLK_TOOLS.PATIENT_ID1, BLK_TOOLS.PATIENT_ID2;
@WernfriedDomscheit 据我了解 BLK_TOOLS.PATIENT_ID1 是与:
标记一起使用的绑定变量。所以不确定它是否会像这样工作
@Tatiana 不,它不是(至少对于 Oracle 而言)。语法必须在我的评论中给出。以上是关于如何通过从数据库中获取表名和列名来更新 Oracle 表?的主要内容,如果未能解决你的问题,请参考以下文章