Oracle函数将列名硬编码为参数

Oracle函数将列名硬编码为参数,oracle,function,Oracle,Function,我有两个表具有相同的集合列名(52+coulmns)。我需要编写一个Oracle函数来比较这些列之间是否有任何记录被更改EMP_ID是主键 我试图使用下面的函数,但它给出的结果不正确, 我这样称呼函数: get_data_change (emp_id, 'DEPT_NAME'); get_data_change (emp_id, 'PHONE_NUMBER'); 我创建的函数: CREATE OR REPLACE function get_data_change ( in_emp_i

我有两个表具有相同的集合列名(52+coulmns)。我需要编写一个Oracle函数来比较这些列之间是否有任何记录被更改<代码>EMP_ID是主键

我试图使用下面的函数,但它给出的结果不正确, 我这样称呼函数:

get_data_change (emp_id, 'DEPT_NAME');
get_data_change (emp_id, 'PHONE_NUMBER');
我创建的函数:

CREATE OR REPLACE function  get_data_change (
    in_emp_id varchar2, in_Column_Name varchar2)
return char is

  v_data_changed char;
begin
  select eid, in_Column_Name
    into v_table1_eid, v_table1_Column_Value
    from table 1
   where eid=in_emp_id;

  Select eid, in_Column_Name
    into v_table2_eid, v_table2_Column_Value
    from table 2
   where eid = in_emp_id;


  if ( v_table2_Column_Value != v_table1_Column_Value) 
  then 
    v_data_changed := 'Y'
  else 
    v_data_changed :='N'
  endif
  return v_data_changed 
end
end get_data_change;

\u Column\u Name中的
是一个字符串变量,您将为其分配一个文本字符串值,例如
'DEPT\u Name'

因此,您的查询将其解释为文字字符串值,并将相同的内容返回到
v\u table1\u Column\u value

要实现预期目标,需要使用动态SQL,例如:

EXECUTE IMMEDIATE 'select eid, ' || in_Column_Name
               || ' from table1 where eid=:P_emp_id'
into v_table1_eid, v_table1_Column_Value
using in_emp_id;

您需要注意此处SQL注入的可能性-即,最终用户无法提供\u Column\u Name
的值。

正如@JeffreyKemp已经指出的,您需要使用动态SQL。此外,如果其中一个值为NULL,则检查这两个值是否不同(v_table2_column_value!=v_table1_column_value)将无法按预期工作-您需要对NULL值进行特殊处理。您好,Jef,感谢您的回复。我有两个问题。1.)这是什么:P_emp_id??这有什么影响?2.)我不明白什么时候你的意思是最终用户无法提供列中的名称?我正在使用get_数据变更(emp_id,“部门名称”);调用它。。而且效果很好。你是在什么情况下提到这个的。。感谢您在这方面的投入。再次感谢您提供的解决方案。@balaji-
:P_emp_id
是一个绑定变量标记;在运行时,
using
子句将\u emp\u id
中的
值放入该变量。这更有效,更重要的是防止提供恶意值。但这只适用于值,列名不能绑定,因此必须连接。如果列名称中的
值很糟糕,可能会使它做一些你意想不到的事情。(搜索“小bobby表”)。你可以用它来降低风险,但还是要小心。一个简单的问题。这个“v_table1_Column_Value”的数据类型能够动态定义吗??在这种情况下,我使用的部门名称是Varcahar2,年龄是整数。是否有办法在运行时定义它?您还可以比较SQL上的记录 级别。`'从eid=:P_emp_id1的表1中选择eid,|在| u列| u name |中选择eid,|在| u列| u name |中选择eid,|在| u列|中选择eid,其中eid=:P|emp_id2'`。这将仅在两个记录相同时返回一行,因此可以避免在列中具有不同数据类型时出现问题