# Aufruf von SELECT INTO



## Generic1 (14. Sep 2010)

Hallo,

ich möchte in meiner Stored Procedure (für eine Oracle DB) ein:

s varchar2(200);
SELECT * INTO s FROM ZDEVICES;

machen, bekomme aber den Fehler 

ERROR at line 7: PL/SQL: ORA-00947: Anzahl der Werte reicht nicht aus.

Mir ist schon klar, was der Fehler bedeutet (SELECT liefert mehrere Werte zurück), mir ist aber nicht klar, was ich da in der SP definieren muss als "s" damit mir das Ergebnis in "s" geschrieben wird.

Am liebsten wäre mir halt ein Array, wo in jedem Eintrag ein Ergebnis von Select steht.

Weiß jemand wie ich das am Besten machen kann?
lg


----------



## Michael... (14. Sep 2010)

Ist beim mir schon eine Weile her, aber es müsste sowas wie ROWTYPE geben.

```
s ZDEVICES%ROWTYPE;
```
Alternative könnte man aber auch einen *Cursor* verwenden.


----------



## Generic1 (14. Sep 2010)

Könntest Du vielleicht ein ganzen Beispiel geben?
Mir ist nicht klar wie das Oracle fressen könnte.


----------



## Michael... (14. Sep 2010)

Generic1 hat gesagt.:


> Könntest Du vielleicht ein ganzen Beispiel geben?
> Mir ist nicht klar wie das Oracle fressen könnte.


Naja so wie ich es halt geschrieben habe:

```
s ZDEVICES%ROWTYPE;
SELECT * INTO s FROM ZDEVICES;
```
Wobei hier das Select Statement nur eine "Datenzeile" liefern darf, sonst gibt es glaube ich Probleme.

Ob Dir das weiter hilft, keine Ahnung. Dazu müsste man wissen was Du vorhast.
Wenn das Statement einen mehrzeiligen ResultSet zurückliefert musst Du direkt darüber iterieren oder das ganze mittels Cursor handeln.


----------



## Generic1 (14. Sep 2010)

Michael... hat gesagt.:


> Naja so wie ich es halt geschrieben habe:
> 
> ```
> s ZDEVICES%ROWTYPE;
> ...



Du hast recht, das SELECT darf nur ein Tupel zurückliefern, das bringt mich schon weiter aber wie du schon geschrieben hast, gibt bei mir das SELECT meherer TUPELS zurück.

Könntest du da ein Beispiel geben, wie man das mit einem CURSOR macht oder wie ich über das ResultSet drüberiterieren kann?
vielen Dank,
lg


----------



## Michael... (14. Sep 2010)

Ohne Cursor sollte es so ähnlich funktioneren

```
s ZDEVICES%ROWTYPE;
...
FOR s IN (SELECT * FROM ZDEVICES) LOOP
    DBMS_OUTPUT.PUTLINE(s.id);
END LOOP;
```
Sofern ZDevices eine Spalte namens ID besitzt wird über den ResultSet iteriert und für jeden Datensatz der Wert aus ID ausgegeben.
Für Cursor müsste ich selbst irgendwo nachschlagen oder im Internet suchen.


----------



## Generic1 (14. Sep 2010)

Ein Problem hab ich noch, ich habe einen ROWTYPE, der über mehrere Tabellen geht, 
lässt sich das auch definieren?
Vielen Dank,
lg


```
SELECT Name, Version, UniqueDeviceID
FROM packages, collection, device_collection, devices
WHERE packages.ID = package_ID AND collection.ID = collection_ID AND device_ID = devices.ID
```


----------



## Michael... (14. Sep 2010)

Das wiederrum geht z.B. mittels Cursor

```
CURSOR mycursor IS SELECT Name, Version, UniqueDeviceID
FROM packages, collection, device_collection, devices
WHERE packages.ID = package_ID AND collection.ID...;

myvariable mycursor%ROWTYPE;
...
```
Man kann dann per FETCH und LOOP den Cursor auslesen, muss diesen aber vorher per OPEN initialisieren.

Ist bei mir aber wie gesagt schon eine Weile her. Aber im Netz sollten sich einige Bsp finden lassen.


----------



## Gast2 (14. Sep 2010)

Kann man auch ohne OPEN, in einer FOR Schleife, dann wird halt der gesammte Cursor Inhalt durchlaufen.


```
DECLARE
  CURSOR mycursor IS SELECT Name, Version, UniqueDeviceID
  FROM packages, collection, device_collection, devices 
  WHERE packages.ID = package_ID AND collection.ID...;
 
  myvariable mycursor%ROWTYPE;
BEGIN

  FOR myvariable IN mycursor LOOP
  -- do something
  END LOOP;
END;
```


----------

