我有一个CTE,我知道它可以工作,但是我想把它作为一个存储过程使用,这样我就可以在其中设置一些查询参数。下面是我尝试运行的代码,用来创建存储过程。
CREATE OR REPLACE PROCEDURE VATIS_OWNER.getEnvVariables(PF IN VARCHAR, SN IN VARCHAR) AS
BEGIN
--Joins environemt variables from TESTCASES and ENVIRONMENTS tables and transposes result into columns 'ColumnName' and 'ColumnValue' and the ProfileId
--Is used by getAllDynamicData and unioned with results from sp_getProfileDetails
with
cte as (
SELECT
T.TestcaseID,
T.ProfileID,
T.TrustID,
T.DNIS,
T.TESTID,
T.ACDID,
--Must be 8 digits long, so leading 0's are added
SUBSTR(CONCAT('00000000',T.testcaseid),-8, 8) as TestCaseNo,
T.HostId,
E.TFN
FROM TESTCASES T
FULL JOIN ENVIRONMENTS E ON T.ENV_NAME = E.ENV_NAME
--Only returns env vars associated with testcase @SN
where T.TestcaseID = SN
),
cte2 as (
Select A.ProfileID
,B.*
From cte A
--Transpose happens here
Cross Apply ( SELECT 'TestcaseID' AS ColumnName,A.TestcaseID AS ColumnValue FROM DUAL UNION ALL
SELECT 'ProfileID' AS ColumnName,A.ProfileID AS ColumnValue FROM DUAL UNION ALL
SELECT 'TrustID' AS ColumnName,A.TrustID AS ColumnValue FROM DUAL UNION ALL
SELECT 'DNIS' AS ColumnName,SUBSTR(A.DNIS,-7,7) AS ColumnValue FROM DUAL UNION ALL
SELECT 'TESTID' AS ColumnName,A.TESTID AS ColumnValue FROM DUAL UNION ALL
SELECT 'ACDID' AS ColumnName,A.ACDID AS ColumnValue FROM DUAL UNION ALL
SELECT 'TestCaseNo' AS ColumnName,A.TestCaseNo AS ColumnValue FROM DUAL UNION ALL
SELECT 'HostId' AS ColumnName,A.HostId AS ColumnValue FROM DUAL UNION ALL
SELECT 'TFN' AS ColumnName,A.TFN AS ColumnValue FROM DUAL UNION ALL
SELECT 'INVALIDANI' AS ColumnName,SUBSTR(CONCAT(A.TestcaseID ,A.TESTID),-10,10) AS ColumnValue FROM DUAL
) B
)
select distinct * from cte2 where profileID = PF;
END getEnvVariables;
如果我将SN和PF替换为字符串值,只运行CTE和查询,它就可以工作。在SQL Server中,一个等价的版本可以作为存储过程使用,但是当我试图在Oracle中创建这个存储过程时,我得到了这个编译错误。
PLS-00428: an INTO clause is expected in this SELECT statement
知道为什么我不能在存储过程中使用这个吗?我对SQL Server比Oracle更熟悉,所以如果我忘记了什么,请告诉我。先谢谢你。
如果你想从这个存储过程中返回选择结果,你必须使用一个SYS_REFCURSOR,如下所示----。
CREATE OR replace PROCEDURE vatis_owner.Getenvvariables(pf IN VARCHAR,
sn IN VARCHAR,
res OUT SYS_REFCURSOR) AS
BEGIN
--Joins environemt variables from TESTCASES and ENVIRONMENTS tables and transposes result into columns 'ColumnName' and 'ColumnValue' and the ProfileId
--Is used by getAllDynamicData and unioned with results from sp_getProfileDetails
OPEN res FOR
WITH cte AS
(
SELECT t.testcaseid,
t.profileid,
t.trustid,
t.dnis,
t.testid,
t.acdid,
--Must be 8 digits long, so leading 0's are added
Substr(Concat('00000000',t.testcaseid),-8, 8) AS testcaseno,
t.hostid,
e.tfn
FROM testcases t
full join environments e
ON t.env_name = e.env_name
--Only returns env vars associated with testcase @SN
WHERE t.testcaseid = sn ), cte2 AS
(
SELECT a.profileid ,
b.*
FROM cte a
--Transpose happens here
cross apply
(
SELECT 'TestcaseID' AS columnname,
a.testcaseid AS columnvalue
FROM dual
UNION ALL
SELECT 'ProfileID' AS columnname,
a.profileid AS columnvalue
FROM dual
UNION ALL
SELECT 'TrustID' AS columnname,
a.trustid AS columnvalue
FROM dual
UNION ALL
SELECT 'DNIS' AS columnname,
substr(a.dnis,-7,7) AS columnvalue
FROM dual
UNION ALL
SELECT 'TESTID' AS columnname,
a.testid AS columnvalue
FROM dual
UNION ALL
SELECT 'ACDID' AS columnname,
a.acdid AS columnvalue
FROM dual
UNION ALL
SELECT 'TestCaseNo' AS columnname,
a.testcaseno AS columnvalue
FROM dual
UNION ALL
SELECT 'HostId' AS columnname,
a.hostid AS columnvalue
FROM dual
UNION ALL
SELECT 'TFN' AS columnname,
a.tfn AS columnvalue
FROM dual
UNION ALL
SELECT 'INVALIDANI' AS columnname,
substr(concat(a.testcaseid ,a.testid),-10,10) AS columnvalue
FROM dual ) b )
SELECT DISTINCT *
FROM cte2
WHERE profileid = pf;
END getenvvariables;
然后在以后你可以使用这个 proc 来返回 ref_cursor 变量中的结果。
DECALRE
RES SYS_REFCURSOR;
BEGIN
vatis_owner.Getenvvariables(pf,
sn,
RES);
FOR I IN 1..RES.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(I.YOUR_DESIRED_COLUMNS);
END LOOP;
END;
我可以看到你的查询中使用了CROSS APPLY,这意味着你必须使用12C或更高版本。所以你可以使用DBMS_SQL.RETURN_RESULT函数----。
CREATE OR replace PROCEDURE vatis_owner.Getenvvariables(pf IN VARCHAR,
sn IN VARCHAR) AS
RES SYS_REFCURSOR;
BEGIN
--Joins environemt variables from TESTCASES and ENVIRONMENTS tables and transposes result into columns 'ColumnName' and 'ColumnValue' and the ProfileId
--Is used by getAllDynamicData and unioned with results from sp_getProfileDetails
OPEN RES FOR
WITH cte AS
(
SELECT t.testcaseid,
t.profileid,
t.trustid,
t.dnis,
t.testid,
t.acdid,
--Must be 8 digits long, so leading 0's are added
Substr(Concat('00000000',t.testcaseid),-8, 8) AS testcaseno,
t.hostid,
e.tfn
FROM testcases t
full join environments e
ON t.env_name = e.env_name
--Only returns env vars associated with testcase @SN
WHERE t.testcaseid = sn ), cte2 AS
(
SELECT a.profileid ,
b.*
FROM cte a
--Transpose happens here
cross apply
(
SELECT 'TestcaseID' AS columnname,
a.testcaseid AS columnvalue
FROM dual
UNION ALL
SELECT 'ProfileID' AS columnname,
a.profileid AS columnvalue
FROM dual
UNION ALL
SELECT 'TrustID' AS columnname,
a.trustid AS columnvalue
FROM dual
UNION ALL
SELECT 'DNIS' AS columnname,
substr(a.dnis,-7,7) AS columnvalue
FROM dual
UNION ALL
SELECT 'TESTID' AS columnname,
a.testid AS columnvalue
FROM dual
UNION ALL
SELECT 'ACDID' AS columnname,
a.acdid AS columnvalue
FROM dual
UNION ALL
SELECT 'TestCaseNo' AS columnname,
a.testcaseno AS columnvalue
FROM dual
UNION ALL
SELECT 'HostId' AS columnname,
a.hostid AS columnvalue
FROM dual
UNION ALL
SELECT 'TFN' AS columnname,
a.tfn AS columnvalue
FROM dual
UNION ALL
SELECT 'INVALIDANI' AS columnname,
substr(concat(a.testcaseid ,a.testid),-10,10) AS columnvalue
FROM dual ) b )
SELECT DISTINCT *
FROM cte2
WHERE profileid = pf;
DBMS_SQL.RETURN_RESULT(RES);
END getenvvariables;
当你运行这个程序时,你会在控制台看到结果。如需了解更多信息,请点击 阅读: