我们需要确保只有一个特定过程的副本在 Oracle 中运行。如果它已经在运行并且用户试图打开另一个,那么它应该会出错。
这样做的最佳方法是什么?
我想编写一个带有两个IN参数的函数,其中第一个是 a varchar,第二个是varchars. 基于这些,我想返回一个具有不同列数量和类型名称的表varchar。
据我所知,我必须始终创建一个对象/记录和它的表类型。这意味着我的想法行不通?基本目标是将系统命令输出作为表传递回被调用者。
编辑:更多关于任务。我想发出一个操作系统命令,使用输出并将其作为表返回。OS 命令的输出将是 CSV 格式的数据。在执行时,我不知道要返回的行数,而只知道作为第二个参数传递的列数。我正在考虑使用带有动态STRUCT和ARRAY包含它们的Java 。虽然我更喜欢前一种方法。
它应该是这样的:
create function(clob query, list of varchars cols) returns table
begin
execute system command(query, cols);
examine sysout from command;
return tabular data from syscmd as table;
end
Run Code Online (Sandbox Code Playgroud) 我今天写了 PL/SQL 的片段:
declare
first_id number;
second_id number;
begin
insert into table (sort_nr, text_id, unit_id) values(...,
table_seq.nextval, table_seq.nextval) returning text_id, unit_id
into first_id, second_id;
dbms_output.put_line(first_id);
dbms_output.put_line(second_id);
end;
Run Code Online (Sandbox Code Playgroud)
并收到了唯一的常量违规。经过进一步检查,我发现了它,first_id并且second_id在其中具有相同的价值。
我的问题是:在同一个语句中多次调用同一个序列并接收后续号码是否有任何限制?从我的角度来看,似乎nextval只在查询范围内调用一次并缓存。
只是附带说明,我无法更改那个糟糕的架构以避免在两列中使用相同的序列。
将应用程序从 Oracle 移动到 SQL Server,我有这个伪 Oracle PL/SQL:
SELECT LTRIM(MyColumn, '-, ') FROM MyTable
Run Code Online (Sandbox Code Playgroud)
即我使用Oracle 的LTRIM第二个参数,指定要从字符串左侧修剪的字符。
不幸的是,T-SQL 版本LTRIM不允许我指定要修剪的字符。
目前,我对如何迁移它一无所知LTRIM。在阅读了MyColumn.
这对我来说看起来很不雅观。
我的问题:
是否有任何有意义的方法可以获得LTRIM类似 T-SQL 的功能来传递字符以修剪掉?
编辑1:
我需要替换-,,和从字符串的开头。
例如:
SELECT LTRIM(MyColumn, '-, ') FROM MyTable
Run Code Online (Sandbox Code Playgroud)
会导致
-----, ,,, This is ,- a test,---,
Run Code Online (Sandbox Code Playgroud)
编辑2:
我强烈希望这不是XY 问题。
也许重写我的整个查询会LTRIM完全消除对LTRIM.
这是我的 SQL Server 存储过程,如下所示:
CREATE PROCEDURE passenger_details
AS
BEGIN
SELECT Full_Name, Age, Nationality, Category, Airline_Name, Class_Type
FROM Passenger, Ticket, Airline, Class
WHERE Passenger.Passenger_No=Ticket.Passenger_No AND Airline.Airline_No=Ticket.Airline_No AND Class.Class_No=Ticket.Class_No
END
EXECUTE passenger_details
Run Code Online (Sandbox Code Playgroud)
SQL Server 中的上述存储过程成功运行。
然后我尝试在 Oracle PL/SQL 中执行相同的存储过程,如下所示:
CREATE OR REPLACE PROCEDURE passenger_details
(p_passenger_details OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_passenger_details FOR
SELECT Full_Name, Age, Nationality, Category, Airline_Name, Class_Type
FROM Passenger, Ticket, Airline, Class
WHERE Passenger.Passenger_No=Ticket.Passenger_No AND Airline.Airline_No=Ticket.Airline_No AND Class.Class_No=Ticket.Class_No;
END passenger_details;
Run Code Online (Sandbox Code Playgroud)
以上Oracle PL/SQL中的存储过程编译成功。
然后我尝试执行它,如下所示:
SET SERVEROUTPUT ON;
EXECUTE passenger_details;
Run Code Online (Sandbox Code Playgroud)
在尝试执行存储过程时,我收到以下错误消息,如下所示:
Error …Run Code Online (Sandbox Code Playgroud) PL/SQL 中的过程可以有参数的默认值,但调用者可以传递与默认值相同的值。有没有办法从 PL/SQL 内部确定是否传递了参数?正如暗示的那样,这不能通过将值与默认值进行比较来完成。
使用 Oracle 的Advanced Queuing是否可以按 LIFO(后进先出)顺序出列消息?有通过缺乏信息的指示,这是不是一种选择,但也许是有办法做到这一点,如以不同的顺序排队。
使用 PL/SQL,假设我们已经声明了一个嵌套表类型及其实例,如下所示:
type nested_tab is table of pls_integer;
tab nested_tab;.
然后我们可以按如下方式初始化我们的嵌套表:
tab := nested_tab(1, 2, 3);.
我们可以做类似的事情来初始化关联数组吗?
换句话说,对于以下关联数组:
type associative_tab is table of varchar2(100) index by pls_integer;
a_tab associative_tab;
有没有比这更短的方法:
a_tab(1) := 'hello';
a_tab(2) := 'world';
...
a_tab(100) := '100th string';
用于初始化?
我宣布一个类型TYPE arr_type is TABLE of VARCHAR2(11 BYTE);,然后我初始化:MY_array arr_type := arr_type();。
我在其中插入了一些 varchars,然后尝试将它与 IN 运算符一起使用。
set serveroutput on;
DECLARE
TYPE arr_type is TABLE of VARCHAR2(11 BYTE);
my_array arr_type := arr_type();
my_array_two arr_type := arr_type();
BEGIN
SELECT MY_ID BULK COLLECT INTO my_array FROM XYZ_REQUEST;
SELECT ANOTHER_ID BULK COLLECT INTO my_array_TWO FROM ABC_REQUEST WHERE PARENT_ID IN my_array;
FOR i IN 1..cm_array.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(my_array(i));
END LOOP;
END;
/
Run Code Online (Sandbox Code Playgroud)
我收到错误:local collection types not allowed in SQL statements在包含:的行上SELECT ANOTHER_ID …
这是我创建的表:
CREATE TABLE Toy
(Toy_No NUMBER PRIMARY KEY,
Toy_Name VARCHAR(30) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
这是我创建的序列:
CREATE SEQUENCE toy_seq
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 20;
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用输出参数创建一个简单的存储过程:
CREATE OR REPLACE PROCEDURE insert_toys(toy_id OUT NUMBER,toy_name VARCHAR(30))
AS
BEGIN
toy_id := seq_toy.NEXTVAL;
INSERT INTO Toy (Toy_No,Toy_Name)
VALUES (toy_id,toy_name);
END;
Run Code Online (Sandbox Code Playgroud)
但我收到编译错误。错误可能在哪里?