动态修剪列值
Posted
技术标签:
【中文标题】动态修剪列值【英文标题】:Dynamically Trim Column Values 【发布时间】:2014-05-19 20:01:28 【问题描述】:这里有一个问题要问大家,有没有办法通过动态替换cursor.column_name
语法中的column_name
来使下面的PL/SQL 代码工作?我知道我混淆了 pl/sql 引擎,但我不完全确定如何解决这个问题......
目前我收到以下错误,但我认为实际问题是 pl/sql 引擎不知道如何解释 TRIM (e_rec.v_temp_column_name)
:
"[错误] PLS-00302 (133: 26): PLS-00302: 组件 必须声明“V_TEMP_COLUMN_NAME””
参数: x_person_rec IN OUT xxsome_table%ROWTYPE
v_temp_column_name dba_tab_columns.column_name%TYPE;
...
BEGIN
FOR e_rec IN (SELECT * FROM xxsome_table WHERE ..)
LOOP
--LOG (3, 'Loading/Sanitizing Header Record');
FOR col IN (SELECT column_name
FROM dba_tab_columns
WHERE table_name = UPPER ('xxsome_table'))
LOOP
--LOG (3, 'Sanitizing Column Name: ' || col.column_name);
v_temp_column_name := col.column_name;
x_person_rec.v_temp_column_name := TRIM (e_rec.v_temp_column_name);
END LOOP;
END LOOP;
...
我试过这样做(这会导致不同的错误):x_person_rec.col.column_name := TRIM (e_rec.col.column_name);
【问题讨论】:
【参考方案1】:不,你不能,而且你确实混淆了 PL/SQL 引擎。问题是v_temp_column_name
是一个字符,所以TRIM (e_rec.v_temp_column_name)
被评估为TRIM (e_rec.'v_temp_column_name')
,这没有任何意义。
如果出现尾随空格问题,最好的办法是确保您的应用程序/ETL 进程同时修剪所有放入数据库的数据。如果你不能这样做,那么使用触发器来确保它发生在数据库内部。如果这是一个真的很糟糕的问题,你甚至可以强制检查约束来阻止它发生。
现在,为了回答您的问题,这里无需动态执行任何操作。您的光标可能是隐式的,但它不是动态生成的。您知道表格中的每一列,所以不要那么懒惰,将它们全部输入。
FOR e_rec IN (SELECT trim(col1) as col1
, trim(col2) as col2
FROM xxsome_table WHERE ...
如果您无法修复数据(或者如果它没有损坏!),那么这很容易成为最简单的方法。
要真正回答您的问题,您可以使用您在此处使用的相同技术动态构建您的 SELECT 语句...
declare
l_cols varchar2(4000);
l_curs sys_refcursor;
begin
select wm_concat('trim(' || column_name || ')')
into l_cols
from user_tab_columns
where table_name = 'XXSOME_TABLE'
;
open l_curs for
' select ' || l_cols || ' from xxsome_table where ...';
loop
...
end loop;
end;
/
由于您使用的是 10g,因此您无法使用出色的 LISTAGG()
,但有 plenty of other string aggregation techniques。请注意if the resulting string is greater than 4,000 bytes,您必须循环而不是在单个 SQL 语句中生成列列表。
P.S.,如果这些列是 CHAR(n)
,那么您每次选择时都必须修剪它们。可能值得将它们更改为 VARCHAR2(n)
【讨论】:
感谢您的回复,我想您说了我需要听到的内容,我将在 ETL 过程中处理数据修剪。您关于动态构建 SELECT 的建议实际上是解决此问题的好方法,因此我感谢您付出的额外努力! 没问题@Roberto;设置一些东西来修剪所有东西很麻烦,但从长远来看,它会容易得多,因为你只需要做一次而不是每次......以上是关于动态修剪列值的主要内容,如果未能解决你的问题,请参考以下文章