如何在 PL/SQL 的 LIKE 子句中使用变量
Posted
技术标签:
【中文标题】如何在 PL/SQL 的 LIKE 子句中使用变量【英文标题】:How to use a variable in a LIKE clause in PL/SQL 【发布时间】:2020-02-07 12:29:24 【问题描述】:我是 Oracle 新手,正在学习;我只是想运行这个 T-SQL 查询
DECLARE @SearchObj varchar(100);
SET @SearchObj='%aldbrough%';
SELECT
obj_id,
name,
description
FROM
agnis.t_object
WHERE
lower(name) = ObjToSearch ;
我正在使用 SQL Developer Oracle 工具,它还有一个“草稿编辑器”来帮助翻译 T-SQL。当我运行该工具时,它给了我这段代码
DECLARE
v_SearchObj VARCHAR2(100);
BEGIN
v_SearchObj := '%aldbrough%' ;
SELECT obj_id ,
NAME ,
DESCRIPTION
FROM agnis.t_object
WHERE LOWER(NAME) = ObjToSearch;
END;
但是同样的工具给了我这个错误
Error report -
ORA-06550: line 10, column 26:
PL/SQL: ORA-00904: "OBJTOSEARCH": invalid identifier
ORA-06550: line 6, column 4:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
那么在返回多行的 LIKE 子句中使用变量的正确语法是什么? 我希望我不必像this question 中建议的那样使用游标等简单语句
【问题讨论】:
至于您的另一点,您不必使用显式光标。但是您必须将结果集选择到 something 中。当您的查询返回多行 you should use an array。除非您使用 12c 或更高版本,在这种情况下您可以使用 T-SQL 样式的隐式游标,但仍然比 T-SQL 中的编码更多。 Find out more 感谢 = 而不是 LIKE 等,这是我复制和粘贴的坏习惯 【参考方案1】:嗯,是的 - 那些“翻译”并不总是做他们应该做的。
你的代码应该是这样的:
在where
子句中使用like
,而不是=
在 PL/SQL 中,您必须将 select
语句 into
的结果放入某些东西 - 例如,本地声明的变量(如我的示例所示)。
所以:
DECLARE
v_SearchObj VARCHAR2 (100) := '%aldbrough%';
--
v_obj_id t_object.obj_id%TYPE;
v_name t_object.name%TYPE;
v_description t_object.description%TYPE;
BEGIN
SELECT obj_id, NAME, DESCRIPTION
INTO v_obj_id, v_name, v_description
FROM agnis.t_object
WHERE LOWER (NAME) LIKE v_searchobj;
END;
如果这样的代码返回错误 - too_many_rows
(是的,确实如此),那么一种选择是循环通过行并做某事(例如显示这些值):
DECLARE
v_SearchObj VARCHAR2 (100) := '%aldbrough%';
BEGIN
FOR cur_r IN (SELECT obj_id, NAME, DESCRIPTION
FROM agnis.t_object
WHERE LOWER (NAME) LIKE v_searchobj)
LOOP
DBMS_OUTPUT.put_line (
'Name = ' || cur_r.name || ', description = ' || cur_r.description);
END LOOP;
END;
【讨论】:
好的,我知道我必须为查询返回的每个数据项声明一个变量,但是是的,在这种情况下,使用您的好代码会给我返回多行错误 完全正确,就像@APC 所说的那样。我添加了更多代码来显示您如何“修复”它,但是 - 最终结果取决于您想要做什么。这只是在支持 DBMS_OUTPUT 的工具(例如 SQLPlus 或 SQL Developer)中显示值。 我现在使用这个代码 DECLARE v_SearchObj VARCHAR2 (100) := '%aldbrough%';类型 v_obj_id 是数字表;类型 v_name 是 VARCHAR 表(200);类型 v_description 是 VARCHAR 表(200); BEGIN SELECT obj_id, NAME, DESCRIPTION BULK COLLECT INTO v_obj_id, v_name, v_description FROM agnis.t_object WHERE LOWER (NAME) LIKE v_searchobj;结尾;但我收到此错误错误报告 - ORA-06550:第 9 行,第 24 列:PLS-00321:表达式“V_OBJ_ID”不适合作为赋值语句的左侧 无法在 cmets 中格式化代码;最好编辑您发布的原始问题。无论如何,您不能将 3 列批量收集到 3 个数组中。创建一个包含所有 3 列的数组。 @brillox 你可以将BULK COLLECT
3 列分成 3 个数组db<>fiddle。您只需要将集合声明为变量并声明这些集合的类型。您可以通过将代码包装在 ` 反引号中来编写代码,但您不能在 cmets 中包含换行符。【参考方案2】:
由于这是标记为 SQL Developer,所以使用绑定变量:
SELECT obj_id,
name,
description
FROM agnis.t_object
WHERE lower(name) = :ObjToSearch;
SQL 开发人员会弹出一个对话框,您可以在其中设置ObjToSearch
变量的值。
如果你想在代码中指定绑定变量,那么:
VARIABLE objtosearch VARCHAR2(50)
BEGIN
:objtosearch := '%aldbrough%';
END;
/
SELECT obj_id,
name,
description
FROM agnis.t_object
WHERE lower(name) = :ObjToSearch;
并使用 F5 将语句作为脚本运行,而不是作为单个语句运行。
【讨论】:
以上是关于如何在 PL/SQL 的 LIKE 子句中使用变量的主要内容,如果未能解决你的问题,请参考以下文章
如何在 select 的 where 子句中替换 oracle pl/sql 变量
Oracle PL/SQL:在 SAMPLE 子句中使用变量时出现语法错误