SELECT 中某些函数的布尔值 return
Boolean return value of some function inside SELECT
我正在 PL/SQL 中开发一个包。
这是我的规格:
TYPE outrec IS RECORD(
tw_m_id NUMBER,
tw_m_dealer_id NUMBER,
tw_number NUMBER,
check_uid NUMBER);
TYPE outrecset IS TABLE OF outrec;
FUNCTION report
(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
) RETURN outrecset
PIPELINED;
这是我的 body:
FUNCTION func
(
p_watermark => p_watermark,
p_param => p_param,
p_index => p_index
)
RETURN outrecset
PIPELINED IS
temp outrec;
BEGIN
before_report(p_watermark => p_watermark,
p_param => p_param,
p_index => p_index);
FOR c_rec IN (SELECT tw_m_id,
tw_m_dealer_id,
tw_number,
package_name.somefunction(tw_number) AS check_uid
FROM table1
JOIN table2 rk ON id1 = rk.id2
WHERE 1 = 1
AND id1 = rk.id2
AND id1 = p_param)
LOOP
temp.tw_m_tw_rechnungskopf_id := c_rec.tw_m_tw_rechnungskopf_id;
temp.tw_m_haendler_id_rechnung := c_rec.tw_m_haendler_id_rechnung;
temp.check_uid := c_rec.check_uid;
PIPE ROW(temp);
END LOOP;
END;
我正在尝试从 package_name.somefunction(tw_number) AS check_uid 获取值。问题是 somefunction returns BOOLEAN 值。
当我将 check_uid 设置为 BOOLEAN 时,出现错误:PLS-00382:表达式类型错误,因为 SQL 当然不支持 BOOLEAN。我试过了:
CASE
WHEN package_name.somefunction(tw_number) THEN true
else false
END as check_uid
在 SELECT 中然后我得到错误:PL/SQL:ORA-00920:无效的关系运算符。
有人能告诉我怎么做吗PL/SQL 不是我最强的一面:(
- 编辑:我无法将 somefunction 更改为 return 例如 varchar2 它需要保持原样
通常您会在包中创建一个 returns 1/0 或 Y/N 的重载函数。但是由于您无权访问该包,您可以在 sql 查询中使用内联函数来为您执行此操作。
create or replace function func (parameter_i VARCHAR2) RETURN BOOLEAN
AS
BEGIN
return true;
END;
/
WITH
FUNCTION func_yn(parameter_i VARCHAR2)
RETURN NUMBER
IS
l_return_value BOOLEAN;
BEGIN
l_return_value :=func(parameter_i => parameter_i);
RETURN CASE l_return_value WHEN TRUE THEN 1 WHEN FALSE THEN 0 END;
END func_yn;
SELECT
func_yn('test')
FROM dual;
编写一个简单的包装函数将 PL/SQL BOOLEAN
转换为 NUMBER
在 SQL 中有效且符合您的记录类型的数据类型,您可以将函数调用移到 SQL.
之外
CREATE FUNCTION MAP_BOOLEAN( truthy IN BOOLEAN ) RETURN NUMBER DETERMINISTIC
IS
BEGIN
RETURN CASE truthy
WHEN TRUE THEN 1
WHEN FALSE THEN 0
ELSE NULL
END;
END map_boolean;
/
所以您的规格是:
CREATE PACKAGE package_name IS
TYPE outrec IS RECORD(
tw_m_id NUMBER,
tw_m_dealer_id NUMBER,
tw_number NUMBER,
check_uid NUMBER
);
TYPE outrecset IS TABLE OF outrec;
-- Note: This may be in another package but is here for convenience.
FUNCTION somefunction(value IN NUMBER) RETURN BOOLEAN;
FUNCTION report
(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
) RETURN outrecset PIPELINED;
END;
/
对应的正文是:
CREATE PACKAGE BODY package_name IS
FUNCTION somefunction(value IN NUMBER) RETURN BOOLEAN
IS
BEGIN
RETURN TRUE;
END;
PROCEDURE before_report(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
)
IS
BEGIN
NULL;
END;
FUNCTION report(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
) RETURN outrecset PIPELINED
IS
temp outrec;
BEGIN
before_report(
p_watermark => p_watermark,
p_param => p_param,
p_index => p_index
);
FOR c_rec IN (
SELECT tw_m_id,
tw_m_dealer_id,
tw_number
FROM table1
JOIN table2 rk ON id1 = rk.id2
WHERE id1 = p_param
)
LOOP
temp.tw_m_id := c_rec.tw_m_id;
temp.tw_m_dealer_id := c_rec.tw_m_dealer_id;
temp.check_uid := MAP_BOOLEAN(
PACKAGE_NAME.SOMEFUNCTION( c_rec.tw_number )
);
PIPE ROW(temp);
END LOOP;
END;
END;
/
(注意:您还需要更新游标循环,因为您选择的值与记录的字段不匹配。)
db<>fiddle here
我正在 PL/SQL 中开发一个包。
这是我的规格:
TYPE outrec IS RECORD(
tw_m_id NUMBER,
tw_m_dealer_id NUMBER,
tw_number NUMBER,
check_uid NUMBER);
TYPE outrecset IS TABLE OF outrec;
FUNCTION report
(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
) RETURN outrecset
PIPELINED;
这是我的 body:
FUNCTION func
(
p_watermark => p_watermark,
p_param => p_param,
p_index => p_index
)
RETURN outrecset
PIPELINED IS
temp outrec;
BEGIN
before_report(p_watermark => p_watermark,
p_param => p_param,
p_index => p_index);
FOR c_rec IN (SELECT tw_m_id,
tw_m_dealer_id,
tw_number,
package_name.somefunction(tw_number) AS check_uid
FROM table1
JOIN table2 rk ON id1 = rk.id2
WHERE 1 = 1
AND id1 = rk.id2
AND id1 = p_param)
LOOP
temp.tw_m_tw_rechnungskopf_id := c_rec.tw_m_tw_rechnungskopf_id;
temp.tw_m_haendler_id_rechnung := c_rec.tw_m_haendler_id_rechnung;
temp.check_uid := c_rec.check_uid;
PIPE ROW(temp);
END LOOP;
END;
我正在尝试从 package_name.somefunction(tw_number) AS check_uid 获取值。问题是 somefunction returns BOOLEAN 值。 当我将 check_uid 设置为 BOOLEAN 时,出现错误:PLS-00382:表达式类型错误,因为 SQL 当然不支持 BOOLEAN。我试过了:
CASE
WHEN package_name.somefunction(tw_number) THEN true
else false
END as check_uid
在 SELECT 中然后我得到错误:PL/SQL:ORA-00920:无效的关系运算符。
有人能告诉我怎么做吗PL/SQL 不是我最强的一面:(
- 编辑:我无法将 somefunction 更改为 return 例如 varchar2 它需要保持原样
通常您会在包中创建一个 returns 1/0 或 Y/N 的重载函数。但是由于您无权访问该包,您可以在 sql 查询中使用内联函数来为您执行此操作。
create or replace function func (parameter_i VARCHAR2) RETURN BOOLEAN
AS
BEGIN
return true;
END;
/
WITH
FUNCTION func_yn(parameter_i VARCHAR2)
RETURN NUMBER
IS
l_return_value BOOLEAN;
BEGIN
l_return_value :=func(parameter_i => parameter_i);
RETURN CASE l_return_value WHEN TRUE THEN 1 WHEN FALSE THEN 0 END;
END func_yn;
SELECT
func_yn('test')
FROM dual;
编写一个简单的包装函数将 PL/SQL BOOLEAN
转换为 NUMBER
在 SQL 中有效且符合您的记录类型的数据类型,您可以将函数调用移到 SQL.
CREATE FUNCTION MAP_BOOLEAN( truthy IN BOOLEAN ) RETURN NUMBER DETERMINISTIC
IS
BEGIN
RETURN CASE truthy
WHEN TRUE THEN 1
WHEN FALSE THEN 0
ELSE NULL
END;
END map_boolean;
/
所以您的规格是:
CREATE PACKAGE package_name IS
TYPE outrec IS RECORD(
tw_m_id NUMBER,
tw_m_dealer_id NUMBER,
tw_number NUMBER,
check_uid NUMBER
);
TYPE outrecset IS TABLE OF outrec;
-- Note: This may be in another package but is here for convenience.
FUNCTION somefunction(value IN NUMBER) RETURN BOOLEAN;
FUNCTION report
(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
) RETURN outrecset PIPELINED;
END;
/
对应的正文是:
CREATE PACKAGE BODY package_name IS
FUNCTION somefunction(value IN NUMBER) RETURN BOOLEAN
IS
BEGIN
RETURN TRUE;
END;
PROCEDURE before_report(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
)
IS
BEGIN
NULL;
END;
FUNCTION report(
p_watermark IN NUMBER,
p_param IN NUMBER,
p_index IN NUMBER
) RETURN outrecset PIPELINED
IS
temp outrec;
BEGIN
before_report(
p_watermark => p_watermark,
p_param => p_param,
p_index => p_index
);
FOR c_rec IN (
SELECT tw_m_id,
tw_m_dealer_id,
tw_number
FROM table1
JOIN table2 rk ON id1 = rk.id2
WHERE id1 = p_param
)
LOOP
temp.tw_m_id := c_rec.tw_m_id;
temp.tw_m_dealer_id := c_rec.tw_m_dealer_id;
temp.check_uid := MAP_BOOLEAN(
PACKAGE_NAME.SOMEFUNCTION( c_rec.tw_number )
);
PIPE ROW(temp);
END LOOP;
END;
END;
/
(注意:您还需要更新游标循环,因为您选择的值与记录的字段不匹配。)
db<>fiddle here