Solusi untuk "tidak dapat melakukan operasi DML di dalam kueri"?

Saya menggunakan alat Analisis Data dan persyaratan yang saya miliki adalah menerima nilai dari pengguna, meneruskannya sebagai parameter dan menyimpannya dalam tabel. Cukup mudah sehingga saya duduk untuk menulis ini

create or replace
procedure complex(datainput in VARCHAR2)
is
begin
insert into dumtab values (datainput);
end complex;

Saya mengeksekusi ini di SQL Developer menggunakan pernyataan berikut

begin
complex('SomeValue');  
end;

Ini bekerja dengan baik, dan nilainya dimasukkan ke dalam tabel. Namun, pernyataan di atas tidak didukung dalam alat Analisis Data, jadi saya menggunakan fungsi sebagai gantinya. Berikut ini adalah kode fungsi, itu dikompilasi.

create or replace
function supercomplex(datainput in VARCHAR2)
return varchar2
is
begin
insert into dumtab values (datainput);
return 'done';
end supercomplex;   

Sekali lagi saya mencoba mengeksekusinya di SQL Developer, tetapi saya mendapatkan tidak dapat melakukan operasi DML di dalam kueri setelah mengeksekusi kode berikut ini

select supercomplex('somevalue') from dual;

Pertanyaan saya adalah

  • Saya membutuhkan pernyataan yang dapat menjalankan fungsi yang disebutkan di SQL Developer atau
  • Fungsi yang dapat melakukan apa yang saya cari yang dapat dijalankan oleh pernyataan pilih.
  • Jika tidak mungkin untuk melakukan apa yang saya minta, saya ingin alasannya sehingga saya dapat memberi tahu manajer saya karena saya masih sangat baru (seperti seminggu?) Untuk PL / SQL jadi saya tidak mengetahui aturan dan sintaksisnya.

P.S. Betapa saya berharap ini adalah C ++ atau bahkan Java :(

EDIT

Saya perlu menjalankan fungsi pada SQL Developer karena sebelum menjalankannya di DMine (yang merupakan alat) untuk menguji apakah itu valid atau tidak. Apa pun yang tidak valid di SQL juga tidak valid di DMine, tetapi tidak sebaliknya.

Terima kasih atas bantuannya, saya mengerti situasinya dan mengapa hal itu ilegal/tidak direkomendasikan

Larutan

Anda bisa menggunakan arahan pragma autonomous_transaction. Ini akan menjalankan fungsi ke dalam transaksi independen yang akan dapat melakukan DML tanpa memunculkan ORA-14551.

Ketahuilah bahwa karena transaksi otonom bersifat independen, hasil DML akan dikomit di luar lingkup transaksi induk. Dalam kebanyakan kasus, hal itu tidak akan menjadi solusi yang dapat diterima.

SQL> CREATE OR REPLACE FUNCTION supercomplex(datainput IN VARCHAR2)
  2     RETURN VARCHAR2 IS
  3     PRAGMA AUTONOMOUS_TRANSACTION;
  4  BEGIN
  5     INSERT INTO dumtab VALUES (datainput);
  6     COMMIT;
  7     RETURN 'done';
  8  END supercomplex;
  9  /

Function created

SQL> SELECT supercomplex('somevalue') FROM dual;

SUPERCOMPLEX('SOMEVALUE')
--------------------------------------------------------------------------------
done

SQL> select * from dumtab;

A
--------------------------------------------------------------------------------
somevalue

Tom Kyte memiliki penjelasan yang bagus tentang mengapa kesalahan itu muncul di tempat pertama. Ini tidak aman karena mungkin tergantung pada urutan baris yang diproses. Lebih jauh lagi, Oracle tidak menjamin bahwa fungsi tersebut akan dieksekusi setidaknya sekali dan paling banyak sekali per baris.

Komentar (0)

Deklarasikan saja sebuah variabel untuk menerima nilai balik, misalnya:

declare
    retvar varchar2(4);
begin
    retvar := supercomplex('somevalue');
end;

Pilih tidak berfungsi karena fungsi tersebut melakukan penyisipan, jika yang dilakukannya hanyalah mengembalikan nilai maka itu akan berfungsi.

Komentar (1)

Jalankan saja fungsi dalam pernyataan if ... end if; dummy untuk mengabaikan nilai balik:


exec if supercomplex('somevalue') then null; end if;
~~~
Atau jalankan sebagai parameter untuk prosedur `put_line` untuk mengeluarkan nilai balik:
~~~~sql
exec dbms_ouput ('result of supercomplex='||supercomplex('somevalue'));

hasil superkompleks = selesai
~~~
Komentar (0)