如何创建带参数的 SQL 函数?
Posted
技术标签:
【中文标题】如何创建带参数的 SQL 函数?【英文标题】:How can I create a SQL function with a parameter? 【发布时间】:2012-03-14 19:16:24 【问题描述】:以下代码根据输入“28”返回一个字段,即一个字符串。
SELECT data.id, LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names
FROM (
SELECT id, name, ROW_NUMBER() OVER (order by name) rownumber, COUNT(*) OVER () cnt
FROM (
SELECT es.EVENT_ID as id, s.SERVICE_NAME as name FROM DT_SERVICES s
JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID
WHERE es.EVENT_ID = 28
)
) data
WHERE rownumber = cnt
START WITH rownumber = 1
CONNECT BY PRIOR rownumber = rownumber-1;
如何从中创建一个 SQL 函数,以便我可以传入任何数字(而不是 28),并且该函数将返回该选择的结果是什么?
我尝试创建一个,但我不断收到编译错误。
用于创建函数的当前 SQL
create or replace function "DT_SERVICE_STRING" (id in VARCHAR2)
return VARCHAR2 is
begin
DECLARE
result VARCHAR(200);
SELECT data.id, LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names
INTO result
FROM (
SELECT id, name, ROW_NUMBER() OVER (order by name) rownumber, COUNT(*) OVER () cnt
FROM (
SELECT es.EVENT_ID as id, s.SERVICE_NAME as name FROM DT_SERVICES s
JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID
WHERE es.EVENT_ID = id
)
) data
WHERE rownumber = cnt
START WITH rownumber = 1
CONNECT BY PRIOR rownumber = rownumber-1;
return result;
end;
错误: 编译失败,第 7 行 (15:22:21) PLS-00103:当期望以下之一时遇到符号“SELECT”:开始函数杂注过程子类型类型当前光标删除之前存在
【问题讨论】:
你有什么导致编译错误? 我正在尝试将其创建为 Oracle Apex 中的一个函数 它看起来像什么,这不起作用?使用现有但损坏的代码更新您的问题。 【参考方案1】:假设您想要一个可从 SQL 语句调用的 PL/SQL 函数(您不能在 SQL 中定义函数),听起来您想要类似的东西
CREATE OR REPLACE FUNCTION get_conc_names( p_event_id IN dt_event_service.event_id%type )
RETURN VARCHAR2
IS
l_conc_names VARCHAR2(32676);
-- You may want a smaller variable if you know the result will be smaller
BEGIN
SELECT LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names
INTO l_conc_names
FROM (
SELECT id, name, ROW_NUMBER() OVER (order by name) rownumber, COUNT(*) OVER () cnt
FROM (SELECT es.EVENT_ID as id, s.SERVICE_NAME as name
FROM DT_SERVICES s
JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID
WHERE es.EVENT_ID = p_event_id )
) data
WHERE rownumber = cnt
START WITH rownumber = 1
CONNECT BY PRIOR rownumber = rownumber-1;
RETURN l_conc_names;
END;
根据您刚刚发布的代码,您似乎只需要去掉DECLARE
并将局部变量result
的声明移到BEGIN
之前和IS
之后。
【讨论】:
确实。现在我明白了:编译失败,第 8 行 (15:27:25) PL/SQL: ORA-00947: not enough valuesCompilation failed,line 7 (15:27:25) PL/SQL: SQL Statement denied @antonpug - 我更新了我的答案。没有注意到您的SELECT
语句选择了两列。由于您只返回一个值,我假设您真的只需要选择 conc_names
字符串。
嗯,这很奇怪,同样的错误仍然存在。是的,我自己也注意到了这两列。它一直告诉我没有足够的价值【参考方案2】:
我认为分析函数需要位于内部内联视图中,然后外部内联视图可以选择它们——这就是我一直这样做的方式。试试这个:
CREATE OR REPLACE FUNCTION get_conc_names( p_event_id IN dt_event_service.event_id%type )
RETURN VARCHAR2
IS
l_conc_names VARCHAR2(32676);
-- You may want a smaller variable if you know the result will be smaller
BEGIN
SELECT LTRIM(SYS_CONNECT_BY_PATH(name, ', '),',') conc_names
INTO l_conc_names
FROM (
SELECT id, name, rownumber, cnt
FROM (SELECT es.EVENT_ID as id
,s.SERVICE_NAME as name
,ROW_NUMBER() OVER (order by name) as rownumber
,COUNT(*) OVER () as cnt
FROM DT_SERVICES s
JOIN DT_EVENT_SERVICE es ON s.SERVICE_ID = es.SERVICE_ID
WHERE es.EVENT_ID = p_event_id )
) data
WHERE rownumber = cnt
START WITH rownumber = 1
CONNECT BY PRIOR rownumber = rownumber-1;
RETURN l_conc_names;
END;
【讨论】:
以上是关于如何创建带参数的 SQL 函数?的主要内容,如果未能解决你的问题,请参考以下文章