我有以下查询:
select ''|| CHR(10) || CHR(10)
|| 'INSERT into ' || v_TableName || '(' || v_Columns || ')' || CHR(10)
|| 'VALUES (' || SUBSTR(v_Values,1, LENGTH(RTRIM(v_Values))-1) || ')' from dual;
执行时我得到:
v_TableName ='tblRecHistCalc',
v_Columns ='average_eps,company_id,rec_code,rec_date'
v_Values ='3.3887524216711,25597,'B','20-Mar-2019','
因此查询变为:
select ''|| CHR(10) || CHR(10)
|| 'INSERT into ' || 'tblRecHistCalc' || '(' || 'average_eps,company_id,rec_code,rec_date' || ')' || CHR(10)
|| 'VALUES (' || SUBSTR('3.3887524216711,25597,'B','20-Mar-2019',',1, LENGTH(RTRIM('3.3887524216711,25597,'B','20-Mar-2019','))-1) || ')' from dual;
但是我无法执行上述查询,因为'B'和'20 -Mar-2019'中有单引号,这使查询无法成功执行。
我尝试将其更改为以下内容:
select ''|| CHR(10) || CHR(10)
|| 'INSERT into ' || 'tblRecHistCalc' || '(' ||'average_eps,company_id,rec_code,rec_date' || ')' || CHR(10)
|| 'VALUES (' || SUBSTR(Replace('3.3887524216711,25597,'B','20-Mar-2019',',''','''''),1, LENGTH(RTRIM('3.3887524216711,25597,'B','20-Mar-2019','))-1) || ')' from dual;
但是查询仍然无法成功执行。
我该如何实现?
编辑:
根据 Alex Poole 的要求, 变量声明如下:
v_TableName NVARCHAR2(50);
v_Columns Nvarchar2(4000);
v_Values Nvarchar2(4000);
v_Count NUMBER(10);
v_SQL Nvarchar2(4000):='';
下面显示了如何填充三个变量:
WHILE (v_Count > 0)
LOOP
v_Columns := '';
v_Values := '';
-- Gets 1 table name at a time
SELECT TableName INTO v_TableName
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY TableName) as Rowcnt, TableName
FROM
--#tmp_Templates_Load_InsertSQL STARTS
(
SELECT D.TableName, D.ColumnName, D.Val
FROM
--#tmp_Templates_Load_Destinations STARTS
(
SELECT ID, TableName, ColumnName, Val
FROM tblTemplates_Load_OtherObjects_Raw OO
JOIN tblTemplates_Fields F ON OO.OtherObjectsField = F.FieldName
WHERE TemplateType IN ('All','ALL', v_TemplateType)
AND OO.Val IS NOT NULL
AND (TemplateVersion = p_TemplateVersion or (TemplateVersion is null and p_TemplateVersion <> 'V8'))
UNION
SELECT FieldID, TableName, ColumnName, Val
FROM tblTemplates_Fields_OtherDestinations OD
JOIN
(
SELECT ID, Val
FROM tblTemplates_Load_OtherObjects_Raw OO
JOIN tblTemplates_Fields F ON OO.OtherObjectsField = F.FieldName
WHERE TemplateType IN ('All','ALL', v_TemplateType)
AND OO.Val IS NOT NULL
AND (TemplateVersion = p_TemplateVersion or (TemplateVersion is null and p_TemplateVersion <> 'V8'))
) UsedIDs
ON OD.FieldID = UsedIDs.ID
) D
--#tmp_Templates_Load_Destinations ENDS
JOIN USER_TAB_COLS C ON upper(D.TableName) = upper(C.TABLE_NAME) AND upper(D.ColumnName) = upper(C.COLUMN_NAME)
WHERE (v_UpdateComp = 0 OR D.TableName <> 'tblComp')
AND (v_UpdateCompInd = 0 OR D.TableName <> 'tblCompInd')
ORDER BY D.TableName, D.ColumnName
)
--#tmp_Templates_Load_InsertSQL ENDS
GROUP BY TableName
) DistinctTableNames
WHERE Rowcnt = v_Count;
-- Get lists of all columns for current table
Select LISTAGG( ColumnName, ',' ) WITHIN GROUP ( ORDER BY ROWNUM )
into v_Columns
FROM
--#tmp_Templates_Load_InsertSQL STARTS
(
SELECT D.TableName, D.ColumnName, D.Val
FROM
--#tmp_Templates_Load_Destinations STARTS
(
SELECT ID, TableName, ColumnName, Val
FROM tblTemplates_Load_OtherObjects_Raw OO
JOIN tblTemplates_Fields F ON OO.OtherObjectsField = F.FieldName
WHERE TemplateType IN ('All','ALL', v_TemplateType)
AND OO.Val IS NOT NULL
AND (TemplateVersion = p_TemplateVersion or (TemplateVersion is null and p_TemplateVersion <> 'V8'))
UNION
SELECT FieldID, TableName, ColumnName, Val
FROM tblTemplates_Fields_OtherDestinations OD
JOIN
(
SELECT ID, Val
FROM tblTemplates_Load_OtherObjects_Raw OO
JOIN tblTemplates_Fields F ON OO.OtherObjectsField = F.FieldName
WHERE TemplateType IN ('All','ALL', v_TemplateType)
AND OO.Val IS NOT NULL
AND (TemplateVersion = p_TemplateVersion or (TemplateVersion is null and p_TemplateVersion <> 'V8'))
) UsedIDs
ON OD.FieldID = UsedIDs.ID
) D
--#tmp_Templates_Load_Destinations ENDS
JOIN USER_TAB_COLS C ON upper(D.TableName) = upper(C.TABLE_NAME) AND upper(D.ColumnName) = upper(C.COLUMN_NAME)
WHERE (v_UpdateComp = 0 OR D.TableName <> 'tblComp')
AND (v_UpdateCompInd = 0 OR D.TableName <> 'tblCompInd')
ORDER BY D.TableName, D.ColumnName
)
--#tmp_Templates_Load_InsertSQL ENDS
WHERE TableName = v_TableName ;
-- Get lists of all values for current table
Select LISTAGG(
CASE ISNUMERIC(Val)
WHEN 1 THEN Val
WHEN 0 THEN '''' || REPLACE(LTRIM(RTRIM(Val)), '''','''''') || ''''
END
|| ',' ) WITHIN GROUP ( ORDER BY ROWNUM )
into v_Values
FROM
--#tmp_Templates_Load_InsertSQL STARTS
(
SELECT D.TableName, D.ColumnName, D.Val
FROM
--#tmp_Templates_Load_Destinations STARTS
(
SELECT ID, TableName, ColumnName, Val
FROM tblTemplates_Load_OtherObjects_Raw OO
JOIN tblTemplates_Fields F ON OO.OtherObjectsField = F.FieldName
WHERE TemplateType IN ('All','ALL', v_TemplateType)
AND OO.Val IS NOT NULL
AND (TemplateVersion = p_TemplateVersion or (TemplateVersion is null and p_TemplateVersion <> 'V8'))
UNION
SELECT FieldID, TableName, ColumnName, Val
FROM tblTemplates_Fields_OtherDestinations OD
JOIN
(
SELECT ID, Val
FROM tblTemplates_Load_OtherObjects_Raw OO
JOIN tblTemplates_Fields F ON OO.OtherObjectsField = F.FieldName
WHERE TemplateType IN ('All','ALL', v_TemplateType)
AND OO.Val IS NOT NULL
AND (TemplateVersion = p_TemplateVersion or (TemplateVersion is null and p_TemplateVersion <> 'V8'))
) UsedIDs
ON OD.FieldID = UsedIDs.ID
) D
--#tmp_Templates_Load_Destinations ENDS
JOIN USER_TAB_COLS C ON upper(D.TableName) = upper(C.TABLE_NAME) AND upper(D.ColumnName) = upper(C.COLUMN_NAME)
WHERE (v_UpdateComp = 0 OR D.TableName <> 'tblComp')
AND (v_UpdateCompInd = 0 OR D.TableName <> 'tblCompInd')
ORDER BY D.TableName, D.ColumnName
)
--#tmp_Templates_Load_InsertSQL ENDS
WHERE TableName = v_TableName ;
-- Build Insert and append to v_SQL variable
v_SQL:= v_SQL || CHR(10) || CHR(10)
|| 'INSERT into ' || v_TableName || '(' || SUBSTR(v_Columns, 1, LENGTH(RTRIM(v_Columns))) || ')' || CHR(10)
|| 'VALUES (' || SUBSTR(v_Values, 1, LENGTH(RTRIM(v_Values))-1) || ')' ;
v_Count := v_Count -1;
EXECUTE IMMEDIATE v_SQL;
end loop;
答案 0 :(得分:3)
您尚未显示您当前如何将一个语句转换为另一个语句-我怀疑您使用不需要的动态SQL-但您可以这样做:
declare
v_TableName varchar2(30) := 'tblRecHistCalc';
v_Columns varchar2(80) := 'average_eps,company_id,rec_code,rec_date';
v_Values varchar2(80) := q'[3.3887524216711,25597,'B','20-Mar-2019',]';
v_sql varchar2(4000);
begin
select ''|| CHR(10) || CHR(10)
|| 'INSERT into ' || v_TableName || '(' || v_Columns || ')' || CHR(10)
|| 'VALUES (' || SUBSTR(v_Values,1, LENGTH(RTRIM(v_Values))-1) || ')'
into v_sql
from dual;
dbms_output.put_line(v_query);
end;
/
或使用赋值而不是对偶表进行选择:
v_sql := CHR(10) || CHR(10)
|| 'INSERT into ' || v_TableName || '(' || v_Columns || ')' || CHR(10)
|| 'VALUES (' || SUBSTR(v_Values,1, LENGTH(RTRIM(v_Values))-1) || ')';
这两个都会生成:
INSERT into tblRecHistCalc(average_eps,company_id,rec_code,rec_date)
VALUES (3.3887524216711,25597,'B','20-Mar-2019')
PL/SQL procedure successfully completed.
'20-Mar-2019'
仍然只是一个字符串,因此您依赖于隐式转换和NLS设置-如果立即执行该插入操作,则它们至少会匹配,但是会浪费时间的时间部分任何值(使用此模型;可能会产生更糟的影响),最好使用与字符串值之间的显式转换。
我也不清楚您的代码-不是我检查的太详细了-v_Values
的结尾是逗号吗?但是您也可以trim()
关闭它,而不用使用substr()
。