Anordnung oder Liste in Oracle mit cfprocparam
-
30-09-2019 - |
Frage
habe ich eine Liste von Werten I in eine Tabelle über eine gespeicherte Prozedur eingefügt werden sollen. Ich dachte, ich würde ein Array Orakel und Schleife durch das Array übergeben, aber ich sehe nicht, wie ein Array in Oracle zu übergeben. Ich würde eine Liste übergeben, aber ich sehe nicht, wie mit der Liste arbeiten, um es in ein Array zu drehen mit PL / SQL (Ich bin ziemlich neu in PL / SQL). Bin ich dies für die falsche Art und Weise nähern?
Verwenden von Oracle 9i und CF8.
EDIT
Vielleicht über das ich denke, den falschen Weg? Ich bin sicher, ich tue nichts Neues hier ... Ich dachte, ich würde die Liste auf ein assoziatives Array dann Schleife das Array konvertieren, da Oracle mit Listen zu funktionieren gut scheint nicht (in meiner begrenzten Beobachtung).
Ich versuche, ein Produkt hinzuzufügen, dann fügen Sie Datensätze für das Management-Team.
- Produkttabelle
product = 'foo' product = 'bar' ... ... etc
-. Das Managementteam Tabelle hat nur die ID des Produkts und die ID der von einem Dropdown ausgewählten Benutzern
Das Benutzer-IDs in über eine Liste übergeben werden, wie "1,3,6,20"
Wie soll ich mich über die Datensätze an die Management-Team Tabelle hinzufügen?
Hier ist, wo ich bin Code weise
In der Theorie gebe ich eine Liste "1,2,3,4" zu inserts.addProduct.
inserts.addProduct sollte tools.listToArray anrufen und ein Array zurück.
inserts.addProduct neu erstellt eine Liste mit * delim als Test.
CREATE OR PAKET Tools AS
TYPE array_type is TABLE OF VARCHAR2(225) INDEX BY BINARY_INTEGER;
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type;
END tools;
CREATE OR REPLACE PACKAGE BODY tools
AS
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type
IS
l_token_count BINARY_INTEGER := 0;
-- l_token_tbl type_array;
i pls_integer;
l_start_pos INTEGER := 1;
l_end_pos INTEGER :=1;
p_parsed_table array_type;
BEGIN -- original work by John Spencer
WHILE l_end_pos <> 0 LOOP
l_end_pos := instr(in_list,in_delim,l_start_pos);
IF l_end_pos <> 0 THEN
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count ) :=
substr(in_list,l_start_pos,l_end_pos - l_start_pos);
l_start_pos := l_end_pos + 1;
END IF;
END LOOP;
IF l_token_count = 0 THEN /* We haven't parsed anything so */
l_token_count := 1;
p_parsed_table(l_token_count) := in_list;
ELSE /* We need to get the last token */
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count) := substr(in_list,l_start_pos);
END If;
RETURN p_parsed_table;
END listToArray; -- Procedure
END tools;
CREATE OR REPLACE PACKAGE inserts AS
TYPE array_type is TABLE OF VARCHAR2(225) INDEX BY BINARY_INTEGER;
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
);
END inserts;
CREATE OR REPLACE PACKAGE BODY inserts
AS
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
)
IS
i NUMBER;
localArray array_type := tools.listToArray(inList);
BEGIN
outList := '';
FOR i IN localArray.first .. localArray.last LOOP
outList := outList || '*' ||localArray(i); -- return a string just to test this mess
END LOOP;
END addProduct;
END inserts;
Ich bin immer noch einen Fehler "PLS-00382: Ausdruck ist von falschem Typ" auf localArray array_type: = tools.listToArray (INLIST);
letzter Arbeitscode (vielen Dank!)
- erstellen SQL-Typ Sammlung
CREATE OR REPLACE TYPE array_type is TABLE OF VARCHAR2(225);
/
CREATE OR REPLACE PACKAGE tools AS
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type;
END tools;
/
CREATE OR REPLACE PACKAGE BODY tools
AS
FUNCTION listToArray(in_list IN VARCHAR,
in_delim IN VARCHAR2 DEFAULT ',')
RETURN array_type
IS
l_token_count BINARY_INTEGER := 0;
i pls_integer;
l_start_pos INTEGER := 1;
l_end_pos INTEGER :=1;
p_parsed_table array_type := array_type();
BEGIN
WHILE l_end_pos <> 0 LOOP
l_end_pos := instr(in_list,in_delim,l_start_pos);
IF l_end_pos <> 0 THEN
p_parsed_table.extend(1);
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count ) :=
substr(in_list,l_start_pos,l_end_pos - l_start_pos);
l_start_pos := l_end_pos + 1;
END IF;
END LOOP;
p_parsed_table.extend(1);
IF l_token_count = 0 THEN /* We haven't parsed anything so */
l_token_count := 1;
p_parsed_table(l_token_count) := in_list;
ELSE /* We need to get the last token */
l_token_count := l_token_count + 1;
p_parsed_table(l_token_count) := substr(in_list,l_start_pos);
END If;
RETURN p_parsed_table;
END listToArray; -- Procedure
END tools;
/
CREATE OR REPLACE PACKAGE inserts AS
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
);
END inserts;
/
CREATE OR REPLACE PACKAGE BODY inserts
AS
PROCEDURE addProduct (inList IN VARCHAR2,
outList OUT VARCHAR2
)
IS
i NUMBER;
mylist VARCHAR(100);
localArray array_type := array_type();
BEGIN
localArray := tools.listToArray(inList);
mylist := '';
FOR i IN localArray.first .. localArray.last LOOP
mylist := mylist || localArray(i) || '*';
END LOOP;
aList := mylist;
END addProduct;
END inserts;
/
Lösung
PL / SQL unterstützt hat Arrays seit Oracle 8.0. Sie verwendet, um PL / SQL-Tabellen genannt werden, die aus jeder der Teufel verwirrt, so dass jetzt sie Sammlungen genannt werden. Erfahren Sie mehr.
Das Problem ist, dass sie als benutzerdefinierte implementiert werden Typen (das heißt Objekte). Meine Lektüre der Coldfusion-Dokumente , die cfprocparam
schlägt nur unterstützt die "primitive" Datentypen (number, varchar2, etc). So UDTs werden nicht unterstützt.
Ich bin mir nicht sicher, was Sie damit meinen:
würde ich eine Liste übergeben, aber ich sehe nicht, wie man Arbeit mit der Liste, um es in eine verwandeln Array mit PL / SQL
Wenn Sie meinen, Sie eine Reihe von Komma übergeben wollen separated values ??....
"Fox in socks, Mr Knox, Sam-I-Am, The Lorax"
dann habe ich eine Lösung für Sie. Oracle bietet keine Tokenizer-in gebaut. Aber vor langer Zeit John Spencer veröffentlichte eine handgerollte Lösung, die auf den OTN-Foren in Oracle 9i funktioniert. Finden Sie es hier.
Bearbeiten
aber ... Oracle hasst mich
nicht verzweifeln. Die OTN-Foren haben ein paar Mal aktualisiert wurde, da John, dass geschrieben, und die Formatierung scheint den Code irgendwo auf dem Weg zu haben, beschädigt. Es gab ein paar Kompilierungsfehlern, die sie nicht haben, nicht genutzt haben.
Ich habe Johns Code, einschließlich einer neuen Funktion neu geschrieben. Der wesentliche Unterschied besteht darin, dass die verschachtelte Tabelle als SQL-Typ deklariert wird eher als ein PL / SQL-Typ.
create or replace type tok_tbl as table of varchar2(225)
/
create or replace package parser is
function my_parse(
p_str_to_search in varchar2
, p_delimiter in varchar2 default ',')
return tok_tbl;
procedure my_parse(
p_str_to_search in varchar2
, p_delimiter in varchar2 default ','
, p_parsed_table out tok_tbl);
end parser;
/
Wie Sie sehen können, die Funktion ist nur ein Wrapper zu dem Verfahren.
create or replace package body parser is
procedure my_parse ( p_str_to_search in varchar2
, p_delimiter in varchar2 default ','
, p_parsed_table out tok_tbl)
is
l_token_count binary_integer := 0;
l_token_tbl tok_tbl := tok_tbl();
i pls_integer;
l_start_pos integer := 1;
l_end_pos integer :=1;
begin
while l_end_pos != 0
loop
l_end_pos := instr(p_str_to_search,p_delimiter,l_start_pos);
if l_end_pos != 0 then
l_token_count := l_token_count + 1;
l_token_tbl.extend();
l_token_tbl(l_token_count ) :=
substr(p_str_to_search,l_start_pos,l_end_pos - l_start_pos);
l_start_pos := l_end_pos + 1;
end if;
end loop;
l_token_tbl.extend();
if l_token_count = 0 then /* we haven't parsed anything so */
l_token_count := 1;
l_token_tbl(l_token_count) := p_str_to_search;
else /* we need to get the last token */
l_token_count := l_token_count + 1;
l_token_tbl(l_token_count) := substr(p_str_to_search,l_start_pos);
end if;
p_parsed_table := l_token_tbl;
end my_parse;
function my_parse ( p_str_to_search in varchar2
, p_delimiter in varchar2 default ',')
return tok_tbl
is
rv tok_tbl;
begin
my_parse(p_str_to_search, p_delimiter, rv);
return rv;
end my_parse;
end parser;
/
Die Tugend der Typ in SQL zu erklären ist, dass wir es in einer FROM-Klausel wie diese verwenden können:
SQL> insert into t23
2 select trim(column_value)
3 from table(parser.my_parse('Fox in socks, Mr Knox, Sam-I-Am, The Lorax'))
4 /
4 rows created.
SQL> select * from t23
2 /
TXT
------------------------------------------------------------------------------
Fox in socks
Mr Knox
Sam-I-Am
The Lorax
SQL>