如何通过从数据库中获取表名和列名来更新 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 表?的主要内容,如果未能解决你的问题,请参考以下文章

获取模式中所有表名和列名的查询[重复]

oracle中已经知道一个具体值,如何根据该值查询出含有该值的表名和列名?

如何从sql查询中提取表名和列名?

Oracle 获取表名和某个表的所有列名

通过从列表中选择列名来绑定行?

sql 获取包含给定字符串的表名和列名