Insert into tables with & operator - plsql

I have some tables and I want to insert into them by asking their name, then putting in the values for the columns. Thing is, Whenever I run this, it goes through all the inputs no matter what, even if I input an incorrect tables. Then I get an error that it expected = symbol instead of :=.
The code:
set serveroutput on;
declare
myTable varchar2;
begin
myTable = &input_table;
if myTable = 'Supervisor' then
insert into Supervisor values(&supID, &supName);
elsif myTable = 'Job' then
insert into Job values(&jobID, &jobName);
else dbms_output.put_line('Found no such table.');
end if;
end;
/

PL/SQL scripts (running in SQLPlus or SQLPlus emulators) are not interactive tools. When you run the script, Oracle first parses its text, then defines all &-variables, then ask you to fill them, and only then begins execution. Use any interactive tools instead (in fact, for your own task you have to write your own tool yourself).

Related

Column sizes sometimes do not fit when I move data from table 'TABLE_1' to table 'TABLE_2'. oracle is sending an error as follows

I want to move data from one table to a table.
I wrote one plsql code for this process.
Column sizes sometimes do not fit when I move data from table 'TABLE_1' to table 'TABLE_2'.
oracle is sending an error as follows.
I have identified one exception to get rid of this error.
but this exception is in a static state.
I want to make this exception part dynamic.
that is, if this error occurs in other columns, I want to automatically increase the size of the column in those columns.
the following is the plsql code I wrote.
for example, an oracle insert operation may give the same error in the 'explanation' column.
I want to modify the size of the 'explanation' column.
if this error occurs,
I want to perform these operations automatically for each column.
DECLARE
SAYAC INTEGER;
SAYAC_2 INTEGER;
extension_already_exists EXCEPTION;
PRAGMA EXCEPTION_INIT(extension_already_exists, -12899);
BEGIN
SAYAC:=0;
FOR XX IN (SELECT
FILE_NO,
NAME,
EV_ADRESI,
explanation
FROM TABLE_1
WHERE NOT EXISTS (SELECT *
FROM TABLE_2
WHERE TABLE_2.FILE_NO = TABLE_1.FILE_NO )
)LOOP
BEGIN
SAYAC:=SAYAC+1;
EXECUTE IMMEDIATE 'INSERT INTO
TABLE_2(
FILE_NO,
NAME,
EV_ADRESI,
explanation
)
VALUES
(
:A,
:B,
:C,
:D
) '
using XX.FILE_NO,XX.NAME,XX.EV_ADRESI,xx.explanation
;
IF MOD(SAYAC,1000)=0 THEN
COMMIT;
END IF;
EXCEPTION WHEN extension_already_exists THEN
dbms_output.put_line('seviye cok buyuk = '||sqlcode||' FILE_NO = '||XX.FILE_NO||','||xx.EV_ADRESI);--this error may occur in other columns
EXECUTE IMMEDIATE 'ALTER TABLE TABLE_2 MODIFY EV_ADRESI,explanation VARCHAR2(100)'; --forexample xx.explanation
NULL; --I want to make this place dynamic
end;
END LOOP;
COMMIT;
END;
ORA-12899: value too large for column "HOSPITAL"."table_2"."EV_ADRESI" (actual: 34, maximum: 20)
ORA-06512: at line 20
That won't work anyway. Even if you capture the error and enlarge the column, you'd miss the offending row as you should repeat the previous insert (which failed).
From my point of view, you should first match columns' datatpyes and then move data from here to there in a simple manner.
By the way, why did you use dynamic SQL for insert? There's nothing dynamic there.

how to get the count of folders if i am having the path of the file in PL/SQL?

I want to find the count of the folders present in the specified path
For example 'C:\Users\abc'
What is the code to get the count of the files present inside this path?
There is one way I found to do that in pure PL/SQL using SYS.DBMS_BACKUP_RESTORE.SEARCHFILES. It involves granting some strange rights. I have not tested it myself though. You can find more details here
Basically, you create the directory, and a pipelined function that lists the files in the directory. Then you can simply count them.
create type file_array as table of varchar2(100)
/
CREATE OR REPLACE FUNCTION COUNT_FILES (lp_string IN VARCHAR2 default null)
RETURN file_array pipelined AS
lv_pattern VARCHAR2(1024);
lv_ns VARCHAR2(1024);
BEGIN
SELECT directory_path
INTO lv_pattern
FROM dba_directories
WHERE directory_name = '<YOUR_DIR_NAME>';
SYS.DBMS_BACKUP_RESTORE.SEARCHFILES(lv_pattern, lv_ns);
FOR file_list IN (SELECT FNAME_KRBMSFT AS file_name
FROM X$KRBMSFT
WHERE FNAME_KRBMSFT LIKE '%'|| NVL(lp_string, FNAME_KRBMSFT)||'%' ) LOOP
PIPE ROW(file_list.file_name);
END LOOP;
END;
/
grant execute on LIST_FILES to public;
create public synonym list_files for sys.LIST_FILES;
Then you can run your query:
select count from table(list_files);
If you could not have these rights, the only way is to use external Java or C routine and call it from PL/SQL to do it for you. There is numerous examples for Java

how to guess random values from user in pl sql

could someone help?
declare
ran int:=dbms_random.value(1,5);
num number;
begin
dbms_output.put_line('enter the num');
num:=&num;
if num<ran then
&dbms_output.put_line('Your num is less'||ran);
elsif num>ran then
&dbms_output.put_line('Your num is greater'||ran);
else
&dbms_output.put_line('Equal'||num||'='||ran);
end if;
while num=ran loop
&dbms_output.put_line('enter the num');
num:=&num;
end loop;
end;
there is some problems ?
what is wrong?
how to guess random numbers what's wrong
You would need to prompt for the number separately, and then use the value in a PL/SQL block once you have it.
Substitution variables are a SQL*Plus feature and not part of the core PL/SQL language (which is not interactive), so the following works in SQL*Plus. Client applications such as PL/SQL Developer emulate it to varying degrees, so it may also work in those (for example in PL/SQL Developer you would run it in a Command window, or in TOAD you'd use the 'Run as script' option). You may also be able to do something in Apex or using a third party scripting language such as Perl, Python, PowerShell etc.
accept mynumber number format 0 prompt "Enter a number between 1 and 5: "
declare
ran int := dbms_random.value(1, 5);
begin
if &mynumber < ran then
dbms_output.put_line('&mynumber is less than ' || ran);
elsif &mynumber > ran then
dbms_output.put_line('&mynumber is greater than ' || ran);
else
dbms_output.put_line('&mynumber = ' || ran);
end if;
end;
/
I'm not sure what the loop in your example is supposed to do. If you want it to prompt for input repeatedly in a loop you will need to write something in a separate scripting language or another development framework.

ORA-00900: invalid SQL statement when using loop to insert rows

I'm trying to insert multiple rows into an Oracle 11g table by running the following in Aqua Data Studio (version 15.0.11), using this:
BEGIN
FOR i IN 1..700 LOOP
INSERT INTO lims.stock_template (
stock_template_id,
name,
group_id,
version,
version_status,
workflow_id,
amount,
stock_type_id,
aliquot_template_id,
auto_authorise,
reorder_amount
)
VALUES (
lims.sq_stock_template.nextval,
lims.sq_stock_template.currval,
21,
1,
'A',
51881,
0,
103,
2362,
'F',
0
);
END LOOP;
END;
/
but I get the following error:
>[Error] Script lines: 30-30 ------------------------
ORA-00900: invalid SQL statement
Script line 30, statement line 1, column 0
If I run just the INSERT statement by itself, it works just fine, but I want to be able to insert multiple rows in one operation.
I'm sure that I've run something similar in the past, but I can't see what the problem is.
Any help much appreciated.
Thanks
In your example, you included a BEGIN and END clause, which turns this into a "Anonymous PL/SQL Block"
http://docstore.mik.ua/orelly/oracle/prog2/ch15_03.htm
Within a PL/SQL block you can't execute a SQL statement directly. You have to use only PL/SQL. See attached example.
Now you can create a stored procedure to execute your insert and use Script Object to Window As -> Execute or Execute Bind. See below screenshot.
In a stored procedure or a stored procedure within a package you can do whatever you like!
create or replace procedure testMe as
begin
FOR i IN 1..700 LOOP
INSERT INTO lims.stock_template (
stock_template_id,
name,
group_id,
version,
version_status,
workflow_id,
amount,
stock_type_id,
aliquot_template_id,
auto_authorise,
reorder_amount
)
VALUES (
lims.sq_stock_template.nextval,
lims.sq_stock_template.currval,
21,
1,
'A',
51881,
0,
103,
2362,
'F',
0
);
END LOOP;
end;
This is EXACTLY analogous to typing every line in at the SQL prompt form the word begin to the word end;.
What is more then likely tripping you up is the slash at the bottom. In the CLI sqlPlus the end of the line with the semicolon ( ; ) causes it to run the process, hence :
select 'A' from dual;
The semicolon tells it to execute.
IF on the other hand you type in the word begin then it shifts mode and will accept semicolons anywhere and just keep adding your strings to the buffer. ON A BLANK LINE the type the / and return and it will try and execute your code.
I think if you remove the slash it will execute quite nicely.

cant compile plsql package in sqldeveloper 4.0

I have to use sqldeveloper 4.0. But i cant compile single package in it. It compiles in other programs, but i have to use sqldeveloper. I tryed to compile oracle tutorial package:
CREATE OR REPLACE PACKAGE emp_actions AS -- spec
TYPE EmpRecTyp IS RECORD (emp_id INT, salary REAL);
CURSOR desc_salary RETURN EmpRecTyp;
PROCEDURE hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr NUMBER,
sal NUMBER,
comm NUMBER,
deptno NUMBER);
PROCEDURE fire_employee (emp_id NUMBER);
END emp_actions;
CREATE OR REPLACE PACKAGE BODY emp_actions AS -- body
CURSOR desc_salary RETURN EmpRecTyp IS
SELECT empno, sal FROM emp ORDER BY sal DESC;
PROCEDURE hire_employee (
ename VARCHAR2,
job VARCHAR2,
mgr NUMBER,
sal NUMBER,
comm NUMBER,
deptno NUMBER) IS
BEGIN
INSERT INTO emp VALUES (empno_seq.NEXTVAL, ename, job,
mgr, SYSDATE, sal, comm, deptno);
END hire_employee;
PROCEDURE fire_employee (emp_id NUMBER) IS
BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;
END emp_actions;
And i get Error(14,1): PLS-00103: Encountered the symbol "CREATE" - on create package body line
I tryed to put "/" in front of it but i get Error(13,1): PLS-00103: Encountered the symbol "/".
I dont know the version of the database.
Thank you for help
If you want to run both statements together then you need to put a / after each of them, by itself on a new line:
CREATE OR REPLACE PACKAGE emp_actions AS -- spec
...
END emp_actions;
/
CREATE OR REPLACE PACKAGE BODY emp_actions AS -- body
...
END emp_actions;
/
... and then do 'Run Script' (F5, or the button with an icon of a green arrow over a document), rather than 'Run Statement' (Ctrl-Enter, or the button with just a green arrow). The output will go in the 'Script Output' pane.
You can't run multiple statements with 'Run Statement', although you can still select the text of one statement from a script and run that on its own - if it's a query then the output will still appear in the 'Query Result' pane.
If you've created a new package from the 'File->New' menu item, or by right-clicking the 'Package' header in the object browser and selecting 'New Package', then you can only enter the specification in the window that's displayed (the tab has the package name and an icon of a wrapped present). That does actually make more sense - I thought the line number on your second error was wrong, but that matches working in this window.
So enter just the package specification in that window and compile. Then back in the object browser, refresh the package list, right-click your new package name and select 'Create Body'. You'll get a second tab which looks very similar but the tab name will say ' body'. You can put the package body in there and compile it.
Using these views you always have the specification and body in separate tabs. Once both exist each has a button to open the other - the specification window has a button to open the body, and vice versa.

Resources