Woo*_*Moo 2 sql oracle reflection tuples
我试图编写一个通用触发器,可以检查要插入数据库的每个元组.在这个检查中,我想替换我感兴趣的字符,例如带有常规引号(")的弯引号(MS字).因为我不想为每列写入两个替换调用存储用户提供的数据,我也不想在应用程序中出于多种原因这样做.伪代码如下:
create or replace trigger changeChars
before insert
on @tableName
reference new as var
for each row
Begin
loop
:var.@column := replace(:var.@column,'”', '"');
end
Run Code Online (Sandbox Code Playgroud)
为什么要替换这些字符?很多人都遇到像Microsoft卷曲引号这样的字符问题,因为这些字符不受数据库字符集的支持,默认情况下,这些字符集导致字符集转换用替换字符替换那些字符,如'?'.如果这是您尝试解决的问题,则数据库代码无法提供帮助,因为在数据甚至到达数据库之前,字符集转换发生在网络层.您可以使用Oracle Locale Builder为客户端计算机构建自定义区域设置,以允许您指定不同的替换字符(即双引号而不是Microsoft卷曲引号).
如果您的问题与字符集无关,则无法创建此类动态触发器.您可以编写一些动态SQL,为每个调用表中REPLACE每VARCHAR2列的表创建一个触发器.当然,每次VARCHAR2添加其他列时(通过更改触发器或重新运行PL/SQL块),您都需要维护触发器.
未经测试,我确定生成的DDL不正确,但你需要类似的东西
DECLARE
l_sql_stmt VARCHAR2(4000);
BEGIN
FOR tbl IN (SELECT * FROM user_tables)
LOOP
l_sql_stmt := 'CREATE OR REPLACE TRIGGER ' || tbl.table_name || '_changeChars ' ||
' BEFORE INSERT ON ' || tbl.table_name ||
' FOR EACH ROW ' ||
'BEGIN ';
FOR col IN (SELECT * FROM user_tab_cols WHERE table_name = tbl.table_name)
LOOP
l_sql_stmt := l_sql_stmt ||
' :new.' || col.column_name ||
' := replace( :new.' || col.column_name || ',''"'', ''"''');';
END LOOP;
l_sql_stmt := l_sql_stmt ||
'END; ';
dbms_output.put_line( 'SQL statement = ' || l_sql_stmt );
EXECUTE IMMEDIATE l_sql_stmt;
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)