我想动态创建一个具有多个值的INSERT语句,如以下示例所示:
INSERT INTO table_name (ID, PARENT, NAME, ENABLED)
VALUES (1, 't1', 'Test1', 1 ), (2, 't2', 'Test2', 1 ), (3, 't3', 'Test3', 1 );
当前,我正在使用以下语句,但是现在我得到的单个语句过多,因此无法提供良好的性能
SELECT 'INSERT INTO table_name(ID, PARENT, NAME, ENABLED) '
|| 'VALUES ('|| ID ||','''|| PARENT ||''','''|| NAME || ''', '|| ENABLED ||');'
FROM table_name WHERE ID IN (... [inner select] ...);
怎么可能在这样的单个插入语句中创建一个附加新值的循环?
SELECT 'INSERT INTO table_name (ID, PARENT, NAME, ENABLED)' VALUES
DECLARE
myValues varchar2(500);
CURSOR myCur IS SELECT ID, PARENT, NAME, ENABLED FROM table_name;
BEGIN
FOR values IN myCur LOOP
IF myCur%ROWCOUNT = 1 THEN
myValues := '('||values.ID ||', '''|| values.PARENT ||''', '''|| values.NAME ||''', '|| values.ENABLED ||'),';
ELSE
myValues := '('||values.ID ||', '''|| values.PARENT ||''', '''|| values.NAME ||''', '|| values.ENABLED ||')';
end if;
END LOOP;
END;
--...
我需要使用SQLplus导出我的数据并将其插入另一个数据库
谢谢
答案 0 :(得分:2)
如果要插入静态增量数据(按照您的原始示例),请对分层查询使用INSERT INTO ... SELECT
:
INSERT INTO table_name ( id, parent, name, enabled )
SELECT LEVEL, 't' || LEVEL, 'Test' || LEVEL, 1
FROM DUAL
CONNECT BY LEVEL <= 3
如果要从现有表构建查询,则:
SELECT 'INSERT INTO table_name ( id, parent, name, enabled )'
|| LISTAGG(
'SELECT ' || id || ', '
|| '''' || REPLACE( parent, '''', '''''' ) || ''', '
|| '''' || REPLACE( name, '''', '''''' ) || ''', '
|| enabled
|| ' FROM DUAL',
' UNION ALL '
) WITHIN GROUP ( ORDER BY ROWNUM )
FROM table_name
如果要超过4000个字符,则可以生成多行:
SELECT 'INSERT INTO table_name ( id, parent, name, enabled )' FROM DUAL
UNION ALL
SELECT 'SELECT ' || id || ', '
|| '''' || REPLACE( parent, '''', '''''' ) || ''', '
|| '''' || REPLACE( name, '''', '''''' ) || ''', '
|| enabled
|| ' FROM DUAL'
|| CASE WHEN ROWNUM < COUNT(*) OVER () THEN ' UNION ALL ' END
FROM table_name
db <>提琴here
或使用Oracle实用程序RMAN
或ExpDP
生成表的备份。
答案 1 :(得分:0)
我认为,您应该停止重新发明轮子。 Oracle提供了数据泵导出/导入实用程序,这些实用程序旨在用于此目的-移动数据。在简单的(或者,我应该说大多数)情况下,甚至可以使用原始导出/导入实用程序。
您未指定要使用的数据库版本-这是12c数据泵文档:https://docs.oracle.com/database/121/SUTIL/GUID-501A9908-BCC5-434C-8853-9A6096766B5A.htm#SUTIL2877
有很多示例将展示如何做到这一点。我建议您不要跳过阅读文档,而直接跳到运行一些代码。了解自己的实际工作将使您受益,而不是希望它会变成 right 。
答案 2 :(得分:0)
一种方法是使用XML文件进行数据传输。
以XML格式获取数据:
DECLARE
l_xml DBMS_XMLGEN.ctxHandle;
BEGIN
l_xml := dbms_xmlgen.newContext('SELECT * FROM table_name WHERE ID IN (... [inner select] ...)');
dbms_output.put_line(dbms_xmlgen.getXML(l_xml));
dbms_xmlgen.closeContext(l_xml);
END;
插入声明:
INSERT INTO table_name (ID, PARENT, NAME, ENABLED)
SELECT dbms_xmlgen.convert(value(soc).EXTRACT('/ROW/ID/text()' ).getStringVal(), 1)
, dbms_xmlgen.convert(value(soc).EXTRACT('/ROW/PARENT/text()' ).getStringVal(), 1)
, dbms_xmlgen.convert(value(soc).EXTRACT('/ROW/NAME/text()' ).getStringVal(), 1)
, dbms_xmlgen.convert(value(soc).EXTRACT('/ROW/ENABLED/text()').getStringVal(), 1)
FROM TABLE(XMLSequence(EXTRACT(XMLType(<XML>), '/ROWSET/ROW'))) SOC