【发布时间】:2013-12-10 16:55:07
【问题描述】:
以下函数生成 SELECT 以生成 Oracle 表记录的 INSERT STATEMENT:
CREATE OR REPLACE FUNCTION GEN_INSERT_STATEMENT (IN_TABLE_NAME VARCHAR2)
RETURN CLOB
IS
LC$COLS_SELECT CLOB;
LC$COLS_VALUES CLOB;
LC$COLOUMN CLOB;
CURSOR LCUR$TAB_COLUMNS (IN_TABLE_NAME VARCHAR2)
IS
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_ID
FROM USER_TAB_COLS
WHERE TABLE_NAME = IN_TABLE_NAME
ORDER BY COLUMN_ID;
BEGIN
FOR LREC$TAB_COLUMNS IN LCUR$TAB_COLUMNS (UPPER (IN_TABLE_NAME))
LOOP
LC$COLS_SELECT :=
LC$COLS_SELECT
|| CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END
|| LREC$TAB_COLUMNS.COLUMN_NAME;
IF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'CHAR') > 0
THEN
LC$COLOUMN :=
'''''''''||REPLACE('
|| LREC$TAB_COLUMNS.COLUMN_NAME
|| ','''''''','''''''''''')||''''''''';
ELSIF INSTR (LREC$TAB_COLUMNS.DATA_TYPE, 'DATE') > 0
THEN
LC$COLOUMN :=
'''TO_DATE(''''''||TO_CHAR(' || LREC$TAB_COLUMNS.COLUMN_NAME
|| ',''mm/dd/yyyy hh24:mi:ss'')||'''''',''''mm/dd/yyyy hh24:mi:ss'''')''';
ELSE
LC$COLOUMN := LREC$TAB_COLUMNS.COLUMN_NAME;
END IF;
LC$COLS_VALUES :=
LC$COLS_VALUES
|| CASE LREC$TAB_COLUMNS.COLUMN_ID WHEN 1 THEN '' ELSE ',' END
|| '''||DECODE('
|| LREC$TAB_COLUMNS.COLUMN_NAME
|| ',NULL,''NULL'','
|| LC$COLOUMN
|| ')||''';
END LOOP;
RETURN 'SELECT ''INSERT INTO '
|| IN_TABLE_NAME
|| ' ('
|| LC$COLS_SELECT
|| ') VALUES ('
|| LC$COLS_VALUES
|| ');'' FROM '
|| IN_TABLE_NAME
|| ';';
END;
/
问题是这个函数不能处理存在一些VARCHAR2字段以CHR(0)结尾的情况
用法:
SELECT GEN_INSERT_STATEMENT ('MY_ORACLE_TABLE_NAME') FROM DUAL;
... 生成一个 SELECT 以生成 INSERT 语句。
如果在VARCHAR2 字段中的值以CHR(0) 结尾,则INSERT 语句将被截断,正好是CHR(0) 所在的位置。
我该如何解决这个问题?
【问题讨论】:
-
您的意思是当您运行由函数生成的各个插入语句时,而不是在运行函数本身时,对吧? (只是出于兴趣,例如,您为什么要这样做而不是导出数据?)
-
当我运行该功能时,一切正常。当我运行该函数生成的 SELECT 时,该函数会产生许多 INSERT STATEMENTS。其中一些 INSERT STATEMENTS 在某些 VARCHAR2 字段中存在 CHR(0) 时被截断。
-
这不能回答您的问题,但您可能需要研究替代引用机制和时间戳文字,以帮助保持此类代码的清洁。例如:
q'! ' !'和timestamp '2000-01-01 14:00:00'。