Insert in table, Sequence.nextval not working - sql

I have the following 3 tables,
Data_Excel contains the names, address, city and source of person;
Person table has the name and ID;
I need to insert into person_location the address source, address, city and ID...
I am using the following query :
CREATE SEQUENCE seq
START WITH 6571
MINVALUE 6571
INCREMENT BY 1
CACHE 100
INSERT INTO Person (id,Name,source)
Select (seq.nextval),p_name,source
FROM Data_Excel
WHERE P_Name NOT IN
(SELECT name FROM Person)
GROUP BY P_Name,P_Address,P_city,Source
HAVING count(*) < 2;
but I get the following error.
I am using seq because ID is the primary key in persons but its not auto incrementing. I also tried that but there was an error :
02287. 00000 - "sequence number not allowed here"
*Cause: The specified sequence umber (CURRVAL or NEXTVAL) is inappropriate
here in the statement.
*Action: emove the sequence number.

Try moving the sequence out of the grouping query:
INSERT INTO Person (id,Name,source)
SELECT seq.nextval, p_name,source FROM (
Select p_name,source
FROM Data_Excel
WHERE P_Name NOT IN
(SELECT name FROM Person)
GROUP BY P_Name,P_Address,P_city,Source
HAVING count(*) < 2
);

Related

Own id for every unique name in the table?

Is it possible to make a table that has like auto-incrementing id's for every unique name that I make in the table?
For example:
ID NAME_ID NAME
----------------------
1 1 John
2 1 John
3 1 John
4 2 Mary
5 2 Mary
6 3 Sarah
7 4 Lucas
and so on.
Use the window function rank() to get a unique id per name. Or dense_rank() to get the same without gaps:
SELECT id, dense_rank() OVER (ORDER BY name) AS name_id, name
FROM tbl;
I would advise not to write that redundant information to your table. You can generate that number on the fly. Or you shouldn't store name redundantly in that table, name would typically live in another table, with name_id as PRIMARY KEY.
Then you have a "names" table and run "SELECT or INSERT" there to get a unique name_id for every new entry in the main table. See:
Is SELECT or INSERT in a function prone to race conditions?
First add the column to the table.
ALTER TABLE yourtable
ADD [UID] INT NULL;
``
ALTER TABLE yourtable
ADD constraint fk_yourtable_uid_id foreign key ([UID]) references yourtable([Serial]);
Then you can update the UID with the minimum Serial ID per Name.
UPDATE t
SET [UID] = q.[UID]
FROM yourtable t
JOIN
(
SELECT Name, MIN([Serial]) AS [UID]
FROM yourtable
GROUP BY Name
) q ON q.Name = t.Name
WHERE (t.[UID] IS NULL OR t.[UID] != q.[UID]) -- Repeatability

OPENQUERY DELETE WHERE IN

Need to delete records from local person table where employee status in remote employee table is terminated. Trying something like the following but cannot get the open query syntax correct:
DELETE FROM PERSON WHERE ID IN
OPENQUERY(LSVR1,'SELECT DISTINCT ID FROM EMPLOYEE WHERE EMPLOYEE_STATUS=''T'' AND TERMINATION_DATE<SYSDATE-365')
I get
"Incorrect syntax near the keyword 'openquery'."
You could use IN (SELECT ... FROM OPENQUERY() alias):
DELETE FROM PERSON WHERE ID IN (
SELECT ID
FROM OPENQUERY(LSVR1,
'SELECT DISTINCT ID FROM EMPLOYEE WHERE EMPLOYEE_STATUS=''T'' AND TERMINATION_DATE<SYSDATE-365'
) sub);

How to manipulate VARRAYS in sql (oracle)?

Supposing i am using a table person, and persons might have multiple last names, so that attribute should be a varray of 3 elements for example (it's not about where to store last names), here is a simple sql for creating the type last name, the table person and adding an example row in oracle's sql developper (11G XE):
create type lastn as varray(3) of varchar2(10);
CREATE TABLE person
(
ID NUMBER NOT NULL
, last_name lastn
, CONSTRAINT EXEMPLE_PK PRIMARY KEY
(
ID
)
ENABLE
);
insert into person values(1,lastn('dani','bilel'));
I know how to update all last names at once, but i need to preserve existing last names and add other last names, or remove a single last name without affecting the others. In a nutshell, i want my code to be like (i am not familiar with PL/SQL):
insert into table
(select last_name from example where id=1)
values lastn('new');
This is the case where i want to get persons that have a first last name of 'bilel' and second last_name as 'dani'
select * from person where id in (select id from pernom p,table(p.last_name)
where column_value(1)='bilel' and column_value(2)='dani');
I know that it doesn't work like that, but i want to know CRUD(create update delete) statements in that case. and select statement with varray in where statement.
Thanks for your response.
From the docs:
Oracle does not support piecewise updates on VARRAY columns. However, VARRAY columns can be inserted into or updated as an atomic unit.
As shown in the examples there, you can manipulate the collection through PL/SQL instead; incuding adding an element to the array:
declare
l_last_name lastn;
begin
select last_name into l_last_name
from person where id = 1;
l_last_name.extend();
l_last_name(l_last_name.count) := 'third';
update person
set last_name = l_last_name
where id = 1;
end;
/
PL/SQL procedure successfully completed.
select last_name from person where id = 1;
LAST_NAME
--------------------------------------------------
LASTN('dani', 'bilel', 'third')
You can also do this via cast(multiset(...) as ...):
-- rollback; to reverse PL/SQL block actions above
update person p
set last_name = cast(multiset(
select column_value
from table (last_name)
union all
select 'third' from dual
) as lastn)
where id = 1;
1 row updated.
select last_name from person where id = 1;
LAST_NAME
--------------------------------------------------
LASTN('dani', 'bilel', 'third')
That explodes the existing last_name value into multiple rows, union's in a new value, and then converts the combined result back into your varray type.
And you can delete or update elements in a similar way:
update person p
set last_name = cast(multiset(
select column_value
from table (last_name)
where column_value != 'bilel'
) as lastn)
where id = 1;
1 row updated.
select last_name from person where id = 1;
LAST_NAME
--------------------------------------------------
LASTN('dani', 'third')
update person p
set last_name = cast(multiset(
select case column_value when 'third' then 'second' else column_value end
from table (last_name)
) as lastn)
where id = 1;
1 row updated.
select last_name from person where id = 1;
LAST_NAME
--------------------------------------------------
LASTN('dani', 'second')
For the select statement, i've figured out the solution, which goes like this :
select * from person p where id in (select id from table(p.last_name) where
column_value='bilel' intersect select id from table(p.last_name) where
column_value='dani');
or
select * from agent ag where id in (select id from table(ag.prenom)
t1,table(ag.prenom) t2,table(ag.prenom) t3 where t1.column_value='bilel' and
t2.column_value='dani' and t3.column_value='third');

Queries return results that don't add up

sqlite> select count(*) from authors;
1274360
sqlite> select count(*) from authors where length(Name)<1;
0
sqlite> select count(*) from authors where length(Name)>=1;
516738
The above doesn't make sense. Can anyone explain why the second and third query don't give me all the rows in the table?
I know that none of the names have NULL in them, but just to make sure I queried it and it also returned 0
sqlite> select count(*) from authors where Name==NULL;
0
Better check for NULLs with:
select count(*) from authors where Name is NULL;
And read about three valued logic. You can not check with operator == , because NULL <> NULL.
Following Query gives you Total Count of Authors
Which is 1274360 Authors in your table
sqlite> select count(*) from authors;
1274360
Following Query gives you Total Count of those authors whose name's length is less than 1 and your query gives 0 count because in your authors table you don't have such authors whose name length is less than 1
sqlite> select count(*) from authors where length(Name)<1;
0
Following Query gives you Total Count of those authors whose name's length is greater than equal to 1 and your query gives 516738 count because in your authors table you have such authors whose name length is greater than and equal to 1
sqlite> select count(*) from authors where length(Name)>=1;
516738
Following Query gives you Total Count of those authors whose name is null
and you don have any authors that is why you get 0
sqlite> select count(*) from authors where Name =NULL;
0
Note: for Null checking you should do something like this
sqlite> SELECT COUNT(*) FROM authors WHERE Name IS NULL;
/* to get count of all not null name use IS NOT NULL */
sqlite> SELECT COUNT(*) FROM authors WHERE Name IS NOT NULL;

What is wrong with my select statement?

Here is the question, keep in mind I'm using SQL developer 3....
The Student Services department wants to know how involved each faculty member is when it comes to supplying advice to students outside of class. Supply a list of faculty IDs and the number of students that faculty member is advising. Title the output column for faculty IDs “Faculty ID”, and the output column for the student count as “NumStuds”. Produce output only if the faculty id is less than 100 and the student has a value entered in either the last name or first name field. Present the output in increasing order by faculty ID
This is what I get...
SELECT F_ID AS "Falculty ID" , COUNT S_ID AS "NumStud" FROM student
WHERE ( s_first, s_last, f_id ) IS NOT NULL
AND IS <= 100
ORDER BY F_ID ACD
Then I get error Error starting at line 329 in command:
SELECT F_ID AS "Falculty ID" , COUNT S_ID AS "NumStud" FROM student
WHERE ( s_first, s_last, f_id ) IS NOT NULL
AND IS <= 100
ORDER BY F_ID ACD
Error at Command Line:329 Column:42 Error report: SQL Error:
ORA-00923: FROM keyword not found where expected
00923. 00000 - "FROM keyword not found where expected"
PLEASE HELP!
You cannot do that since you are testing for null value. It should manually be tested.
SELECT F_ID AS "Falculty ID" , COUNT(S_ID) AS "NumStud"
FROM student
WHERE (
s_first IS NOT NULL OR
s_last IS NOT NULL OR
f_id IS NOT NULL
) AND IS <= 100
ORDER BY F_ID ASC
Second, it should ASC for Ascending not ACD
Try:
SELECT F_ID AS "Faculty ID" , COUNT(S_ID) AS "NumStud"
FROM student
WHERE COALESCE( s_first, s_last ) IS NOT NULL AND F_ID < 100
GROUP BY F_ID
ORDER BY F_ID ASC