I am using a select withing an insert to add a previous record value. This requires me to do the following code:
insert into My_table
values ('a', select value_with_sp_char from table where criterion_to_guarantee_single_row=true), 'b','c')
Now whenever the value_with_sp_char has a character like _,&,%,.,comma,- the query fails.
Any ideas on how I can get that value inserted correctly?
Yes, you are right, I solved this.
I was not entirely truthful in the way I have represented this question.
I was trying to add the value to a variable like so
Declare
lv_txt_var varchar2(255) := '';
Begin
select value_with_sp_char into lv_txt_var from table where criterion_to_guarantee_single_row=true;
if (input_param = null)
insert into table values ('a', lv_txt_var, 'b', 'c');
end if;
when I used the above query, that failed because of the special char. However, when I modified this to use the select query, it worked.
You really don't need PL/SQL for this insert. It's better to write it this way:
INSERT INTO table_a
SELECT 'a', value_with_sp_char, 'b', 'c'
FROM table_b
WHERE criterion_to_guarantee_single_row = true;
Related
I need to delete data from many tables based on one parameter
The problem is that two tables are related to each other so in order to delete data properly i need to store id's somewhere.
-- i would like to store temp data
-- this one is only for convienience to avoid repeating same select many times
create table ztTaryfa as select zt_taryfa from tw_zbiory_taryfy
where 1=2;
-- this one is mandatory but I dont know how to make it work
Create table wnioskiId as select poli_wnio_id_wniosku from polisy
where 1=2;
Begin
-- fill temp tables
insert into ztTaryfa (
select zt_taryfa from tw_zbiory_taryfy
where zt_zbior = :zbiorId);
insert into wnioskiId (
select poli_wnio_id_wniosku from polisy
where poli_taryfa_id in ztTaryfa);
- regular deletion
delete from POLISY_OT where ot_poli_id in (
select poli_id from polisy
where poli_taryfa_id in ztTaryfa);
commit;
delete from DANE_RAPORTOWE where DR_RPU_ID in (
select RPU_ID from ROZLICZ_PLIK_UBEZP where RPU_ROZLICZ_PLIK_ID in (
select RP_ID from ROZLICZ_PLIK
where RP_ZBIOR_ID = :zbiorId ));
commit;
-- and here we go I need to delete data from POLISY first
delete from POLISY where poli_taryfa_id in ztTaryfa;
commit;
-- but by doing it I lose ids which i need here,
-- so I have to store them somehow and use them here.
delete from WNIOSKI where wnio_id in wnioskiId;
commit;
End;
-- and now lets get rid off temp tables
drop table ztTaryfa;
commit;
drop table wnioskiId;
commit;
To sum up i just need to know how to store somewhere between Begin and End a result of a select query which I can later use in delete statement.
Sounds but I tried so many different methods and all seems to not work.
What u see above is just a 1/3 of the script so I rly would like to make it all simple to use with one parameter.
Thanks you in advance.
You can use global types as simple as this:
create or replace type myrec is object (myid number);
create or replace type mytemp_collection is table of myrec;
declare
v_temp_collection mytemp_collection;
begin
v_temp_collection := mytemp_collection();
select myrec (t.field_type_id ) bulk collect into v_temp_collection from fs_field_types t
where mod(t.field_type_id+1,3)=0; -- for example
FOR i IN 1 .. v_temp_collection.count LOOP
DBMS_OUTPUT.put_line(v_temp_collection(i).myid);
End loop;
delete fs_field_types_back t where t.field_type_id in (select myid from table(v_temp_collection));
end;
Change select and where clause according to your business.
I'm writing a PL/SQL procedure, and I need to insert into a Table, based on an equality of two columns from two differents tables.
Here is my code:
create or replace PROCEDURE insertSomething
IS
BEGIN
INSERT INTO MYDBP ( ZIP )
SELECT POSTCODE
FROM ZIPDBP
WHERE ZIPDBP.ZIP = OTHERDBP.ZIP;
COMMIT;
END;
I'm getting an error saying OTHERDBP.ZIP is an invalid identifier. What is the issue?
EDIT:
To get the output I expected I need another equality statement between two of the tables ID, but again I'm getting invalid identifier again, this time for DBP_CLIENTS.ID. Here is the code
INSERT INTO DBP_CLIENTS ( POSTCODE )
SELECT POSTCODE
FROM DBP_POSTCODE, HELENS_DATA
WHERE DBP_POSTCODE.LOCALITY = HELENS_DATA.SUBURB
AND DBP_POSTCODE.STATE = 'NSW'
AND DBP_CLIENTS.ID = HELENS_DATA.ID;
COMMIT;
Try this:
create or replace PROCEDURE insertSomething
IS
BEGIN
INSERT INTO MYDBP ( ZIP )
SELECT POSTCODE
FROM ZIPDBP, OTHERDBP
WHERE ZIPDBP.ZIP = OTHERDBP.ZIP;
COMMIT;
END;
You have to add otherdbp to from section. And you don't need to use () in procedure declaration.
Moreover, insert is reserverd word in pl/sql, so procedure must have different name
You have to add DBP_CLIENTS in the FROM clause:
INSERT INTO DBP_CLIENTS ( POSTCODE )
SELECT POSTCODE
FROM DBP_POSTCODE, HELENS_DATA, DBP_CLIENTS
WHERE DBP_POSTCODE.LOCALITY = HELENS_DATA.SUBURB
AND DBP_CLIENTS.ID = HELENS_DATA.ID
AND DBP_POSTCODE.STATE = 'NSW';
COMMIT;
I have one table named Test with columns named ID,Name,UserValue,AverageValue
ID,Name,UserValue,AverageValue (As Appears on Table)
1,a,10,NULL
2,a,20,NULL
3,b,5,NULL
4,b,10,NULL
5,c,25,NULL
I know how to average the numbers via (SELECT Name, AVG(UserValue) FROM Test GROUP BY Name)
Giving me:
Name,Column1(AVG(Query)) (As Appears on GridView1 via databind when I run the website)
a,15
b,7.5
c,25
What I need to do is make the table appear as such by inserting the calculated AVG() into the AverageValue column server side:
ID,Name,UserValue,AverageValue (As Appears on Table)
1,a,10,15
2,a,20,15
3,b,5,7.5
4,b,10,7.5
5,c,25,25
Conditions:
The AVG(UserValue) must be inserted into Test table AverageValue.
If new entries are made the AverageValue would be updated to match AVG(UserValue).
So what I am looking for is a SQL command that is something like this:
INSERT INTO Test (AverageValue) VALUES (SELECT Name, AVG(UserValue) FROM Test GROUP BY Name)
I have spent considerable amount of time searching on google to find an example but have had no such luck. Any examples would be greatly appreciated. Many thanks in advance.
Try this:
with toupdate as (
select t.*, avg(uservalue) over (partition by name) as newavg
from test t
)
update toupdate
set AverageValue = newavg;
The CTE toupdate is an updatable CTE, so you can just use it in an update statement as if it were a table.
I believe this will do the trick for you. I use the merge statement a lot! It's perfect for doing things like this.
Peace,
Katherine
use [test_01];
go
if object_id (N'tempdb..##test', N'U') is not null
drop table ##test;
go
create table ##test (
[id] [int] identity(1, 1) not null,
[name] [nvarchar](max) not null,
[user_value] [int] not null,
[average_value] [decimal](5, 2),
constraint [pk_test_id] primary key([id])
);
go
insert into ##test
([name], [user_value])
values (N'a',10),
(N'a',20),
(N'b',5),
(N'b',10),
(N'c',25);
go
with [average_builder] as (select [name],
avg(cast([user_value] as [decimal](5, 2))) as [average_value]
from ##test
group by [name])
merge into ##test as target
using [average_builder] as source
on target.[name] = source.[name]
when matched then
update set target.[average_value] = source.[average_value];
go
select [id], [name], [user_value], [average_value] from ##test;
go
I have a table named CUSTOMER, with few columns. One of them is Customer_ID.
Initially Customer_ID column WILL NOT accept NULL values.
I've made some changes from code level, so that Customer_ID column will accept NULL values by default.
Now my requirement is that, I need to again make this column to accept NULL values.
For this I've added executing the below query:
ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL
I'm getting the following error:
ORA-01451 error, the column already allows null entries so
therefore cannot be modified
This is because already I've made the Customer_ID column to accept NULL values.
Is there a way to check if the column will accept NULL values before executing the above query...??
You can use the column NULLABLE in USER_TAB_COLUMNS. This tells you whether the column allows nulls using a binary Y/N flag.
If you wanted to put this in a script you could do something like:
declare
l_null user_tab_columns.nullable%type;
begin
select nullable into l_null
from user_tab_columns
where table_name = 'CUSTOMER'
and column_name = 'CUSTOMER_ID';
if l_null = 'N' then
execute immediate 'ALTER TABLE Customer
MODIFY (Customer_ID nvarchar2(20) NULL)';
end if;
end;
It's best not to use dynamic SQL in order to alter tables. Do it manually and be sure to double check everything first.
Or you can just ignore the error:
declare
already_null exception;
pragma exception_init (already_null , -01451);
begin
execute immediate 'alter table <TABLE> modify(<COLUMN> null)';
exception when already_null then null;
end;
/
You might encounter this error when you have previously provided a DEFAULT ON NULL value for the NOT NULL column.
If this is the case, to make the column nullable, you must also reset its default value to NULL when you modify its nullability constraint.
eg:
DEFINE table_name = your_table_name_here
DEFINE column_name = your_column_name_here;
ALTER TABLE &table_name
MODIFY (
&column_name
DEFAULT NULL
NULL
);
I did something like this, it worked fine.
Try to execute query, if any error occurs, catch SQLException.
try {
stmt.execute("ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL");
} catch (SQLException sqe) {
Logger("Column to be modified to NULL is already NULL : " + sqe);
}
Is this correct way of doing?
To modify the constraints of an existing table
for example... add not null constraint to a column.
Then follow the given steps:
1) Select the table in which you want to modify changes.
2) Click on Actions.. ---> select column ----> add.
3) Now give the column name, datatype, size, etc. and click ok.
4) You will see that the column is added to the table.
5) Now click on Edit button lying on the left side of Actions button.
6) Then you will get various table modifying options.
7) Select the column from the list.
8) Select the particular column in which you want to give not null.
9) Select Cannot be null from column properties.
10) That's it.
I have an SQL query similar to the following:
create procedure test
(
#param1 nvarchar(max)
)
as
begin
select * from table where column1 in (#param1)
end
Now I need to pass the value of #param1 from my .net application in such a way that the above query works.
Can some one please advise me on how to pass from my VB.NET code a value which is similiar to below:
'1','2','3'
My main question is how do I structure value of parameter like above example from my .NET application?
quickly like that, I would create a table valued function that would parse it so you can do
select *
from table
where field in (select field from dbo.myfunction(#param1))
For this type of thing, I use this function and use it as follows:
select Column1, column2 from my table where ID in (select item from fnSplit('1,2,3,4,5,6',','))
create FUNCTION [dbo].[fnSplit](
#sInputList VARCHAR(8000) -- List of delimited items
, #sDelimiter VARCHAR(8000) = ',' -- delimiter that separates items
)
RETURNS #List TABLE (item VARCHAR(8000))
BEGIN
DECLARE #sItem VARCHAR(8000)
WHILE CHARINDEX(#sDelimiter,#sInputList,0) <> 0
BEGIN
SELECT
#sItem=RTRIM(LTRIM(SUBSTRING(#sInputList,1,CHARINDEX(#sDelimiter,#sInputList,0)-1))),
#sInputList=RTRIM(LTRIM(SUBSTRING(#sInputList,CHARINDEX(#sDelimiter,#sInputList,0)+LEN(#sDelimiter),LEN(#sInputList))))
IF LEN(#sItem) > 0
INSERT INTO #List SELECT #sItem
END
IF LEN(#sInputList) > 0
INSERT INTO #List SELECT #sInputList -- Put the last item in
RETURN
END
I don't think the problem is in the values you are passing. #param1 is just a string.
You need to address this in your procedure. Your select statement will not be able to recognize the values in you IN clause. One solution is to take the comma-separated string and insert each record into a table variable Explained Here
If your table variable is table #param_list, you procedure test looks like:
create procedure test ( #param1 nvarchar(max) )
as begin
select * from table where column1 in (Select thefield from #param_list);
end