如何像在 T-SQL 中一样在 PL/SQL 中声明和使用变量?
Posted
技术标签:
【中文标题】如何像在 T-SQL 中一样在 PL/SQL 中声明和使用变量?【英文标题】:How do I declare and use variables in PL/SQL like I do in T-SQL? 【发布时间】:2012-06-08 20:05:05 【问题描述】:在 Sql Server 中,我经常在测试存储过程的主体时,将主体复制到 SSMS 中,在页面顶部声明变量,将它们设置为一些示例值,然后将主体执行为-是。
例如,如果我的 proc 是
CREATE PROC MySampleProc
@Name VARCHAR(20)
AS
SELECT @Name
那么我的测试sql就是
DECLARE @Name VARCHAR(20)
SET @Name = 'Tom'
SELECT @Name
与此等效的 Oracle PL/SQL 是什么?
这是我想出的最接近的方法,但我得到“PLS-00428:此 SELECT 语句中应有一个 INTO 子句”
DECLARE
myname varchar2(20);
BEGIN
myname := 'Tom';
select myname from DUAL;
END;
这是我真正想做的一个更好的例子:
DECLARE
myname varchar2(20);
BEGIN
myname := 'Tom';
SELECT *
FROM Customers
WHERE Name = myname;
END;
但同样,它需要一个“INTO”,而我真的只想将记录打印在屏幕上,而不是存储在另一个表中......
已解决:
感谢@Allan,我已经让它运行良好。 Oracle SQL Developer 显然会记住您提供给它的参数值。然而,PL/SQL Developer 不想与此有任何关系....
如果您“以脚本方式运行”,它将遵循您的默认设置,但它只会将结果作为 ASCI 文本返回,而不是在网格/电子表格中
【问题讨论】:
这是我找到的与我的答案最接近的,但他们没有显示如何在查询的选择列表中使用该变量,并且不断向我抛出错误。 plsql-tutorial.com/plsql-variables.htm 你最后一段代码有两个问题。 1)变量前面不需要冒号,无论是在赋值中还是在 SELECT 语句中。 2) SELECT 语句的结果需要去某个地方,例如你声明第二个变量并写SELECT Name INTO Name2 FROM DUAL
。
如果我不想让结果出现在某个地方,我只想让它们显示在 PL/SQL Developer 的网格中怎么办?
这是不可能的(除非您使用相当高级的功能)。 T-SQL 和 PL/SQL 在这方面有很大不同。如果您想测试存储过程,那么您可能需要使用 DBMS_OUTPUT.PRINT_LINE 以大多数 Oracle 工具(例如 TOAD、SQL Developer、PL/SQL Developer)可以捕获和显示的方式编写结果。
我过去也曾为此苦苦挣扎。您必须使用 select into 并使用 dbms_output.put_line(myname); 打印输出Oracle 使用游标返回结果,SQL Server 不使用。
【参考方案1】:
修改后的答案
如果您不是从另一个程序调用此代码,一个选项是跳过 PL/SQL 并使用绑定变量在 SQL 中严格执行:
var myname varchar2(20);
exec :myname := 'Tom';
SELECT *
FROM Customers
WHERE Name = :myname;
在许多工具(例如 Toad 和 SQL Developer)中,省略 var
和 exec
语句将导致程序提示您输入值。
原答案
T-SQL 和 PL/SQL 之间的一个很大区别是 Oracle 不允许您隐式返回查询结果。结果总是必须以某种方式显式返回。最简单的方法是使用DBMS_OUTPUT
(大致相当于print
)输出变量:
DECLARE
myname varchar2(20);
BEGIN
myname := 'Tom';
dbms_output.print_line(myname);
END;
但是,如果您尝试返回结果集,这并不是很有帮助。在这种情况下,您可能想要返回一个集合或一个引用。但是,使用这些解决方案中的任何一个都需要将您的代码包装在一个函数或过程中,并从能够使用结果的东西中运行该函数/过程。以这种方式工作的函数可能如下所示:
CREATE FUNCTION my_function (myname in varchar2)
my_refcursor out sys_refcursor
BEGIN
open my_refcursor for
SELECT *
FROM Customers
WHERE Name = myname;
return my_refcursor;
END my_function;
【讨论】:
我认为你的第三个例子就是我正在寻找的。我将如何在 PL/SQL Developer 中运行它?如果我使用该语法,我会在 var 行上得到“无效的 SQL 语句”?还是我只需要使用 Toad? 我最初在exec
语句中留下了一个冒号。使用冒号,如果您“运行脚本”,它应该可以在 SQL Developer 中运行,但结果将输出到“脚本输出”窗格,而不是“查询结果”网格。鉴于有限的实验,我发现将其放入网格的唯一方法是省略 var
和 exec
语句,让 SQL Developer 提示您输入值。
我不断收到“ORA-01008:并非所有变量都绑定”。我应该将其作为“SQL 窗口”还是“测试窗口”或其他窗口运行?
您使用的是什么工具?我的印象是您使用的是 Oracle 的免费 SQL Developer,但这与您最后的评论不符。
我使用的是 PL/SQL Developer,而不是 Oracle Developer。刚刚安装了,它提示输入参数,就像你描述的那样。我仍然想知道如何使用脚本定义的密码,但这已经足够了。【参考方案2】:
在 Oracle PL/SQL 中,如果您正在运行可能返回多行的查询,则需要一个游标来遍历结果。最简单的方法是使用 for 循环,例如:
declare
myname varchar2(20) := 'tom';
begin
for result_cursor in (select * from mytable where first_name = myname) loop
dbms_output.put_line(result_cursor.first_name);
dbms_output.put_line(result_cursor.other_field);
end loop;
end;
如果您有一个只返回一行的查询,那么您可以使用select...into...
语法,例如:
declare
myname varchar2(20);
begin
select first_name into myname
from mytable
where person_id = 123;
end;
【讨论】:
【参考方案3】:变量未定义,但已声明。
这可能与declare variables in a pl/sql block 重复
但是你可以看这里:
http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/fundamentals.htm#i27306
http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/overview.htm
更新:
参考这里:How to return a resultset / cursor from a Oracle PL/SQL anonymous block that executes Dynamic SQL?
【讨论】:
也许我没有问对问题。根据您的链接,我知道如何分配值,但是如何选择它并将其显示在结果集中? 在结果集中显示它是什么意思?你想选择值作为函数吗? 用一个更好的例子来更新问题的尾部,说明我正在尝试做什么/回答你的后续问题。 然后你需要创建函数而不是过程并执行 SELECT MY_FUNC() FROM DUAL;函数可以返回结果集。查看我的更新 啊,我不想重复使用代码,这就是我的意思。我想知道如何在现在只是一个 1 次运行的 PL/SQL Developer 窗口中重新使用过程主体(并具有参数),并带有静态定义/分配的变量。以上是关于如何像在 T-SQL 中一样在 PL/SQL 中声明和使用变量?的主要内容,如果未能解决你的问题,请参考以下文章
PL/SQL 我是谁功能类似于 T-SQL 的 OBJECT_NAME(@@PROCID)
在 PL/SQL Oracle 中需要此 T-Sql 函数的等效函数。如果有其他解决方案,那么流水线