我有以下查询:
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 = bblRecistKal,
v_Columns = 'average_eps,COMPANY_ID,rec_code,rec_date'
V_value ='1.3220 c,20,'或','to-mar-to-1','
所以查询变成:
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;
您还没有展示当前如何将一个语句转换为另一个语句 - 我怀疑使用您不需要的动态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()
。